(function(){
/*
 * jQuery 1.2.6 - New Wave Javascript
 *
 * Copyright (c) 2008 John Resig (jquery.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * $Date: 2008-05-24 14:22:17 -0400 (Sat, 24 May 2008) $
 * $Rev: 5685 $
 */
var _jQuery = window.jQuery,
	_$ = window.$;
var jQuery = window.jQuery = window.$ = function( selector, context ) {
	return new jQuery.fn.init( selector, context );
};
var quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#(\w+)$/,
	isSimple = /^.[^:#\[\.]*$/,
	undefined;
jQuery.fn = jQuery.prototype = {
	init: function( selector, context ) {
		selector = selector || document;
		if ( selector.nodeType ) {
			this[0] = selector;
			this.length = 1;
			return this;
		}
		if ( typeof selector == "string" ) {
			var match = quickExpr.exec( selector );

			// Verify a match, and that no context was specified for #id
			if ( match && (match[1] || !context) ) {
				// HANDLE: $(html) -> $(array)
				if ( match[1] )
					selector = jQuery.clean( [ match[1] ], context );
				// HANDLE: $("#id")
				else {
					var elem = document.getElementById( match[3] );
					// Make sure an element was located
					if ( elem ){
						// Handle the case where IE and Opera return items
						// by name instead of ID
						if ( elem.id != match[3] )
							return jQuery().find( selector );
						// Otherwise, we inject the element directly into the jQuery object
						return jQuery( elem );
					}
					selector = [];
				}

			// HANDLE: $(expr, [context])
			// (which is just equivalent to: $(content).find(expr)
			} else
				return jQuery( context ).find( selector );

		// HANDLE: $(function)
		// Shortcut for document ready
		} else if ( jQuery.isFunction( selector ) )
			return jQuery( document )[ jQuery.fn.ready ? "ready" : "load" ]( selector );

		return this.setArray(jQuery.makeArray(selector));
	},
	// The current version of jQuery being used
	jquery: "1.2.6",

	// The number of elements contained in the matched element set
	size: function() {
		return this.length;
	},
	// The number of elements contained in the matched element set
	length: 0,

	// Get the Nth element in the matched element set OR
	// Get the whole matched element set as a clean array
	get: function( num ) {
		return num == undefined ?

			// Return a 'clean' array
			jQuery.makeArray( this ) :

			// Return just the object
			this[ num ];
	},
	// Take an array of elements and push it onto the stack
	// (returning the new matched element set)
	pushStack: function( elems ) {
		// Build a new jQuery matched element set
		var ret = jQuery( elems );

		// Add the old object onto the stack (as a reference)
		ret.prevObject = this;

		// Return the newly-formed element set
		return ret;
	},
	// Force the current matched set of elements to become
	// the specified array of elements (destroying the stack in the process)
	// You should use pushStack() in order to do this, but maintain the stack
	setArray: function( elems ) {
		// Resetting the length to 0, then using the native Array push
		// is a super-fast way to populate an object with array-like properties
		this.length = 0;
		Array.prototype.push.apply( this, elems );
		return this;
	},

	// Execute a callback for every element in the matched set.
	// (You can seed the arguments with an array of args, but this is
	// only used internally.)
	each: function( callback, args ) {
		return jQuery.each( this, callback, args );
	},

	// Determine the position of an element within
	// the matched set of elements
	index: function( elem ) {
		var ret = -1;

		// Locate the position of the desired element
		return jQuery.inArray(
			// If it receives a jQuery object, the first element is used
			elem && elem.jquery ? elem[0] : elem
		, this );
	},

	attr: function( name, value, type ) {
		var options = name;
		// Look for the case where we're accessing a style value
		if ( name.constructor == String )
			if ( value === undefined )
				return this[0] && jQuery[ type || "attr" ]( this[0], name );

			else {
				options = {};
				options[ name ] = value;
			}
		// Check to see if we're setting style values
		return this.each(function(i){
			// Set all the styles
			for ( name in options )
				if(typeof options[name] != 'function')
					jQuery.attr(
						type ?
							this.style :
							this,
						name, jQuery.prop( this, options[ name ], type, i, name )
					);
		});
	},

	css: function( key, value ) {
		// ignore negative width and height values
		if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 )
			value = undefined;
		return this.attr( key, value, "curCSS" );
	},

	text: function( text ) {
		if ( typeof text != "object" && text != null )
			return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) );

		var ret = "";

		jQuery.each( text || this, function(){
			jQuery.each( this.childNodes, function(){
				if ( this.nodeType != 8 )
					ret += this.nodeType != 1 ?
						this.nodeValue :
						jQuery.fn.text( [ this ] );
			});
		});

		return ret;
	},

	wrapAll: function( html ) {
		if ( this[0] )
			// The elements to wrap the target around
			jQuery( html, this[0].ownerDocument )
				.clone()
				.insertBefore( this[0] )
				.map(function(){
					var elem = this;

					while ( elem.firstChild )
						elem = elem.firstChild;

					return elem;
				})
				.append(this);

		return this;
	},

	wrapInner: function( html ) {
		return this.each(function(){
			jQuery( this ).contents().wrapAll( html );
		});
	},

	wrap: function( html ) {
		return this.each(function(){
			jQuery( this ).wrapAll( html );
		});
	},

	append: function() {
		return this.domManip(arguments, true, false, function(elem){
			if (this.nodeType == 1)
				this.appendChild( elem );
		});
	},

	prepend: function() {
		return this.domManip(arguments, true, true, function(elem){
			if (this.nodeType == 1)
				this.insertBefore( elem, this.firstChild );
		});
	},
	before: function() {
		return this.domManip(arguments, false, false, function(elem){
			this.parentNode.insertBefore( elem, this );
		});
	},

	after: function() {
		return this.domManip(arguments, false, true, function(elem){
			this.parentNode.insertBefore( elem, this.nextSibling );
		});
	},

	end: function() {
		return this.prevObject || jQuery( [] );
	},

	find: function( selector ) {
		var elems = jQuery.map(this, function(elem){
			return jQuery.find( selector, elem );
		});

		return this.pushStack( /[^+>] [^+>]/.test( selector ) || (selector && selector.indexOf && selector.indexOf("..") > -1) ?
			jQuery.unique( elems ) :
			elems );
	},

	clone: function( events ) {
		// Do the clone
		var ret = this.map(function(){
			if ( jQuery.browser.msie && !jQuery.isXMLDoc(this) ) {
				// IE copies events bound via attachEvent when
				// using cloneNode. Calling detachEvent on the
				// clone will also remove the events from the orignal
				// In order to get around this, we use innerHTML.
				// Unfortunately, this means some modifications to
				// attributes in IE that are actually only stored
				// as properties will not be copied (such as the
				// the name attribute on an input).
				var clone = this.cloneNode(true),
					container = document.createElement("div");
				container.appendChild(clone);
				return jQuery.clean([container.innerHTML])[0];
			} else
				return this.cloneNode(true);
		});

		// Need to set the expando to null on the cloned set if it exists
		// removeData doesn't work here, IE removes it from the original as well
		// this is primarily for IE but the data expando shouldn't be copied over in any browser
		var clone = ret.find("*").andSelf().each(function(){
			if ( this[ expando ] != undefined )
				this[ expando ] = null;
		});
		// Copy the events from the original to the clone
		if ( events === true )
			this.find("*").andSelf().each(function(i){
				if (this.nodeType == 3)
					return;
				var events = jQuery.data( this, "events" );

				for ( var type in events )
					for ( var handler in events[ type ] )
						jQuery.event.add( clone[ i ], type, events[ type ][ handler ], events[ type ][ handler ].data );
			});

		// Return the cloned set
		return ret;
	},

	filter: function( selector ) {
		return this.pushStack(
			jQuery.isFunction( selector ) &&
			jQuery.grep(this, function(elem, i){
				return selector.call( elem, i );
			}) ||

			jQuery.multiFilter( selector, this ) );
	},

	not: function( selector ) {
		if ( selector.constructor == String )
			// test special case where just one selector is passed in
			if ( isSimple.test( selector ) )
				return this.pushStack( jQuery.multiFilter( selector, this, true ) );
			else
				selector = jQuery.multiFilter( selector, this );

		var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType;
		return this.filter(function() {
			return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector;
		});
	},

	add: function( selector ) {
		return this.pushStack( jQuery.unique( jQuery.merge(
			this.get(),
			typeof selector == 'string' ?
				jQuery( selector ) :
				jQuery.makeArray( selector )
		)));
	},

	is: function( selector ) {
		return !!selector && jQuery.multiFilter( selector, this ).length > 0;
	},

	hasClass: function( selector ) {
		return this.is( "." + selector );
	},
	val: function( value ) {
		if ( value == undefined ) {

			if ( this.length ) {
				var elem = this[0];

				// We need to handle select boxes special
				if ( jQuery.nodeName( elem, "select" ) ) {
					var index = elem.selectedIndex,
						values = [],
						options = elem.options,
						one = elem.type == "select-one";
					// Nothing was selected
					if ( index < 0 )
						return null;

					// Loop through all the selected options
					for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
						var option = options[ i ];

						if ( option.selected ) {
							// Get the specifc value for the option
							value = jQuery.browser.msie && !option.attributes.value.specified ? option.text : option.value;
							// We don't need an array for one selects
							if ( one )
								return value;
							// Multi-Selects return an array
							values.push( value );
						}
					}
					return values;
				// Everything else, we just grab the value
				} else
					return (this[0].value || "").replace(/\r/g, "");

			}

			return undefined;
		}
		if( value.constructor == Number )
			value += '';

		return this.each(function(){
			if ( this.nodeType != 1 )
				return;

			if ( value.constructor == Array && /radio|checkbox/.test( this.type ) )
				this.checked = (jQuery.inArray(this.value, value) >= 0 ||
					jQuery.inArray(this.name, value) >= 0);

			else if ( jQuery.nodeName( this, "select" ) ) {
				var values = jQuery.makeArray(value);

				jQuery( "option", this ).each(function(){
					this.selected = (jQuery.inArray( this.value, values ) >= 0 ||
						jQuery.inArray( this.text, values ) >= 0);
				});

				if ( !values.length )
					this.selectedIndex = -1;

			} else
				this.value = value;
		});
	},
	html: function( value ) {
		return value == undefined ?
			(this[0] ?
				this[0].innerHTML :
				null) :
			this.empty().append( value );
	},

	replaceWith: function( value ) {
		return this.after( value ).remove();
	},

	eq: function( i ) {
		return this.slice( i, i + 1 );
	},

	slice: function() {
		return this.pushStack( Array.prototype.slice.apply( this, arguments ) );
	},

	map: function( callback ) {
		return this.pushStack( jQuery.map(this, function(elem, i){
			return callback.call( elem, i, elem );
		}));
	},

	andSelf: function() {
		return this.add( this.prevObject );
	},

	data: function( key, value ){
		var parts = key.split(".");
		parts[1] = parts[1] ? "." + parts[1] : "";

		if ( value === undefined ) {
			var data = this.triggerHandler("getData" + parts[1] + "!", [parts[0]]);
			if ( data === undefined && this.length )
				data = jQuery.data( this[0], key );

			return data === undefined && parts[1] ?
				this.data( parts[0] ) :
				data;
		} else
			return this.trigger("setData" + parts[1] + "!", [parts[0], value]).each(function(){
				jQuery.data( this, key, value );
			});
	},

	removeData: function( key ){
		return this.each(function(){
			jQuery.removeData( this, key );
		});
	},
	domManip: function( args, table, reverse, callback ) {
		var clone = this.length > 1, elems;

		return this.each(function(){
			if ( !elems ) {
				elems = jQuery.clean( args, this.ownerDocument );

				if ( reverse )
					elems.reverse();
			}

			var obj = this;

			if ( table && jQuery.nodeName( this, "table" ) && jQuery.nodeName( elems[0], "tr" ) )
				obj = this.getElementsByTagName("tbody")[0] || this.appendChild( this.ownerDocument.createElement("tbody") );

			var scripts = jQuery( [] );

			jQuery.each(elems, function(){
				var elem = clone ?
					jQuery( this ).clone( true )[0] :
					this;

				// execute all scripts after the elements have been injected
				if ( jQuery.nodeName( elem, "script" ) )
					scripts = scripts.add( elem );
				else {
					// Remove any inner scripts for later evaluation
					if ( elem.nodeType == 1 )
						scripts = scripts.add( jQuery( "script", elem ).remove() );

					// Inject the elements into the document
					callback.call( obj, elem );
				}
			});

			scripts.each( evalScript );
		});
	}
};

// Give the init function the jQuery prototype for later instantiation
jQuery.fn.init.prototype = jQuery.fn;

function evalScript( i, elem ) {
	if ( elem.src )
		jQuery.ajax({
			url: elem.src,
			async: false,
			dataType: "script"
		});

	else
		jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" );

	if ( elem.parentNode )
		elem.parentNode.removeChild( elem );
}
function now(){
	return +new Date;
}

jQuery.extend = jQuery.fn.extend = function() {
	// copy reference to target object
	var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;

	// Handle a deep copy situation
	if ( target.constructor == Boolean ) {
		deep = target;
		target = arguments[1] || {};
		// skip the boolean and the target
		i = 2;
	}

	// Handle case when target is a string or something (possible in deep copy)
	if ( typeof target != "object" && typeof target != "function" )
		target = {};

	// extend jQuery itself if only one argument is passed
	if ( length == i ) {
		target = this;
		--i;
	}

	for ( ; i < length; i++ )
		// Only deal with non-null/undefined values
		if ( (options = arguments[ i ]) != null )
			// Extend the base object
			/* for ( var name in options ) {
				var src = target[ name ], copy = options[ name ];
				// Prevent never-ending loop
				if ( target === copy )
					continue;

				// Recurse if we're merging object values
				if ( deep && copy && typeof copy == "object" && !copy.nodeType )
					target[ name ] = jQuery.extend( deep, 
						// Never move original objects, clone them
						src || ( copy.length != null ? [ ] : { } )
					, copy );

				// Don't bring in undefined values
				else if ( copy !== undefined )
					target[ name ] = copy;

			} */
			for ( var name in options ) {
				// Prevent never-ending loop
				if ( target === options[ name ] )
					continue;

				// Recurse if we're merging object values
				if ( deep && options[ name ] && typeof options[ name ] == "object" && target[ name ] && !options[ name ].nodeType )
					target[ name ] = jQuery.extend( target[ name ], options[ name ] );

				// Don't bring in undefined values
				else if ( options[ name ] != undefined )
					target[ name ] = options[ name ];

			}
	// Return the modified object
	return target;
};

var expando = "jQuery" + now(), uuid = 0, windowData = {},
	// exclude the following css properties to add px
	exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i,
	// cache defaultView
	defaultView = document.defaultView || {};

jQuery.extend({
	noConflict: function( deep ) {
		window.$ = _$;

		if ( deep )
			window.jQuery = _jQuery;

		return jQuery;
	},

	// See test/unit/core.js for details concerning this function.
	isFunction: function( fn ) {
		return !!fn && typeof fn != "string" && !fn.nodeName &&
			fn.constructor != Array && /^[\s[]?function/.test( fn + "" );
	},
	// check if an element is in a (or is an) XML document
	isXMLDoc: function( elem ) {
		return elem.documentElement && !elem.body ||
			elem.tagName && elem.ownerDocument && !elem.ownerDocument.body;
	},

	// Evalulates a script in a global context
	globalEval: function( data ) {
		data = jQuery.trim( data );
		if ( data ) {
			// Inspired by code by Andrea Giammarchi
			// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
			var head = document.getElementsByTagName("head")[0] || document.documentElement,
				script = document.createElement("script");

			script.type = "text/javascript";
			if ( jQuery.browser.msie )
				script.text = data;
			else
				script.appendChild( document.createTextNode( data ) );

			// Use insertBefore instead of appendChild  to circumvent an IE6 bug.
			// This arises when a base node is used (#2709).
			head.insertBefore( script, head.firstChild );
			head.removeChild( script );
		}
	},

	nodeName: function( elem, name ) {
		return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase();
	},
	cache: {},
	data: function( elem, name, data ) {
		elem = elem == window ?
			windowData :
			elem;

		var id = elem[ expando ];

		// Compute a unique ID for the element
		if ( !id )
			id = elem[ expando ] = ++uuid;

		// Only generate the data cache if we're
		// trying to access or manipulate it
		if ( name && !jQuery.cache[ id ] )
			jQuery.cache[ id ] = {};
		// Prevent overriding the named cache with undefined values
		if ( data !== undefined )
			jQuery.cache[ id ][ name ] = data;
		// Return the named cache data, or the ID for the element
		return name ?
			jQuery.cache[ id ][ name ] :
			id;
	},
	removeData: function( elem, name ) {
		elem = elem == window ?
			windowData :
			elem;

		var id = elem[ expando ];

		// If we want to remove a specific section of the element's data
		if ( name ) {
			if ( jQuery.cache[ id ] ) {
				// Remove the section of cache data
				delete jQuery.cache[ id ][ name ];

				// If we've removed all the data, remove the element's cache
				name = "";

				for ( name in jQuery.cache[ id ] )
					break;

				if ( !name )
					jQuery.removeData( elem );
			}

		// Otherwise, we want to remove all of the element's data
		} else {
			// Clean up the element expando
			try {
				delete elem[ expando ];
			} catch(e){
				// IE has trouble directly removing the expando
				// but it's ok with using removeAttribute
				if ( elem.removeAttribute )
					elem.removeAttribute( expando );
			}

			// Completely remove the data cache
			delete jQuery.cache[ id ];
		}
	},

	// args is for internal usage only
	each: function( object, callback, args ) {
		var name, i = 0, length = object.length;
		if ( args ) {
			if ( length == undefined ) {
				for ( name in object )
					if ( callback.apply( object[ name ], args ) === false )
						break;
			} else
				for ( ; i < length; )
					if ( callback.apply( object[ i++ ], args ) === false )
						break;

		// A special, fast, case for the most common use of each
		} else {
			if ( length == undefined ) {
				for ( name in object )
					if ( callback.call( object[ name ], name, object[ name ] ) === false )
						break;
			} else
				for ( var value = object[0];
					i < length && callback.call( value, i, value ) !== false; value = object[++i] ){}
		}

		return object;
	},
	prop: function( elem, value, type, i, name ) {
		// Handle executable functions
		if ( jQuery.isFunction( value ) )
			value = value.call( elem, i );

		// Handle passing in a number to a CSS property
		return value && value.constructor == Number && type == "curCSS" && !exclude.test( name ) ?
			value + "px" :
			value;
	},

	className: {
		// internal only, use addClass("class")
		add: function( elem, classNames ) {
			jQuery.each((classNames || "").split(/\s+/), function(i, className){
				if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) )
					elem.className += (elem.className ? " " : "") + className;
			});
		},

		// internal only, use removeClass("class")
		remove: function( elem, classNames ) {
			if (elem.nodeType == 1)
				elem.className = classNames != undefined ?
					jQuery.grep(elem.className.split(/\s+/), function(className){
						return !jQuery.className.has( classNames, className );
					}).join(" ") :
					"";
		},

		// internal only, use hasClass("class")
		has: function( elem, className ) {
			return jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1;
		}
	},

	// A method for quickly swapping in/out CSS properties to get correct calculations
	swap: function( elem, options, callback ) {
		var old = {};
		// Remember the old values, and insert the new ones
		for ( var name in options ) {
			old[ name ] = elem.style[ name ];
			elem.style[ name ] = options[ name ];
		}

		callback.call( elem );

		// Revert the old values
		for ( var name in options )
			elem.style[ name ] = old[ name ];
	},

	css: function( elem, name, force ) {
		if ( name == "width" || name == "height" ) {
			var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ];
			function getWH() {
				val = name == "width" ? elem.offsetWidth : elem.offsetHeight;
				var padding = 0, border = 0;
				jQuery.each( which, function() {
					padding += parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0;
					border += parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0;
				});
				val -= Math.round(padding + border);
			}
			if ( jQuery(elem).is(":visible") )
				getWH();
			else
				jQuery.swap( elem, props, getWH );
			return Math.max(0, val);
		}
		return jQuery.curCSS( elem, name, force );
	},

	curCSS: function( elem, name, force ) {
		var ret, style = elem.style;

		// A helper method for determining if an element's values are broken
		function color( elem ) {
			if ( !jQuery.browser.safari )
				return false;

			// defaultView is cached
			var ret = defaultView.getComputedStyle( elem, null );
			return !ret || ret.getPropertyValue("color") == "";
		}

		// We need to handle opacity special in IE
		if ( name == "opacity" && jQuery.browser.msie ) {
			ret = jQuery.attr( style, "opacity" );

			return ret == "" ?
				"1" :
				ret;
		}
		// Opera sometimes will give the wrong display answer, this fixes it, see #2037
		if ( jQuery.browser.opera && name == "display" ) {
			var save = style.outline;
			style.outline = "0 solid black";
			style.outline = save;
		}
		// Make sure we're using the right name for getting the float value
		if ( name.match( /float/i ) )
			name = styleFloat;

		if ( !force && style && style[ name ] )
			ret = style[ name ];

		else if ( defaultView.getComputedStyle ) {

			// Only "float" is needed here
			if ( name.match( /float/i ) )
				name = "float";

			name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase();

			var computedStyle = defaultView.getComputedStyle( elem, null );

			if ( computedStyle && !color( elem ) )
				ret = computedStyle.getPropertyValue( name );

			// If the element isn't reporting its values properly in Safari
			// then some display: none elements are involved
			else {
				var swap = [], stack = [], a = elem, i = 0;

				// Locate all of the parent display: none elements
				for ( ; a && color(a); a = a.parentNode )
					stack.unshift(a);

				// Go through and make them visible, but in reverse
				// (It would be better if we knew the exact display type that they had)
				for ( ; i < stack.length; i++ )
					if ( color( stack[ i ] ) ) {
						swap[ i ] = stack[ i ].style.display;
						stack[ i ].style.display = "block";
					}

				// Since we flip the display style, we have to handle that
				// one special, otherwise get the value
				ret = name == "display" && swap[ stack.length - 1 ] != null ?
					"none" :
					( computedStyle && computedStyle.getPropertyValue( name ) ) || "";

				// Finally, revert the display styles back
				for ( i = 0; i < swap.length; i++ )
					if ( swap[ i ] != null )
						stack[ i ].style.display = swap[ i ];
			}

			// We should always get a number back from opacity
			if ( name == "opacity" && ret == "" )
				ret = "1";

		} else if ( elem.currentStyle ) {
			var camelCase = name.replace(/\-(\w)/g, function(all, letter){
				return letter.toUpperCase();
			});

			ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ];

			// From the awesome hack by Dean Edwards
			// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291

			// If we're not dealing with a regular pixel number
			// but a number that has a weird ending, we need to convert it to pixels
			if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) {
				// Remember the original values
				var left = style.left, rsLeft = elem.runtimeStyle.left;

				// Put in the new values to get a computed value out
				elem.runtimeStyle.left = elem.currentStyle.left;
				style.left = ret || 0;
				ret = style.pixelLeft + "px";

				// Revert the changed values
				style.left = left;
				elem.runtimeStyle.left = rsLeft;
			}
		}

		return ret;
	},
	clean: function( elems, context ) {
		var ret = [];
		context = context || document;
		// !context.createElement fails in IE with an error but returns typeof 'object'
		if (typeof context.createElement == 'undefined')
			context = context.ownerDocument || context[0] && context[0].ownerDocument || document;

		jQuery.each(elems, function(i, elem){
			if ( !elem )
				return;

			if ( elem.constructor == Number )
				elem += '';
			// Convert html string into DOM nodes
			if ( typeof elem == "string" ) {
				// Fix "XHTML"-style tags in all browsers
				elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){
					return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ?
						all :
						front + "></" + tag + ">";
				});

				// Trim whitespace, otherwise indexOf won't work as expected
				var tags = jQuery.trim( elem ).toLowerCase(), div = context.createElement("div");

				var wrap =
					// option or optgroup
					!tags.indexOf("<opt") &&
					[ 1, "<select multiple='multiple'>", "</select>" ] ||
					!tags.indexOf("<leg") &&
					[ 1, "<fieldset>", "</fieldset>" ] ||
					tags.match(/^<(thead|tbody|tfoot|colg|cap)/) &&
					[ 1, "<table>", "</table>" ] ||
					!tags.indexOf("<tr") &&
					[ 2, "<table><tbody>", "</tbody></table>" ] ||
				 	// <thead> matched above
					(!tags.indexOf("<td") || !tags.indexOf("<th")) &&
					[ 3, "<table><tbody><tr>", "</tr></tbody></table>" ] ||
					!tags.indexOf("<col") &&
					[ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ] ||

					// IE can't serialize <link> and <script> tags normally
					jQuery.browser.msie &&
					[ 1, "div<div>", "</div>" ] ||
					[ 0, "", "" ];

				// Go to html and back, then peel off extra wrappers
				div.innerHTML = wrap[1] + elem + wrap[2];
				// Move to the right depth
				while ( wrap[0]-- )
					div = div.lastChild;
				// Remove IE's autoinserted <tbody> from table fragments
				if ( jQuery.browser.msie ) {
					// String was a <table>, *may* have spurious <tbody>
					var tbody = !tags.indexOf("<table") && tags.indexOf("<tbody") < 0 ?
						div.firstChild && div.firstChild.childNodes :
						// String was a bare <thead> or <tfoot>
						wrap[1] == "<table>" && tags.indexOf("<tbody") < 0 ?
							div.childNodes :
							[];
					for ( var j = tbody.length - 1; j >= 0 ; --j )
						if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length )
							tbody[ j ].parentNode.removeChild( tbody[ j ] );
					// IE completely kills leading whitespace when innerHTML is used
					if ( /^\s/.test( elem ) )
						div.insertBefore( context.createTextNode( elem.match(/^\s*/)[0] ), div.firstChild );
				}
				elem = jQuery.makeArray( div.childNodes );
			}

			if ( elem.length === 0 && (!jQuery.nodeName( elem, "form" ) && !jQuery.nodeName( elem, "select" )) )
				return;

			if ( elem[0] == undefined || jQuery.nodeName( elem, "form" ) || elem.options )
				ret.push( elem );

			else
				ret = jQuery.merge( ret, elem );

		});

		return ret;
	},
	attr: function( elem, name, value ) {
		// don't set attributes on text and comment nodes
		if (!elem || elem.nodeType == 3 || elem.nodeType == 8 || name == 'toJSONString')
			return undefined;

		var notxml = !jQuery.isXMLDoc( elem ),
			// Whether we are setting (or getting)
			set = value !== undefined,
			msie = jQuery.browser.msie;
		// Try to normalize/fix the name
		name = notxml && jQuery.props[ name ] || name;
		
		// Only do all the following if this is a node (faster for style)
		// IE elem.getAttribute passes even for style
		if ( elem.tagName ) {

			// These attributes require special treatment
			var special = /href|src|style/.test( name );
			
			// Safari mis-reports the default selected property of a hidden option
			// Accessing the parent's selectedIndex property fixes it
			if ( name == "selected" && jQuery.browser.safari )
				elem.parentNode.selectedIndex;
			
			// If applicable, access the attribute via the DOM 0 way
			if ( name in elem && notxml && !special ) {
				if ( set ){
					// We can't allow the type property to be changed (since it causes problems in IE)
					if ( name == "type" && jQuery.nodeName( elem, "input" ) && elem.parentNode )
						throw "type property can't be changed";

					elem[ name ] = value;
				}

				// browsers index elements by id/name on forms, give priority to attributes.
				if( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) )
					return elem.getAttributeNode( name ).nodeValue;

				return elem[ name ];
			}

			if ( msie && notxml &&  name == "style" )
				return jQuery.attr( elem.style, "cssText", value );

			if ( set )
				// convert the value to a string (all browsers do this but IE) see #1070
				elem.setAttribute( name, "" + value );
			
			var attr = msie && notxml && special
					// Some attributes require a special call on IE
					? elem.getAttribute( name, 2 )
					: elem.getAttribute( name );

			// Non-existent attributes return null, we normalize to undefined
			return attr === null ? undefined : attr;
		}

		// elem is actually elem.style ... set the style
		
		// IE uses filters for opacity
		if ( msie && name == "opacity" ) {
			if ( set ) {
				// IE has trouble with opacity if it does not have layout
				// Force it by setting the zoom level
				elem.zoom = 1;

				// Set the alpha filter to set the opacity
				elem.filter = (elem.filter || "").replace( /alpha\([^)]*\)/, "" ) +
					(parseInt( value ) + '' == "NaN" ? "" : "alpha(opacity=" + value * 100 + ")");
			}
			
			return elem.filter && elem.filter.indexOf("opacity=") >= 0 ?
				(parseFloat( elem.filter.match(/opacity=([^)]*)/)[1] ) / 100) + '':
				"";
		}

		name = name.replace(/-([a-z])/ig, function(all, letter){
			return letter.toUpperCase();
		});

		if ( set )
			elem[ name ] = value;

		return elem[ name ];
	},
	trim: function( text ) {
		return (text || "").replace( /^\s+|\s+$/g, "" );
	},

	makeArray: function( array ) {
		var ret = [];

		if( array != null ){
			var i = array.length;
			//the window, strings and functions also have 'length'
			if( i == null || array.split || array.setInterval || array.call )
				ret[0] = array;
			else
				while( i )
					ret[--i] = array[i];
		}

		return ret;
	},

	inArray: function( elem, array ) {
		for ( var i = 0, length = array.length; i < length; i++ )
		// Use === because on IE, window == document
			if ( array[ i ] === elem )
				return i;

		return -1;
	},

	merge: function( first, second ) {
		// We have to loop this way because IE & Opera overwrite the length
		// expando of getElementsByTagName
		var i = 0, elem, pos = first.length;
		// Also, we need to make sure that the correct elements are being returned
		// (IE returns comment nodes in a '*' query)
		if ( jQuery.browser.msie ) {
			while ( elem = second[ i++ ] )
				if ( elem.nodeType != 8 )
					first[ pos++ ] = elem;

		} else
			while ( elem = second[ i++ ] )
				first[ pos++ ] = elem;

		return first;
	},

	unique: function( array ) {
		var ret = [], done = {};

		try {

			for ( var i = 0, length = array.length; i < length; i++ ) {
				var id = jQuery.data( array[ i ] );

				if ( !done[ id ] ) {
					done[ id ] = true;
					ret.push( array[ i ] );
				}
			}

		} catch( e ) {
			ret = array;
		}

		return ret;
	},

	grep: function( elems, callback, inv ) {
		var ret = [];

		// Go through the array, only saving the items
		// that pass the validator function
		for ( var i = 0, length = elems.length; i < length; i++ )
			if ( !inv != !callback( elems[ i ], i ) )
				ret.push( elems[ i ] );

		return ret;
	},

	map: function( elems, callback ) {
		var ret = [];

		// Go through the array, translating each of the items to their
		// new value (or values).
		for ( var i = 0, length = elems.length; i < length; i++ ) {
			var value = callback( elems[ i ], i );

			if ( value != null )
				ret[ ret.length ] = value;
		}

		return ret.concat.apply( [], ret );
	}
});

var userAgent = navigator.userAgent.toLowerCase();

// Figure out what browser is being used
jQuery.browser = {
	version: (userAgent.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [])[1],
	safari: /webkit/.test( userAgent ),
	opera: /opera/.test( userAgent ),
	msie: /msie/.test( userAgent ) && !/opera/.test( userAgent ),
	mozilla: /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent )
};

var styleFloat = jQuery.browser.msie ?
	"styleFloat" :
	"cssFloat";
jQuery.extend({
	// Check to see if the W3C box model is being used
	boxModel: !jQuery.browser.msie || document.compatMode == "CSS1Compat",
	props: {
		"for": "htmlFor",
		"class": "className",
		"float": styleFloat,
		cssFloat: styleFloat,
		styleFloat: styleFloat,
		readonly: "readOnly",
		maxlength: "maxLength",
		cellspacing: "cellSpacing"
	}
});

jQuery.each({
	parent: function(elem){return elem.parentNode;},
	parents: function(elem){return jQuery.dir(elem,"parentNode");},
	next: function(elem){return jQuery.nth(elem,2,"nextSibling");},
	prev: function(elem){return jQuery.nth(elem,2,"previousSibling");},
	nextAll: function(elem){return jQuery.dir(elem,"nextSibling");},
	prevAll: function(elem){return jQuery.dir(elem,"previousSibling");},
	siblings: function(elem){return jQuery.sibling(elem.parentNode.firstChild,elem);},
	children: function(elem){return jQuery.sibling(elem.firstChild);},
	contents: function(elem){return jQuery.nodeName(elem,"iframe")?elem.contentDocument||elem.contentWindow.document:jQuery.makeArray(elem.childNodes);}
}, function(name, fn){
	jQuery.fn[ name ] = function( selector ) {
		var ret = jQuery.map( this, fn );

		if ( selector && typeof selector == "string" )
			ret = jQuery.multiFilter( selector, ret );

		return this.pushStack( jQuery.unique( ret ) );
	};
});

jQuery.each({
	appendTo: "append",
	prependTo: "prepend",
	insertBefore: "before",
	insertAfter: "after",
	replaceAll: "replaceWith"
}, function(name, original){
	jQuery.fn[ name ] = function() {
		var args = arguments;

		return this.each(function(){
			for ( var i = 0, length = args.length; i < length; i++ )
				jQuery( args[ i ] )[ original ]( this );
		});
	};
});

jQuery.each({
	removeAttr: function( name ) {
		jQuery.attr( this, name, "" );
		if (this.nodeType == 1)
			this.removeAttribute( name );
	},

	addClass: function( classNames ) {
		jQuery.className.add( this, classNames );
	},

	removeClass: function( classNames ) {
		jQuery.className.remove( this, classNames );
	},

	toggleClass: function( classNames ) {
		jQuery.className[ jQuery.className.has( this, classNames ) ? "remove" : "add" ]( this, classNames );
	},

	remove: function( selector ) {
		if ( !selector || jQuery.filter( selector, [ this ] ).r.length ) {
			// Prevent memory leaks
			jQuery( "*", this ).add(this).each(function(){
				jQuery.event.remove(this);
				jQuery.removeData(this);
			});
			if (this.parentNode)
				this.parentNode.removeChild( this );
		}
	},

	empty: function() {
		// Remove element nodes and prevent memory leaks
		jQuery( ">*", this ).remove();
		// Remove any remaining nodes
		while ( this.firstChild )
			this.removeChild( this.firstChild );
	}
}, function(name, fn){
	jQuery.fn[ name ] = function(){
		return this.each( fn, arguments );
	};
});

jQuery.each([ "Height", "Width" ], function(i, name){
	var type = name.toLowerCase();
	jQuery.fn[ type ] = function( size ) {
		// Get window width or height
		return this[0] == window ?
			// Opera reports document.body.client[Width/Height] properly in both quirks and standards
			jQuery.browser.opera && document.body[ "client" + name ] ||
			// Safari reports inner[Width/Height] just fine (Mozilla and Opera include scroll bar widths)
			jQuery.browser.safari && window[ "inner" + name ] ||
			// Everyone else use document.documentElement or document.body depending on Quirks vs Standards mode
			document.compatMode == "CSS1Compat" && document.documentElement[ "client" + name ] || document.body[ "client" + name ] :
			// Get document width or height
			this[0] == document ?
				// Either scroll[Width/Height] or offset[Width/Height], whichever is greater
				Math.max(
					Math.max(document.body["scroll" + name], document.documentElement["scroll" + name]),
					Math.max(document.body["offset" + name], document.documentElement["offset" + name])
				) :

				// Get or set width or height on the element
				size == undefined ?
					// Get width or height on the element
					(this.length ? jQuery.css( this[0], type ) : null) :

					// Set the width or height on the element (default to pixels if value is unitless)
					this.css( type, size.constructor == String ? size : size + "px" );
	};
});

// Helper function used by the dimensions and offset modules
function num(elem, prop) {
	return elem[0] && parseInt( jQuery.curCSS(elem[0], prop, true), 10 ) || 0;
}var chars = jQuery.browser.safari && parseInt(jQuery.browser.version) < 417 ?
		"(?:[\\w*_-]|\\\\.)" :
		"(?:[\\w\u0128-\uFFFF*_-]|\\\\.)",
	quickChild = new RegExp("^>\\s*(" + chars + "+)"),
	quickID = new RegExp("^(" + chars + "+)(#)(" + chars + "+)"),
	quickClass = new RegExp("^([#.]?)(" + chars + "*)");

jQuery.extend({
	expr: {
		"": function(a,i,m){return m[2]=="*"||jQuery.nodeName(a,m[2]);},
		"#": function(a,i,m){return a.getAttribute("id")==m[2];},
		":": {
			// Position Checks
			lt: function(a,i,m){return i<m[3]-0;},
			gt: function(a,i,m){return i>m[3]-0;},
			nth: function(a,i,m){return m[3]-0==i;},
			eq: function(a,i,m){return m[3]-0==i;},
			first: function(a,i){return i==0;},
			last: function(a,i,m,r){return i==r.length-1;},
			even: function(a,i){return i%2==0;},
			odd: function(a,i){return i%2;},

			// Child Checks
			"first-child": function(a){return a.parentNode.getElementsByTagName("*")[0]==a;},
			"last-child": function(a){return jQuery.nth(a.parentNode.lastChild,1,"previousSibling")==a;},
			"only-child": function(a){return !jQuery.nth(a.parentNode.lastChild,2,"previousSibling");},

			// Parent Checks
			parent: function(a){return a.firstChild;},
			empty: function(a){return !a.firstChild;},

			// Text Check
			contains: function(a,i,m){return (a.textContent||a.innerText||jQuery(a).text()||"").indexOf(m[3])>=0;},

			// Visibility
			visible: function(a){return "hidden"!=a.type&&jQuery.css(a,"display")!="none"&&jQuery.css(a,"visibility")!="hidden";},
			hidden: function(a){return "hidden"==a.type||jQuery.css(a,"display")=="none"||jQuery.css(a,"visibility")=="hidden";},

			// Form attributes
			enabled: function(a){return !a.disabled;},
			disabled: function(a){return a.disabled;},
			checked: function(a){return a.checked;},
			selected: function(a){return a.selected||jQuery.attr(a,"selected");},

			// Form elements
			text: function(a){return "text"==a.type;},
			radio: function(a){return "radio"==a.type;},
			checkbox: function(a){return "checkbox"==a.type;},
			file: function(a){return "file"==a.type;},
			password: function(a){return "password"==a.type;},
			submit: function(a){return "submit"==a.type;},
			image: function(a){return "image"==a.type;},
			reset: function(a){return "reset"==a.type;},
			button: function(a){return "button"==a.type||jQuery.nodeName(a,"button");},
			input: function(a){return /input|select|textarea|button/i.test(a.nodeName);},

			// :has()
			has: function(a,i,m){return jQuery.find(m[3],a).length;},

			// :header
			header: function(a){return /h\d/i.test(a.nodeName);},

			// :animated
			animated: function(a){return jQuery.grep(jQuery.timers,function(fn){return a==fn.elem;}).length;}
		}
	},
	// The regular expressions that power the parsing engine
	parse: [
		// Match: [@value='test'], [@foo]
		/^(\[) *@?([\w-]+) *([!*$^~=]*) *('?"?)(.*?)\4 *\]/,

		// Match: :contains('foo')
		/^(:)([\w-]+)\("?'?(.*?(\(.*?\))?[^(]*?)"?'?\)/,

		// Match: :even, :last-child, #id, .class
		new RegExp("^([:.#]*)(" + chars + "+)")
	],

	multiFilter: function( expr, elems, not ) {
		var old, cur = [];

		while ( expr && expr != old ) {
			old = expr;
			var f = jQuery.filter( expr, elems, not );
			expr = f.t.replace(/^\s*,\s*/, "" );
			cur = not ? elems = f.r : jQuery.merge( cur, f.r );
		}

		return cur;
	},

	find: function( t, context ) {
		// Quickly handle non-string expressions
		if ( typeof t != "string" )
			return [ t ];

		// check to make sure context is a DOM element or a document
		if ( context && context.nodeType != 1 && context.nodeType != 9)
			return [ ];

		// Set the correct context (if none is provided)
		context = context || document;

		// Initialize the search
		var ret = [context], done = [], last, nodeName;

		// Continue while a selector expression exists, and while
		// we're no longer looping upon ourselves
		while ( t && last != t ) {
			var r = [];
			last = t;

			t = jQuery.trim(t);

			var foundToken = false,

			// An attempt at speeding up child selectors that
			// point to a specific element tag
				re = quickChild,
				m = re.exec(t);

			if ( m ) {
				nodeName = m[1].toUpperCase();

				// Perform our own iteration and filter
				for ( var i = 0; ret[i]; i++ )
					for ( var c = ret[i].firstChild; c; c = c.nextSibling )
						if ( c.nodeType == 1 && (nodeName == "*" || c.nodeName.toUpperCase() == nodeName) )
							r.push( c );

				ret = r;
				t = t.replace( re, "" );
				if ( t.indexOf(" ") == 0 ) continue;
				foundToken = true;
			} else {
				re = /^([>+~])\s*(\w*)/i;

				if ( (m = re.exec(t)) != null ) {
					r = [];

					var merge = {};
					nodeName = m[2].toUpperCase();
					m = m[1];

					for ( var j = 0, rl = ret.length; j < rl; j++ ) {
						var n = m == "~" || m == "+" ? ret[j].nextSibling : ret[j].firstChild;
						for ( ; n; n = n.nextSibling )
							if ( n.nodeType == 1 ) {
								var id = jQuery.data(n);

								if ( m == "~" && merge[id] ) break;
								if (!nodeName || n.nodeName.toUpperCase() == nodeName ) {
									if ( m == "~" ) merge[id] = true;
									r.push( n );
								}
								if ( m == "+" ) break;
							}
					}

					ret = r;

					// And remove the token
					t = jQuery.trim( t.replace( re, "" ) );
					foundToken = true;
				}
			}

			// See if there's still an expression, and that we haven't already
			// matched a token
			if ( t && !foundToken ) {
				// Handle multiple expressions
				if ( !t.indexOf(",") ) {
					// Clean the result set
					if ( context == ret[0] ) ret.shift();

					// Merge the result sets
					done = jQuery.merge( done, ret );

					// Reset the context
					r = ret = [context];

					// Touch up the selector string
					t = " " + t.substr(1,t.length);

				} else {
					// Optimize for the case nodeName#idName
					var re2 = quickID;
					var m = re2.exec(t);
					// Re-organize the results, so that they're consistent
					if ( m ) {
						m = [ 0, m[2], m[3], m[1] ];

					} else {
						// Otherwise, do a traditional filter check for
						// ID, class, and element selectors
						re2 = quickClass;
						m = re2.exec(t);
					}

					m[2] = m[2].replace(/\\/g, "");

					var elem = ret[ret.length-1];

					// Try to do a global search by ID, where we can
					if ( m[1] == "#" && elem && elem.getElementById && !jQuery.isXMLDoc(elem) ) {
						// Optimization for HTML document case
						var oid = elem.getElementById(m[2]);
						// Do a quick check for the existence of the actual ID attribute
						// to avoid selecting by the name attribute in IE
						// also check to insure id is a string to avoid selecting an element with the name of 'id' inside a form
						if ( (jQuery.browser.msie||jQuery.browser.opera) && oid && typeof oid.id == "string" && oid.id != m[2] )
							oid = jQuery('[@id="'+m[2]+'"]', elem)[0];

						// Do a quick check for node name (where applicable) so
						// that div#foo searches will be really fast
						ret = r = oid && (!m[3] || jQuery.nodeName(oid, m[3])) ? [oid] : [];
					} else {
						// We need to find all descendant elements
						for ( var i = 0; ret[i]; i++ ) {
							// Grab the tag name being searched for
							var tag = m[1] == "#" && m[3] ? m[3] : m[1] != "" || m[0] == "" ? "*" : m[2];

							// Handle IE7 being really dumb about <object>s
							if ( tag == "*" && ret[i].nodeName.toLowerCase() == "object" )
								tag = "param";

							r = jQuery.merge( r, ret[i].getElementsByTagName( tag ));
						}

						// It's faster to filter by class and be done with it
						if ( m[1] == "." )
							r = jQuery.classFilter( r, m[2] );

						// Same with ID filtering
						if ( m[1] == "#" ) {
							var tmp = [];

							// Try to find the element with the ID
							for ( var i = 0; r[i]; i++ )
								if ( r[i].getAttribute("id") == m[2] ) {
									tmp = [ r[i] ];
									break;
								}

							r = tmp;
						}

						ret = r;
					}

					t = t.replace( re2, "" );
				}

			}

			// If a selector string still exists
			if ( t ) {
				// Attempt to filter it
				var val = jQuery.filter(t,r);
				ret = r = val.r;
				t = jQuery.trim(val.t);
			}
		}

		// An error occurred with the selector;
		// just return an empty set instead
		if ( t )
			ret = [];

		// Remove the root context
		if ( ret && context == ret[0] )
			ret.shift();

		// And combine the results
		done = jQuery.merge( done, ret );

		return done;
	},

	classFilter: function(r,m,not){
		m = " " + m + " ";
		var tmp = [];
		for ( var i = 0; r[i]; i++ ) {
			var pass = (" " + r[i].className + " ").indexOf( m ) >= 0;
			if ( !not && pass || not && !pass )
				tmp.push( r[i] );
		}
		return tmp;
	},

	filter: function(t,r,not) {
		var last;

		// Look for common filter expressions
		while ( t && t != last ) {
			last = t;

			var p = jQuery.parse, m;

			for ( var i = 0; p[i]; i++ ) {
				m = p[i].exec( t );

				if ( m ) {
					// Remove what we just matched
					t = t.substring( m[0].length );

					m[2] = m[2].replace(/\\/g, "");
					break;
				}
			}

			if ( !m )
				break;

			// :not() is a special case that can be optimized by
			// keeping it out of the expression list
			if ( m[1] == ":" && m[2] == "not" )
				// optimize if only one selector found (most common case)
				r = isSimple.test( m[3] ) ?
					jQuery.filter(m[3], r, true).r :
					jQuery( r ).not( m[3] );

			// We can get a big speed boost by filtering by class here
			else if ( m[1] == "." )
				r = jQuery.classFilter(r, m[2], not);

			else if ( m[1] == "[" ) {
				var tmp = [], type = m[3];
				for ( var i = 0, rl = r.length; i < rl; i++ ) {
					var a = r[i], z = a[ jQuery.props[m[2]] || m[2] ];
					if ( z == null || /href|src|selected/.test(m[2]) )
						z = jQuery.attr(a,m[2]) || '';

					if ( (type == "" && !!z ||
						 type == "=" && z == m[5] ||
						 type == "!=" && z != m[5] ||
						 type == "^=" && z && !z.indexOf(m[5]) ||
						 type == "$=" && z.substr(z.length - m[5].length) == m[5] ||
						 (type == "*=" || type == "~=") && z.indexOf(m[5]) >= 0) ^ not )
							tmp.push( a );
				}
				r = tmp;

			// We can get a speed boost by handling nth-child here
			} else if ( m[1] == ":" && m[2] == "nth-child" ) {
				var merge = {}, tmp = [],
					// parse equations like 'even', 'odd', '5', '2n', '3n+2', '4n-1', '-n+6'
					test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
						m[3] == "even" && "2n" || m[3] == "odd" && "2n+1" ||
						!/\D/.test(m[3]) && "0n+" + m[3] || m[3]),
					// calculate the numbers (first)n+(last) including if they are negative
					first = (test[1] + (test[2] || 1)) - 0, last = test[3] - 0;
				// loop through all the elements left in the jQuery object
				for ( var i = 0, rl = r.length; i < rl; i++ ) {
					var node = r[i], parentNode = node.parentNode, id = jQuery.data(parentNode);

					if ( !merge[id] ) {
						var c = 1;

						for ( var n = parentNode.firstChild; n; n = n.nextSibling )
							if ( n.nodeType == 1 )
								n.nodeIndex = c++;

						merge[id] = true;
					}

					var add = false;

					if ( first == 0 ) {
						if ( node.nodeIndex == last )
							add = true;
					} else if ( (node.nodeIndex - last) % first == 0 && (node.nodeIndex - last) / first >= 0 )
						add = true;

					if ( add ^ not )
						tmp.push( node );
				}

				r = tmp;

			// Otherwise, find the expression to execute
			} else {
				var fn = jQuery.expr[ m[1] ];
				if ( typeof fn == "object" )
					fn = fn[ m[2] ];

				if ( typeof fn == "string" )
					fn = eval("false||function(a,i){return " + fn + ";}");

				// Execute it against the current filter
				r = jQuery.grep( r, function(elem, i){
					return fn(elem, i, m, r);
				}, not );
			}
		}

		// Return an array of filtered elements (r)
		// and the modified expression string (t)
		return { r: r, t: t };
	},

	dir: function( elem, dir ){
		var matched = [],
			cur = elem[dir];
		while ( cur && cur != document ) {
			if ( cur.nodeType == 1 )
				matched.push( cur );
			cur = cur[dir];
		}
		return matched;
	},
	nth: function(cur,result,dir,elem){
		result = result || 1;
		var num = 0;

		for ( ; cur; cur = cur[dir] )
			if ( cur.nodeType == 1 && ++num == result )
				break;

		return cur;
	},
	sibling: function( n, elem ) {
		var r = [];

		for ( ; n; n = n.nextSibling ) {
			if ( n.nodeType == 1 && n != elem )
				r.push( n );
		}

		return r;
	}
});
/*
 * A number of helper functions used for managing events.
 * Many of the ideas behind this code orignated from
 * Dean Edwards' addEvent library.
 */
jQuery.event = {

	// Bind an event to an element
	// Original by Dean Edwards
	add: function(elem, types, handler, data) {
		if ( elem.nodeType == 3 || elem.nodeType == 8 )
			return;

		// For whatever reason, IE has trouble passing the window object
		// around, causing it to be cloned in the process
		if ( jQuery.browser.msie && elem.setInterval )
			elem = window;

		// Make sure that the function being executed has a unique ID
		if ( !handler.guid )
			handler.guid = this.guid++;
		// if data is passed, bind to handler
		if( data != undefined ) {
			// Create temporary function pointer to original handler
			var fn = handler;

			// Create unique handler function, wrapped around original handler
			handler = this.proxy( fn, function() {
				// Pass arguments and context to original handler
				return fn.apply(this, arguments);
			});

			// Store data in unique handler
			handler.data = data;
		}

		// Init the element's event structure
		var events = jQuery.data(elem, "events") || jQuery.data(elem, "events", {}),
			handle = jQuery.data(elem, "handle") || jQuery.data(elem, "handle", function(){
				// Handle the second event of a trigger and when
				// an event is called after a page has unloaded
				if ( typeof jQuery != "undefined" && !jQuery.event.triggered )
					return jQuery.event.handle.apply(arguments.callee.elem, arguments);
			});
		// Add elem as a property of the handle function
		// This is to prevent a memory leak with non-native
		// event in IE.
		handle.elem = elem;
		// Handle multiple events separated by a space
		// jQuery(...).bind("mouseover mouseout", fn);
		jQuery.each(types.split(/\s+/), function(index, type) {
			// Namespaced event handlers
			var parts = type.split(".");
			type = parts[0];
			handler.type = parts[1];

			// Get the current list of functions bound to this event
			var handlers = events[type];

			// Init the event handler queue
			if (!handlers) {
				handlers = events[type] = {};
				// Check for a special event handler
				// Only use addEventListener/attachEvent if the special
				// events handler returns false
				if ( !jQuery.event.special[type] || jQuery.event.special[type].setup.call(elem) === false ) {
					// Bind the global event handler to the element
					if (elem.addEventListener)
						elem.addEventListener(type, handle, false);
					else if (elem.attachEvent)
						elem.attachEvent("on" + type, handle);
				}
			}

			// Add the function to the element's handler list
			handlers[handler.guid] = handler;

			// Keep track of which events have been used, for global triggering
			jQuery.event.global[type] = true;
		});
		// Nullify elem to prevent memory leaks in IE
		elem = null;
	},

	guid: 1,
	global: {},

	// Detach an event or set of events from an element
	remove: function(elem, types, handler) {
		// don't do events on text and comment nodes
		if ( elem.nodeType == 3 || elem.nodeType == 8 )
			return;

		var events = jQuery.data(elem, "events"), ret, index;

		if ( events ) {
			// Unbind all events for the element
			if ( types == undefined || (typeof types == "string" && types.charAt(0) == ".") )
				for ( var type in events )
					this.remove( elem, type + (types || "") );
			else {
				// types is actually an event object here
				if ( types.type ) {
					handler = types.handler;
					types = types.type;
				}
				// Handle multiple events seperated by a space
				// jQuery(...).unbind("mouseover mouseout", fn);
				jQuery.each(types.split(/\s+/), function(index, type){
					// Namespaced event handlers
					var parts = type.split(".");
					type = parts[0];
					if(type == 'toJSONString')
						return;
					if ( events[type] ) {
						// remove the given handler for the given type
						if ( handler )
							delete events[type][handler.guid];
						// remove all handlers for the given type
						else
							for ( handler in events[type] )
								// Handle the removal of namespaced events
								if ( !parts[1] || events[type][handler].type == parts[1] )
									delete events[type][handler];

						// remove generic event handler if no more handlers exist
						for ( ret in events[type] ) break;
						if ( !ret ) {
							if ( !jQuery.event.special[type] || jQuery.event.special[type].teardown.call(elem) === false ) {
								if (elem.removeEventListener)
									elem.removeEventListener(type, jQuery.data(elem, "handle"), false);
								else if (elem.detachEvent)
									elem.detachEvent("on" + type, jQuery.data(elem, "handle"));
							}
							ret = null;
							delete events[type];
						}
					}
				});
			}

			// Remove the expando if it's no longer used
			for ( ret in events ) break;
			if ( !ret ) {
				var handle = jQuery.data( elem, "handle" );
				if ( handle ) handle.elem = null;
				jQuery.removeData( elem, "events" );
				jQuery.removeData( elem, "handle" );
			}
		}
	},

	trigger: function(type, data, elem, donative, extra) {
		// Clone the incoming data, if any
		data = jQuery.makeArray(data);

		if ( type.indexOf("!") >= 0 ) {
			type = type.slice(0, -1);
			var exclusive = true;
		}

		// Handle a global trigger
		if ( !elem ) {
			// Only trigger if we've ever bound an event for it
			if ( this.global[type] )
				jQuery("*").add([window, document]).trigger(type, data);

		// Handle triggering a single element
		} else {
			// don't do events on text and comment nodes
			if ( elem.nodeType == 3 || elem.nodeType == 8 )
				return undefined;

			var val, ret, fn = jQuery.isFunction( elem[ type ] || null ),
				// Check to see if we need to provide a fake event, or not
				event = !data[0] || !data[0].preventDefault;
			// Pass along a fake event
			if ( event ) {
				data.unshift({
					type: type,
					target: elem,
					preventDefault: function(){},
					stopPropagation: function(){},
					timeStamp: now()
				});
				data[0][expando] = true; // no need to fix fake event
			}

			// Enforce the right trigger type
			data[0].type = type;
			if ( exclusive )
				data[0].exclusive = true;

			// Trigger the event, it is assumed that "handle" is a function
			var handle = jQuery.data(elem, "handle");
			if ( handle )
				val = handle.apply( elem, data );

			// Handle triggering native .onfoo handlers (and on links since we don't call .click() for links)
			if ( (!fn || (jQuery.nodeName(elem, 'a') && type == "click")) && elem["on"+type] && elem["on"+type].apply( elem, data ) === false )
				val = false;

			// Extra functions don't get the custom event object
			if ( event )
				data.shift();

			// Handle triggering of extra function
			if ( extra && jQuery.isFunction( extra ) ) {
				// call the extra function and tack the current return value on the end for possible inspection
				ret = extra.apply( elem, val == null ? data : data.concat( val ) );
				// if anything is returned, give it precedence and have it overwrite the previous value
				if (ret !== undefined)
					val = ret;
			}

			// Trigger the native events (except for clicks on links)
			if ( fn && donative !== false && val !== false && !(jQuery.nodeName(elem, 'a') && type == "click") ) {
				this.triggered = true;
				try {
					elem[ type ]();
				// prevent IE from throwing an error for some hidden elements
				} catch (e) {}
			}

			this.triggered = false;
		}

		return val;
	},

	handle: function(event) {
		// returned undefined or false
		var val, ret, namespace, all, handlers;

		event = arguments[0] = jQuery.event.fix( event || window.event );

		// Namespaced event handlers
		namespace = event.type.split(".");
		event.type = namespace[0];
		namespace = namespace[1];
		// Cache this now, all = true means, any handler
		all = !namespace && !event.exclusive;

		handlers = ( jQuery.data(this, "events") || {} )[event.type];

		for ( var j in handlers ) {
			var handler = handlers[j];

			// Filter the functions by class
			if ( all || handler.type == namespace ) {
				// Pass in a reference to the handler function itself
				// So that we can later remove it
				event.handler = handler;
				event.data = handler.data;
				ret = handler.apply( this, arguments );

				if ( val !== false )
					val = ret;

				if ( ret === false ) {
					event.preventDefault();
					event.stopPropagation();
				}
			}
		}

		return val;
	},

	fix: function(event) {
		if ( event[expando] == true )
			return event;
		// store a copy of the original event object
		// and "clone" to set read-only properties
		var originalEvent = event;
		event = { originalEvent: originalEvent };
		var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target timeStamp toElement type view wheelDelta which".split(" ");
		for ( var i=props.length; i; i-- )
			event[ props[i] ] = originalEvent[ props[i] ];

		// Mark it as fixed
		event[expando] = true;
		// add preventDefault and stopPropagation since
		// they will not work on the clone
		event.preventDefault = function() {
			// if preventDefault exists run it on the original event
			if (originalEvent.preventDefault)
				originalEvent.preventDefault();
			// otherwise set the returnValue property of the original event to false (IE)
			originalEvent.returnValue = false;
		};
		event.stopPropagation = function() {
			// if stopPropagation exists run it on the original event
			if (originalEvent.stopPropagation)
				originalEvent.stopPropagation();
			// otherwise set the cancelBubble property of the original event to true (IE)
			originalEvent.cancelBubble = true;
		};
		// Fix timeStamp
		event.timeStamp = event.timeStamp || now();
		// Fix target property, if necessary
		if ( !event.target )
			event.target = event.srcElement || document; // Fixes #1925 where srcElement might not be defined either
		// check if target is a textnode (safari)
		if ( event.target.nodeType == 3 )
			event.target = event.target.parentNode;

		// Add relatedTarget, if necessary
		if ( !event.relatedTarget && event.fromElement )
			event.relatedTarget = event.fromElement == event.target ? event.toElement : event.fromElement;

		// Calculate pageX/Y if missing and clientX/Y available
		if ( event.pageX == null && event.clientX != null ) {
			var doc = document.documentElement, body = document.body;
			event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc.clientLeft || 0);
			event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc.clientTop || 0);
		}
		// Add which for key events
		if ( !event.which && ((event.charCode || event.charCode === 0) ? event.charCode : event.keyCode) )
			event.which = event.charCode || event.keyCode;
		// Add metaKey to non-Mac browsers (use ctrl for PC's and Meta for Macs)
		if ( !event.metaKey && event.ctrlKey )
			event.metaKey = event.ctrlKey;

		// Add which for click: 1 == left; 2 == middle; 3 == right
		// Note: button is not normalized, so don't use it
		if ( !event.which && event.button )
			event.which = (event.button & 1 ? 1 : ( event.button & 2 ? 3 : ( event.button & 4 ? 2 : 0 ) ));
		if(typeof event.layerX == 'undefined')
			event.layerX = (typeof originalEvent.layerX == 'undefined') ? ((typeof event.offsetX == 'undefined') ? originalEvent.offsetX : event.offsetX) : originalEvent.layerX;
		if(typeof event.layerY == 'undefined')
			event.layerY = (typeof originalEvent.layerY == 'undefined') ? ((typeof event.offsetY == 'undefined') ? originalEvent.offsetY : event.offsetY) : originalEvent.layerY;
		return event;
	},
	proxy: function( fn, proxy ){
		// Set the guid of unique handler to the same of original handler, so it can be removed
		proxy.guid = fn.guid = fn.guid || proxy.guid || this.guid++;
		// So proxy can be declared as an argument
		return proxy;
	},
	special: {
		ready: {
			setup: function() {
				// Make sure the ready event is setup
				bindReady();
				return;
			},
			teardown: function() { return; }
		},
		mouseenter: {
			setup: function() {
				if ( jQuery.browser.msie ) return false;
				jQuery(this).bind("mouseover", jQuery.event.special.mouseenter.handler);
				return true;
			},
			teardown: function() {
				if ( jQuery.browser.msie ) return false;
				jQuery(this).unbind("mouseover", jQuery.event.special.mouseenter.handler);
				return true;
			},
			handler: function(event) {
				// If we actually just moused on to a sub-element, ignore it
				if ( withinElement(event, this) ) return true;
				// Execute the right handlers by setting the event type to mouseenter
				event.type = "mouseenter";
				return jQuery.event.handle.apply(this, arguments);
			}
		},
		mouseleave: {
			setup: function() {
				if ( jQuery.browser.msie ) return false;
				jQuery(this).bind("mouseout", jQuery.event.special.mouseleave.handler);
				return true;
			},
			teardown: function() {
				if ( jQuery.browser.msie ) return false;
				jQuery(this).unbind("mouseout", jQuery.event.special.mouseleave.handler);
				return true;
			},
			handler: function(event) {
				// If we actually just moused on to a sub-element, ignore it
				if ( withinElement(event, this) ) return true;
				// Execute the right handlers by setting the event type to mouseleave
				event.type = "mouseleave";
				return jQuery.event.handle.apply(this, arguments);
			}
		}
	}
};

jQuery.fn.extend({
	bind: function( type, data, fn ) {
		return type == "unload" ? this.one(type, data, fn) : this.each(function(){
			jQuery.event.add( this, type, fn || data, fn && data );
		});
	},
	one: function( type, data, fn ) {
		var one = jQuery.event.proxy( fn || data, function(event) {
			jQuery(this).unbind(event, one);
			return (fn || data).apply( this, arguments );
		});
		return this.each(function(){
			jQuery.event.add( this, type, one, fn && data);
		});
	},

	unbind: function( type, fn ) {
		return this.each(function(){
			jQuery.event.remove( this, type, fn );
		});
	},

	trigger: function( type, data, fn ) {
		return this.each(function(){
			jQuery.event.trigger( type, data, this, true, fn );
		});
	},

	triggerHandler: function( type, data, fn ) {
		return this[0] && jQuery.event.trigger( type, data, this[0], false, fn );
	},

	toggle: function( fn ) {
		// Save reference to arguments for access in closure
		var args = arguments, i = 1;

		// link all the functions, so any of them can unbind this click handler
		while( i < args.length )
			jQuery.event.proxy( fn, args[i++] );
		return this.click( jQuery.event.proxy( fn, function(event) {
			// Figure out which function to execute
			this.lastToggle = ( this.lastToggle || 0 ) % i;
			// Make sure that clicks stop
			event.preventDefault();
			// and execute the function
			return args[ this.lastToggle++ ].apply( this, arguments ) || false;
		}));
	},

	hover: function(fnOver, fnOut) {
		return this.bind('mouseenter', fnOver).bind('mouseleave', fnOut);
	},
	ready: function(fn) {
		// Attach the listeners
		bindReady();

		// If the DOM is already ready
		if ( jQuery.isReady )
			// Execute the function immediately
			fn.call( document, jQuery );
		// Otherwise, remember the function for later
		else
			// Add the function to the wait list
			jQuery.readyList.push( function() { return fn.call(this, jQuery); } );
		return this;
	}
});

jQuery.extend({
	isReady: false,
	readyList: [],
	// Handle when the DOM is ready
	ready: function() {
		// Make sure that the DOM is not already loaded
		if ( !jQuery.isReady ) {
			// Remember that the DOM is ready
			jQuery.isReady = true;
			// If there are functions bound, to execute
			if ( jQuery.readyList ) {
				// Execute all of them
				jQuery.each( jQuery.readyList, function(){
					this.call( document );
				});
				// Reset the list of functions
				jQuery.readyList = null;
			}
			// Trigger any bound ready events
			jQuery(document).triggerHandler("ready");
		}
	}
});

var readyBound = false;

function bindReady(){
	if ( readyBound ) return;
	readyBound = true;

	// Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
	if ( document.addEventListener && !jQuery.browser.opera)
		// Use the handy event callback
		document.addEventListener( "DOMContentLoaded", jQuery.ready, false );
	// If IE is used and is not in a frame
	// Continually check to see if the document is ready
	if ( jQuery.browser.msie && window == top ) (function(){
		if (jQuery.isReady) return;
		try {
			// If IE is used, use the trick by Diego Perini
			// http://javascript.nwbox.com/IEContentLoaded/
			document.documentElement.doScroll("left");
		} catch( error ) {
			setTimeout( arguments.callee, 0 );
			return;
		}
		// and execute any waiting functions
		jQuery.ready();
	})();

	if ( jQuery.browser.opera )
		document.addEventListener( "DOMContentLoaded", function () {
			if (jQuery.isReady) return;
			for (var i = 0; i < document.styleSheets.length; i++)
				if (document.styleSheets[i].disabled) {
					setTimeout( arguments.callee, 0 );
					return;
				}
			// and execute any waiting functions
			jQuery.ready();
		}, false);

	if ( jQuery.browser.safari ) {
		var numStyles;
		(function(){
			if (jQuery.isReady) return;
			if ( document.readyState != "loaded" && document.readyState != "complete" ) {
				setTimeout( arguments.callee, 0 );
				return;
			}
			if ( numStyles === undefined )
				numStyles = jQuery("style, link[rel=stylesheet]").length;
			if ( document.styleSheets.length != numStyles ) {
				setTimeout( arguments.callee, 0 );
				return;
			}
			// and execute any waiting functions
			jQuery.ready();
		})();
	}

	// A fallback to window.onload, that will always work
	jQuery.event.add( window, "load", jQuery.ready );
}

jQuery.each( ("blur,focus,load,resize,scroll,unload,click,dblclick," +
	"mousedown,mouseup,mousemove,mouseover,mouseout,change,select," +
	"submit,keydown,keypress,keyup,error").split(","), function(i, name){
	// Handle event binding
	jQuery.fn[name] = function(fn){
		return fn ? this.bind(name, fn) : this.trigger(name);
	};
});

// Checks if an event happened on an element within another element
// Used in jQuery.event.special.mouseenter and mouseleave handlers
var withinElement = function(event, elem) {
	// Check if mouse(over|out) are still within the same parent element
	var parent = event.relatedTarget;
	// Traverse up the tree
	while ( parent && parent != elem ) try { parent = parent.parentNode; } catch(error) { parent = elem; }
	// Return true if we actually just moused on to a sub-element
	return parent == elem;
};

// Prevent memory leaks in IE
// And prevent errors on refresh with events like mouseover in other browsers
// Window isn't included so as not to unbind existing unload events
jQuery(window).bind("unload", function() {
	jQuery("*").add(document).unbind();
});
jQuery.fn.extend({
	// Keep a copy of the old load
	_load: jQuery.fn.load,
	load: function( url, params, callback ) {
		if ( typeof url != 'string' )
			return this._load( url );

		var off = url.indexOf(" ");
		if ( off >= 0 ) {
			var selector = url.slice(off, url.length);
			url = url.slice(0, off);
		}

		callback = callback || function(){};

		// Default to a GET request
		var type = "GET";

		// If the second parameter was provided
		if ( params )
			// If it's a function
			if ( jQuery.isFunction( params ) ) {
				// We assume that it's the callback
				callback = params;
				params = null;

			// Otherwise, build a param string
			} else {
				params = jQuery.param( params );
				type = "POST";
			}

		var self = this;

		// Request the remote document
		jQuery.ajax({
			url: url,
			type: type,
			dataType: "html",
			data: params,
			complete: function(res, status){
				// If successful, inject the HTML into all the matched elements
				if ( status == "success" || status == "notmodified" )
					// See if a selector was specified
					self.html( selector ?
						// Create a dummy div to hold the results
						jQuery("<div/>")
							// inject the contents of the document in, removing the scripts
							// to avoid any 'Permission Denied' errors in IE
							.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))

							// Locate the specified elements
							.find(selector) :

						// If not, just inject the full result
						res.responseText );

				self.each( callback, [res.responseText, status, res] );
			}
		});
		return this;
	},

	serialize: function() {
		return jQuery.param(this.serializeArray());
	},
	serializeArray: function() {
		return this.map(function(){
			return jQuery.nodeName(this, "form") ?
				jQuery.makeArray(this.elements) : this;
		})
		.filter(function(){
			return this.name && !this.disabled &&
				(this.checked || /select|textarea/i.test(this.nodeName) ||
					/text|hidden|password/i.test(this.type));
		})
		.map(function(i, elem){
			var val = jQuery(this).val();
			return val == null ? null :
				val.constructor == Array ?
					jQuery.map( val, function(val, i){
						return {name: elem.name, value: val};
					}) :
					{name: elem.name, value: val};
		}).get();
	}
});

// Attach a bunch of functions for handling common AJAX events
jQuery.each( "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","), function(i,o){
	jQuery.fn[o] = function(f){
		return this.bind(o, f);
	};
});

var jsc = now();

jQuery.extend({
	get: function( url, data, callback, type ) {
		// shift arguments if data argument was ommited
		if ( jQuery.isFunction( data ) ) {
			callback = data;
			data = null;
		}
		return jQuery.ajax({
			type: "GET",
			url: url,
			data: data,
			success: callback,
			dataType: type
		});
	},

	getScript: function( url, callback ) {
		return jQuery.get(url, null, callback, "script");
	},

	getJSON: function( url, data, callback ) {
		return jQuery.get(url, data, callback, "json");
	},

	post: function( url, data, callback, type ) {
		if ( jQuery.isFunction( data ) ) {
			callback = data;
			data = {};
		}

		return jQuery.ajax({
			type: "POST",
			url: url,
			data: data,
			success: callback,
			dataType: type
		});
	},

	ajaxSetup: function( settings ) {
		jQuery.extend( jQuery.ajaxSettings, settings );
	},

	ajaxSettings: {
		url: location.href,
		global: true,
		type: "GET",
		timeout: 0,
		contentType: "application/x-www-form-urlencoded",
		processData: true,
		async: true,
		data: null,
		username: null,
		password: null,
		accepts: {
			xml: "application/xml, text/xml",
			html: "text/html",
			script: "text/javascript, application/javascript",
			json: "application/json, text/javascript",
			text: "text/plain",
			_default: "*/*"
		}
	},
	// Last-Modified header cache for next request
	lastModified: {},

	ajax: function( s ) {
		// Extend the settings, but re-extend 's' so that it can be
		// checked again later (in the test suite, specifically)
		s = jQuery.extend(true, s, jQuery.extend(true, {}, jQuery.ajaxSettings, s));

		var jsonp, jsre = /=\?(&|$)/g, status, data,
			type = s.type.toUpperCase();
		jsre = /=(\?|%3F)/g;
		// convert data if not already a string
		if ( s.data && s.processData && typeof s.data != "string" )
			s.data = jQuery.param(s.data);

		// Handle JSONP Parameter Callbacks
		if ( s.dataType == "jsonp" ) {
			if ( type == "GET" ) {
				if ( !s.url.match(jsre) )
					s.url += (s.url.match(/\?/) ? "&" : "?") + (s.jsonp || "callback") + "=?";
			} else if ( !s.data || !s.data.match(jsre) )
				s.data = (s.data ? s.data + "&" : "") + (s.jsonp || "callback") + "=?";
			s.dataType = "json";
		}

		// Build temporary JSONP function
		if ( s.dataType == "json" && (s.data && s.data.match(jsre) || s.url.match(jsre)) ) {
			jsonp = "jsonp" + jsc++;

			// Replace the =? sequence both in the query string and the data
			// if ( s.data )
				// s.data = (s.data + "").replace(jsre, "=" + jsonp + "$1");
			// s.url = s.url.replace(jsre, "=" + jsonp + "$1");
			if ( s.data )
				s.data = s.data.replace(jsre, "=" + jsonp);
			s.url = s.url.replace(jsre, "=" + jsonp);
			// We need to make sure
			// that a JSONP style response is executed properly
			s.dataType = "script";

			// Handle JSONP-style loading
			window[ jsonp ] = function(tmp){
				data = tmp;
				success();
				complete();
				// Garbage collect
				window[ jsonp ] = undefined;
				try{ delete window[ jsonp ]; } catch(e){}
				if ( head )
					head.removeChild( script );
			};
		}

		if ( s.dataType == "script" && s.cache == null )
			s.cache = false;

		if ( s.cache === false && type == "GET" ) {
			var ts = now();
			// try replacing _= if it is there
			var ret = s.url.replace(/(\?|&)_=.*?(&|$)/, "$1_=" + ts + "$2");
			// if nothing was replaced, add timestamp to the end
			s.url = ret + ((ret == s.url) ? (s.url.match(/\?/) ? "&" : "?") + "_=" + ts : "");
		}

		// If data is available, append data to url for get requests
		if ( s.data && type == "GET" ) {
			s.url += (s.url.match(/\?/) ? "&" : "?") + s.data;

			// IE likes to send both get and post data, prevent this
			s.data = null;
		}

		// Watch for a new set of requests
		if ( s.global && ! jQuery.active++ )
			jQuery.event.trigger( "ajaxStart" );

		// Matches an absolute URL, and saves the domain
		var remote = /^(?:\w+:)?\/\/([^\/?#]+)/;
		// If we're requesting a remote document
		// and trying to load JSON or Script with a GET
		if ( s.dataType == "script" && type == "GET"
				&& remote.test(s.url) && remote.exec(s.url)[1] != location.host ){
			var head = document.getElementsByTagName("head")[0];
			var script = document.createElement("script");
			script.src = s.url;
			if (s.scriptCharset)
				script.charset = s.scriptCharset;

			// Handle Script loading
			if ( !jsonp ) {
				var done = false;

				// Attach handlers for all browsers
				script.onload = script.onreadystatechange = function(){
					if ( !done && (!this.readyState ||
							this.readyState == "loaded" || this.readyState == "complete") ) {
						done = true;
						success();
						complete();
						head.removeChild( script );
					}
				};
			}

			head.appendChild(script);

			// We handle everything using the script element injection
			return undefined;
		}

		var requestDone = false;

		// Create the request object; Microsoft failed to properly
		// implement the XMLHttpRequest in IE7, so we use the ActiveXObject when it is available
		var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();

		// Open the socket
		// Passing null username, generates a login popup on Opera (#2865)
		if( s.username )
			xhr.open(type, s.url, s.async, s.username, s.password);
		else
			xhr.open(type, s.url, s.async);

		// Need an extra try/catch for cross domain requests in Firefox 3
		try {
			// Set the correct header, if data is being sent
			if ( s.data )
				xhr.setRequestHeader("Content-Type", s.contentType);

			// Set the If-Modified-Since header, if ifModified mode.
			if ( s.ifModified )
				xhr.setRequestHeader("If-Modified-Since",
					jQuery.lastModified[s.url] || "Thu, 01 Jan 1970 00:00:00 GMT" );

			// Set header so the called script knows that it's an XMLHttpRequest
			xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");

			// Set the Accepts header for the server, depending on the dataType
			xhr.setRequestHeader("Accept", s.dataType && s.accepts[ s.dataType ] ?
				s.accepts[ s.dataType ] + ", */*" :
				s.accepts._default );
		} catch(e){}

		// Allow custom headers/mimetypes
		if ( s.beforeSend && s.beforeSend(xhr, s) === false ) {
			// cleanup active request counter
			s.global && jQuery.active--;
			// close opended socket
			xhr.abort();
			return false;
		}
		if ( s.global )
			jQuery.event.trigger("ajaxSend", [xhr, s]);

		// Wait for a response to come back
		var onreadystatechange = function(isTimeout){
			// The transfer is complete and the data is available, or the request timed out
			if ( !requestDone && xhr && (xhr.readyState == 4 || isTimeout == "timeout") ) {
				requestDone = true;
				// clear poll interval
				if (ival) {
					clearInterval(ival);
					ival = null;
				}
				status = isTimeout == "timeout" && "timeout" ||
					!jQuery.httpSuccess( xhr ) && "error" ||
					s.ifModified && jQuery.httpNotModified( xhr, s.url ) && "notmodified" ||
					"success";

				if ( status == "success" ) {
					// Watch for, and catch, XML document parse errors
					try {
						// process the data (runs the xml through httpData regardless of callback)
						data = jQuery.httpData( xhr, s.dataType, s.dataFilter );
					} catch(e) {
						status = "parsererror";
					}
				}

				// Make sure that the request was successful or notmodified
				if ( status == "success" ) {
					// Cache Last-Modified header, if ifModified mode.
					var modRes;
					try {
						modRes = xhr.getResponseHeader("Last-Modified");
					} catch(e) {} // swallow exception thrown by FF if header is not available
					if ( s.ifModified && modRes )
						jQuery.lastModified[s.url] = modRes;

					// JSONP handles its own success callback
					if ( !jsonp )
						success();
				} else
					jQuery.handleError(s, xhr, status);

				// Fire the complete handlers
				complete();

				// Stop memory leaks
				if ( s.async )
					xhr = null;
			}
		};
		if ( s.async ) {
			// don't attach the handler to the request, just poll it instead
			var ival = setInterval(onreadystatechange, 13);

			// Timeout checker
			if ( s.timeout > 0 )
				setTimeout(function(){
					// Check to see if the request is still happening
					if ( xhr ) {
						// Cancel the request
						xhr.abort();
						if( !requestDone )
							onreadystatechange( "timeout" );
					}
				}, s.timeout);
		}
		// Send the data
		try {
			xhr.send(s.data);
		} catch(e) {
			jQuery.handleError(s, xhr, null, e);
		}
		// firefox 1.5 doesn't fire statechange for sync requests
		if ( !s.async )
			onreadystatechange();

		function success(){
			// If a local callback was specified, fire it and pass it the data
			if ( s.success )
				s.success( data, status );

			// Fire the global callback
			if ( s.global )
				jQuery.event.trigger( "ajaxSuccess", [xhr, s] );
		}

		function complete(){
			// Process result
			if ( s.complete )
				s.complete(xhr, status);

			// The request was completed
			if ( s.global )
				jQuery.event.trigger( "ajaxComplete", [xhr, s] );

			// Handle the global AJAX counter
			if ( s.global && ! --jQuery.active )
				jQuery.event.trigger( "ajaxStop" );
		}
		// return XMLHttpRequest to allow aborting the request etc.
		return xhr;
	},

	handleError: function( s, xhr, status, e ) {
		// If a local callback was specified, fire it
		if ( s.error ) s.error( xhr, status, e );

		// Fire the global callback
		if ( s.global )
			jQuery.event.trigger( "ajaxError", [xhr, s, e] );
	},

	// Counter for holding the number of active queries
	active: 0,

	// Determines if an XMLHttpRequest was successful or not
	httpSuccess: function( xhr ) {
		try {
			// IE error sometimes returns 1223 when it should be 204 so treat it as success, see #1450
			return !xhr.status && location.protocol == "file:" ||
				( xhr.status >= 200 && xhr.status < 300 ) || xhr.status == 304 || xhr.status == 1223 ||
				jQuery.browser.safari && xhr.status == undefined;
		} catch(e){}
		return false;
	},

	// Determines if an XMLHttpRequest returns NotModified
	httpNotModified: function( xhr, url ) {
		try {
			var xhrRes = xhr.getResponseHeader("Last-Modified");

			// Firefox always returns 200. check Last-Modified date
			return xhr.status == 304 || xhrRes == jQuery.lastModified[url] ||
				jQuery.browser.safari && xhr.status == undefined;
		} catch(e){}
		return false;
	},

	httpData: function( xhr, type, filter ) {
		var ct = xhr.getResponseHeader("content-type"),
			xml = type == "xml" || !type && ct && ct.indexOf("xml") >= 0,
			data = xml ? xhr.responseXML : xhr.responseText;

		if ( xml && data.documentElement.tagName == "parsererror" )
			throw "parsererror";
		// Allow a pre-filtering function to sanitize the response
		if( filter )
			data = filter( data, type );

		// If the type is "script", eval it in global context
		if ( type == "script" )
			jQuery.globalEval( data );

		// Get the JavaScript object, if JSON is used.
		if ( type == "json" )
			data = eval("(" + data + ")");

		return data;
	},

	// Serialize an array of form elements or a set of
	// key/values into a query string
	param: function( a ) {
		var s = [];

		// If an array was passed in, assume that it is an array
		// of form elements
		if ( a.constructor == Array || a.jquery )
			// Serialize the form elements
			jQuery.each( a, function(){
				s.push( encodeURIComponent(this.name) + "=" + encodeURIComponent( this.value ) );
			});

		// Otherwise, assume that it's an object of key/value pairs
		else
			// Serialize the key/values
			for ( var j in a )
				// If the value is an array then the key names need to be repeated
				if ( a[j] && a[j].constructor == Array )
					jQuery.each( a[j], function(){
						s.push( encodeURIComponent(j) + "=" + encodeURIComponent( this ) );
					});
				else
					s.push( encodeURIComponent(j) + "=" + encodeURIComponent( jQuery.isFunction(a[j]) ? a[j]() : a[j] ) );

		// Return the resulting serialization
		return s.join("&").replace(/%20/g, "+");
	}

});
jQuery.fn.extend({
	show: function(speed,callback){
		return speed ?
			this.animate({
				height: "show", width: "show", opacity: "show"
			}, speed, callback) :
			this.filter(":hidden").each(function(){
				this.style.display = this.oldblock || "";
				if ( jQuery.css(this,"display") == "none" ) {
					var elem = jQuery("<" + this.tagName + " />").appendTo("body");
					this.style.display = elem.css("display");
					// handle an edge condition where css is - div { display:none; } or similar
					if (this.style.display == "none")
						this.style.display = "block";
					elem.remove();
				}
			}).end();
	},
	hide: function(speed,callback){
		return speed ?
			this.animate({
				height: "hide", width: "hide", opacity: "hide"
			}, speed, callback) :
			this.filter(":visible").each(function(){
				this.oldblock = this.oldblock || jQuery.css(this,"display");
				this.style.display = "none";
			}).end();
	},

	// Save the old toggle function
	_toggle: jQuery.fn.toggle,
	toggle: function( fn, fn2 ){
		return jQuery.isFunction(fn) && jQuery.isFunction(fn2) ?
			this._toggle.apply( this, arguments ) :
			fn ?
				this.animate({
					height: "toggle", width: "toggle", opacity: "toggle"
				}, fn, fn2) :
				this.each(function(){
					jQuery(this)[ jQuery(this).is(":hidden") ? "show" : "hide" ]();
				});
	},
	slideDown: function(speed,callback){
		return this.animate({height: "show"}, speed, callback);
	},
	slideUp: function(speed,callback){
		return this.animate({height: "hide"}, speed, callback);
	},

	slideToggle: function(speed, callback){
		return this.animate({height: "toggle"}, speed, callback);
	},
	fadeIn: function(speed, callback){
		return this.animate({opacity: "show"}, speed, callback);
	},
	fadeOut: function(speed, callback){
		return this.animate({opacity: "hide"}, speed, callback);
	},
	fadeTo: function(speed,to,callback){
		return this.animate({opacity: to}, speed, callback);
	},
	animate: function( prop, speed, easing, callback ) {
		var optall = jQuery.speed(speed, easing, callback);

		return this[ optall.queue === false ? "each" : "queue" ](function(){
			if ( this.nodeType != 1)
				return false;

			var opt = jQuery.extend({}, optall), p,
				hidden = jQuery(this).is(":hidden"), self = this;

			for ( p in prop ) {
				if ( prop[p] == "hide" && hidden || prop[p] == "show" && !hidden )
					return opt.complete.call(this);

				if ( p == "height" || p == "width" ) {
					// Store display property
					opt.display = jQuery.css(this, "display");

					// Make sure that nothing sneaks out
					opt.overflow = this.style.overflow;
				}
			}

			if ( opt.overflow != null )
				this.style.overflow = "hidden";

			opt.curAnim = jQuery.extend({}, prop);
			jQuery.each( prop, function(name, val){
				var e = new jQuery.fx( self, opt, name );

				if ( /toggle|show|hide/.test(val) )
					e[ val == "toggle" ? hidden ? "show" : "hide" : val ]( prop );
				else {
					var parts = val.toString().match(/^([+-]=)?([\d+-.]+)(.*)$/),
						start = e.cur(true) || 0;

					if ( parts ) {
						var end = parseFloat(parts[2]),
							unit = parts[3] || "px";

						// We need to compute starting value
						if ( unit != "px" ) {
							self.style[ name ] = (end || 1) + unit;
							start = ((end || 1) / e.cur(true)) * start;
							self.style[ name ] = start + unit;
						}

						// If a +=/-= token was provided, we're doing a relative animation
						if ( parts[1] )
							end = ((parts[1] == "-=" ? -1 : 1) * end) + start;

						e.custom( start, end, unit );
					} else
						e.custom( start, val, "" );
				}
			});

			// For JS strict compliance
			return true;
		});
	},
	queue: function(type, fn){
		if ( jQuery.isFunction(type) || ( type && type.constructor == Array )) {
			fn = type;
			type = "fx";
		}

		if ( !type || (typeof type == "string" && !fn) )
			return queue( this[0], type );

		return this.each(function(){
			if ( fn.constructor == Array )
				queue(this, type, fn);
			else {
				queue(this, type).push( fn );
				if ( queue(this, type).length == 1 )
					fn.call(this);
			}
		});
	},

	stop: function(clearQueue, gotoEnd){
		var timers = jQuery.timers;

		if (clearQueue)
			this.queue([]);

		this.each(function(){
			// go in reverse order so anything added to the queue during the loop is ignored
			for ( var i = timers.length - 1; i >= 0; i-- )
				if ( timers[i].elem == this ) {
					if (gotoEnd)
						// force the next step to be the last
						timers[i](true);
					timers.splice(i, 1);
				}
		});

		// start the next in the queue if the last step wasn't forced
		if (!gotoEnd)
			this.dequeue();

		return this;
	}

});

var queue = function( elem, type, array ) {
	if ( elem ){

		type = type || "fx";

		var q = jQuery.data( elem, type + "queue" );

		if ( !q || array )
			q = jQuery.data( elem, type + "queue", jQuery.makeArray(array) );
	}
	return q;
};

jQuery.fn.dequeue = function(type){
	type = type || "fx";

	return this.each(function(){
		var q = queue(this, type);

		q.shift();

		if ( q.length )
			q[0].call( this );
	});
};

jQuery.extend({
	speed: function(speed, easing, fn) {
		var opt = speed && speed.constructor == Object ? speed : {
			complete: fn || !fn && easing ||
				jQuery.isFunction( speed ) && speed,
			duration: speed,
			easing: fn && easing || easing && easing.constructor != Function && easing
		};

		opt.duration = (opt.duration && opt.duration.constructor == Number ?
			opt.duration :
			jQuery.fx.speeds[opt.duration]) || jQuery.fx.speeds.def;
		// Queueing
		opt.old = opt.complete;
		opt.complete = function(){
			if ( opt.queue !== false )
				jQuery(this).dequeue();
			if ( jQuery.isFunction( opt.old ) )
				opt.old.call( this );
		};
		return opt;
	},
	easing: {
		linear: function( p, n, firstNum, diff ) {
			return firstNum + diff * p;
		},
		swing: function( p, n, firstNum, diff ) {
			return ((-Math.cos(p*Math.PI)/2) + 0.5) * diff + firstNum;
		}
	},
	timers: [],
	timerId: null,

	fx: function( elem, options, prop ){
		this.options = options;
		this.elem = elem;
		this.prop = prop;

		if ( !options.orig )
			options.orig = {};
	}

});

jQuery.fx.prototype = {

	// Simple function for setting a style value
	update: function(){
		if ( this.options.step )
			this.options.step.call( this.elem, this.now, this );

		(jQuery.fx.step[this.prop] || jQuery.fx.step._default)( this );

		// Set display property to block for height/width animations
		if ( this.prop == "height" || this.prop == "width" )
			this.elem.style.display = "block";
	},

	// Get the current size
	cur: function(force){
		if ( this.elem[this.prop] != null && this.elem.style[this.prop] == null )
			return this.elem[ this.prop ];

		var r = parseFloat(jQuery.css(this.elem, this.prop, force));
		return r && r > -10000 ? r : parseFloat(jQuery.curCSS(this.elem, this.prop)) || 0;
	},

	// Start an animation from one number to another
	custom: function(from, to, unit){
		this.startTime = now();
		this.start = from;
		this.end = to;
		this.unit = unit || this.unit || "px";
		this.now = this.start;
		this.pos = this.state = 0;
		this.update();

		var self = this;
		function t(gotoEnd){
			return self.step(gotoEnd);
		}

		t.elem = this.elem;

		jQuery.timers.push(t);

		if ( jQuery.timerId == null ) {
			jQuery.timerId = setInterval(function(){
				var timers = jQuery.timers;
				for ( var i = 0; i < timers.length; i++ )
					if ( !timers[i]() )
						timers.splice(i--, 1);

				if ( !timers.length ) {
					clearInterval( jQuery.timerId );
					jQuery.timerId = null;
				}
			}, 13);
		}
	},

	// Simple 'show' function
	show: function(){
		// Remember where we started, so that we can go back to it later
		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
		this.options.show = true;

		// Begin the animation
		this.custom(0, this.cur());

		// Make sure that we start at a small width/height to avoid any
		// flash of content
		if ( this.prop == "width" || this.prop == "height" )
			this.elem.style[this.prop] = "1px";
		// Start by showing the element
		jQuery(this.elem).show();
	},

	// Simple 'hide' function
	hide: function(){
		// Remember where we started, so that we can go back to it later
		this.options.orig[this.prop] = jQuery.attr( this.elem.style, this.prop );
		this.options.hide = true;

		// Begin the animation
		this.custom(this.cur(), 0);
	},

	// Each step of an animation
	step: function(gotoEnd){
		var t = now();

		if ( gotoEnd || t > this.options.duration + this.startTime ) {
			this.now = this.end;
			this.pos = this.state = 1;
			this.update();

			this.options.curAnim[ this.prop ] = true;

			var done = true;
			for ( var i in this.options.curAnim )
				if ( this.options.curAnim[i] !== true )
					done = false;

			if ( done ) {
				if ( this.options.display != null ) {
					// Reset the overflow
					this.elem.style.overflow = this.options.overflow;
					// Reset the display
					this.elem.style.display = this.options.display;
					if ( jQuery.css(this.elem, "display") == "none" )
						this.elem.style.display = "block";
				}

				// Hide the element if the "hide" operation was done
				if ( this.options.hide )
					this.elem.style.display = "none";

				// Reset the properties, if the item has been hidden or shown
				if ( this.options.hide || this.options.show )
					for ( var p in this.options.curAnim )
						jQuery.attr(this.elem.style, p, this.options.orig[p]);
			}

			if ( done )
				// Execute the complete function
				this.options.complete.call( this.elem );

			return false;
		} else {
			var n = t - this.startTime;
			this.state = n / this.options.duration;

			// Perform the easing function, defaults to swing
			this.pos = jQuery.easing[this.options.easing || (jQuery.easing.swing ? "swing" : "linear")](this.state, n, 0, 1, this.options.duration);
			this.now = this.start + ((this.end - this.start) * this.pos);

			// Perform the next step of the animation
			this.update();
		}

		return true;
	}

};

jQuery.extend( jQuery.fx, {
	speeds:{
		slow: 600,
 		fast: 200,
 		// Default speed
 		def: 400
	},
	step: {
		scrollLeft: function(fx){
			fx.elem.scrollLeft = fx.now;
		},

		scrollTop: function(fx){
			fx.elem.scrollTop = fx.now;
		},

		opacity: function(fx){
			jQuery.attr(fx.elem.style, "opacity", fx.now);
		},

		_default: function(fx){
			fx.elem.style[ fx.prop ] = fx.now + fx.unit;
		}
	}
});
// The Offset Method
// Originally By Brandon Aaron, part of the Dimension Plugin
// http://jquery.com/plugins/project/dimensions
jQuery.fn.offset = function() {
	var left = 0, top = 0, elem = this[0], results;
	if ( elem ) with ( jQuery.browser ) {
		var parent       = elem.parentNode,
		    offsetChild  = elem,
		    offsetParent = elem.offsetParent,
		    doc          = elem.ownerDocument,
		    safari2      = safari && parseInt(version) < 522 && !/adobeair/i.test(userAgent),
		    css          = jQuery.curCSS,
		    fixed        = css(elem, "position") == "fixed";
		// Use getBoundingClientRect if available
		if ( elem.getBoundingClientRect ) {
			var box = elem.getBoundingClientRect();
			// Add the document scroll offsets
			add(box.left + Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
				box.top  + Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
			// IE adds the HTML element's border, by default it is medium which is 2px
			// IE 6 and 7 quirks mode the border width is overwritable by the following css html { border: 0; }
			// IE 7 standards mode, the border is always 2px
			// This border/offset is typically represented by the clientLeft and clientTop properties
			// However, in IE6 and 7 quirks mode the clientLeft and clientTop properties are not updated when overwriting it via CSS
			// Therefore this method will be off by 2px in IE while in quirksmode
			add( -doc.documentElement.clientLeft, -doc.documentElement.clientTop );
		// Otherwise loop through the offsetParents and parentNodes
		} else {
			// Initial element offsets
			add( elem.offsetLeft, elem.offsetTop );
			// Get parent offsets
			while ( offsetParent ) {
				// Add offsetParent offsets
				add( offsetParent.offsetLeft, offsetParent.offsetTop );
				// Mozilla and Safari > 2 does not include the border on offset parents
				// However Mozilla adds the border for table or table cells
				if ( mozilla && !/^t(able|d|h)$/i.test(offsetParent.tagName) || safari && !safari2 )
					border( offsetParent );
				// Add the document scroll offsets if position is fixed on any offsetParent
				if ( !fixed && css(offsetParent, "position") == "fixed" )
					fixed = true;
				// Set offsetChild to previous offsetParent unless it is the body element
				offsetChild  = /^body$/i.test(offsetParent.tagName) ? offsetChild : offsetParent;
				// Get next offsetParent
				offsetParent = offsetParent.offsetParent;
			}
			// Get parent scroll offsets
			while ( parent && parent.tagName && !/^body|html$/i.test(parent.tagName) ) {
				// Remove parent scroll UNLESS that parent is inline or a table to work around Opera inline/table scrollLeft/Top bug
				if ( !/^inline|table.*$/i.test(css(parent, "display")) )
					// Subtract parent scroll offsets
					add( -parent.scrollLeft, -parent.scrollTop );
				// Mozilla does not add the border for a parent that has overflow != visible
				if ( mozilla && css(parent, "overflow") != "visible" )
					border( parent );
				// Get next parent
				parent = parent.parentNode;
			}
			// Safari <= 2 doubles body offsets with a fixed position element/offsetParent or absolutely positioned offsetChild
			// Mozilla doubles body offsets with a non-absolutely positioned offsetChild
			if ( (safari2 && (fixed || css(offsetChild, "position") == "absolute")) ||
				(mozilla && css(offsetChild, "position") != "absolute") )
					add( -doc.body.offsetLeft, -doc.body.offsetTop );
			// Add the document scroll offsets if position is fixed
			if ( fixed )
				add(Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft),
					Math.max(doc.documentElement.scrollTop,  doc.body.scrollTop));
		}

		// Return an object with top and left properties
		results = { top: top, left: left };
	}

	function border(elem) {
		add( jQuery.curCSS(elem, "borderLeftWidth", true), jQuery.curCSS(elem, "borderTopWidth", true) );
	}

	function add(l, t) {
		left += parseInt(l, 10) || 0;
		top += parseInt(t, 10) || 0;
	}

	return results;
};

jQuery.fn.extend({
	position: function() {
		var left = 0, top = 0, results;

		if ( this[0] ) {
			// Get *real* offsetParent
			var offsetParent = this.offsetParent(),

			// Get correct offsets
			offset       = this.offset(),
			parentOffset = /^body|html$/i.test(offsetParent[0].tagName) ? { top: 0, left: 0 } : offsetParent.offset();

			// Subtract element margins
			// note: when an element has margin: auto the offsetLeft and marginLeft 
			// are the same in Safari causing offset.left to incorrectly be 0
			offset.top  -= num( this, 'marginTop' );
			offset.left -= num( this, 'marginLeft' );

			// Add offsetParent borders
			parentOffset.top  += num( offsetParent, 'borderTopWidth' );
			parentOffset.left += num( offsetParent, 'borderLeftWidth' );

			// Subtract the two offsets
			results = {
				top:  offset.top  - parentOffset.top,
				left: offset.left - parentOffset.left
			};
		}

		return results;
	},

	offsetParent: function() {
		var offsetParent = this[0].offsetParent;
		while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && jQuery.css(offsetParent, 'position') == 'static') )
			offsetParent = offsetParent.offsetParent;
		return jQuery(offsetParent);
	}
});

// Create scrollLeft and scrollTop methods
jQuery.each( ['Left', 'Top'], function(i, name) {
	var method = 'scroll' + name;
	
	jQuery.fn[ method ] = function(val) {
		if (!this[0]) return;

		return val != undefined ?

			// Set the scroll offset
			this.each(function() {
				this == window || this == document ?
					window.scrollTo(
						!i ? val : jQuery(window).scrollLeft(),
						 i ? val : jQuery(window).scrollTop()
					) :
					this[ method ] = val;
			}) :

			// Return the scroll offset
			this[0] == window || this[0] == document ?
				self[ i ? 'pageYOffset' : 'pageXOffset' ] ||
					jQuery.boxModel && document.documentElement[ method ] ||
					document.body[ method ] :
				this[0][ method ];
	};
});
jQuery.each([ "Height", "Width" ], function(i, name){

	var tl = i ? "Left"  : "Top",  // top or left
		br = i ? "Right" : "Bottom"; // bottom or right

	// innerHeight and innerWidth
	jQuery.fn["inner" + name] = function(){
		return this[ name.toLowerCase() ]() +
			num(this, "padding" + tl) +
			num(this, "padding" + br);
	};

	// outerHeight and outerWidth
	jQuery.fn["outer" + name] = function(margin) {
		return this["inner" + name]() +
			num(this, "border" + tl + "Width") +
			num(this, "border" + br + "Width") +
			(margin ?
				num(this, "margin" + tl) + num(this, "margin" + br) : 0);
	};

});
})();

/******************************************************************************************************************************

 * @ Original idea by by Binny V A, Original version: 2.00.A 
 * @ http://www.openjs.com/scripts/events/keyboard_shortcuts/
 * @ Original License : BSD
 
 * @ jQuery Plugin by Tzury Bar Yochay 
        mail: tzury.by@gmail.com
        blog: evalinux.wordpress.com
        face: facebook.com/profile.php?id=513676303
        
        (c) Copyrights 2007
        
 * @ jQuery Plugin version Beta (0.0.2)
 * @ License: jQuery-License.
 
TODO:
    add queue support (as in gmail) e.g. 'x' then 'y', etc.
    add mouse + mouse wheel events.

USAGE:
    $.hotkeys.add('Ctrl+c', function(){ alert('copy anyone?');});
    $.hotkeys.add('Ctrl+c', {target:'div#editor', type:'keyup', propagate: true},function(){ alert('copy anyone?');});>
    $.hotkeys.remove('Ctrl+c'); 
    $.hotkeys.remove('Ctrl+c', {target:'div#editor', type:'keypress'}); 
    
******************************************************************************************************************************/
(function (jQuery){
    this.version = '(beta)(0.0.3)';
	this.all = {};
    this.special_keys = {
        27: 'esc', 9: 'tab', 32:'space', 13: 'return', 8:'backspace', 145: 'scroll', 20: 'capslock', 
        144: 'numlock', 19:'pause', 45:'insert', 36:'home', 46:'del',35:'end', 33: 'pageup', 
        34:'pagedown', 37:'left', 38:'up', 39:'right',40:'down', 112:'f1',113:'f2', 114:'f3', 
        115:'f4', 116:'f5', 117:'f6', 118:'f7', 119:'f8', 120:'f9', 121:'f10', 122:'f11', 123:'f12'};
        
    this.shift_nums = { "`":"~", "1":"!", "2":"@", "3":"#", "4":"$", "5":"%", "6":"^", "7":"&", 
        "8":"*", "9":"(", "0":")", "-":"_", "=":"+", ";":":", "'":"\"", ",":"<", 
        ".":">",  "/":"?",  "\\":"|" };
        
    this.add = function(combi, options, callback) {
        if (jQuery.isFunction(options)){
            callback = options;
            options = {};
        }
        var opt = {},
            defaults = {type: 'keydown', propagate: false, disableInInput: false, target: jQuery('html')[0], checkParent: true},
            that = this;
        opt = jQuery.extend( opt , defaults, options || {} );
        combi = combi.toLowerCase();        
        
        // inspect if keystroke matches
        var inspector = function(event) {
            event = jQuery.event.fix(event); // jQuery event normalization.
            var element = event.target;
            // @ TextNode -> nodeType == 3
            element = (element.nodeType==3) ? element.parentNode : element;
            
            if(opt['disableInInput']) { // Disable shortcut keys in Input, Textarea fields
                var target = jQuery(element);
                if( target.is("input") || target.is("textarea")){
                    return;
                }
            }
            var code = event.which,
                type = event.type,
                character = String.fromCharCode(code).toLowerCase(),
                special = that.special_keys[code],
                shift = event.shiftKey,
                ctrl = event.ctrlKey,
                alt= event.altKey,
                propagate = true, // default behaivour
                mapPoint = null;
            
            // in opera + safari, the event.target is unpredictable.
            // for example: 'keydown' might be associated with HtmlBodyElement 
            // or the element where you last clicked with your mouse.
            if (jQuery.browser.opera || jQuery.browser.safari || opt.checkParent){
                while (!that.all[element] && element.parentNode){
                    element = element.parentNode;
                }
            }
            
            var cbMap = that.all[element].events[type].callbackMap;
            if(!shift && !ctrl && !alt) { // No Modifiers
                mapPoint = cbMap[special] ||  cbMap[character]
			}
            // deals with combinaitons (alt|ctrl|shift+anything)
            else{
                var modif = '';
                if(alt) modif +='alt+';
                if(ctrl) modif+= 'ctrl+';
                if(shift) modif += 'shift+';
                // modifiers + special keys or modifiers + characters or modifiers + shift characters
                mapPoint = cbMap[modif+special] || cbMap[modif+character] || cbMap[modif+that.shift_nums[character]]
            }
            if (mapPoint){
                mapPoint.cb(event);
                if(!mapPoint.propagate) {
                    event.stopPropagation();
                    event.preventDefault();
                    return false;
                }
            }
		};        
        // first hook for this element
        if (!this.all[opt.target]){
            this.all[opt.target] = {events:{}};
        }
        if (!this.all[opt.target].events[opt.type]){
            this.all[opt.target].events[opt.type] = {callbackMap: {}}
            jQuery.event.add(opt.target, opt.type, inspector);
        }        
        this.all[opt.target].events[opt.type].callbackMap[combi] =  {cb: callback, propagate:opt.propagate};                
        return jQuery;
	};    
    this.remove = function(exp, opt) {
        opt = opt || {};
        target = opt.target || jQuery('html')[0];
        type = opt.type || 'keydown';
		exp = exp.toLowerCase();        
        delete this.all[target].events[type].callbackMap[exp]        
        return jQuery;
	};
    jQuery.hotkeys = this;
    return jQuery;    
})(jQuery);
/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 *
 * $LastChangedDate: 2007-08-17 13:14:11 -0500 (Fri, 17 Aug 2007) $
 * $Rev: 2759 $
 *
 * Version: 1.1.2
 *
 * Requires: jQuery 1.1.3+
 */

(function($){

// store a copy of the core height and width methods
var height = $.fn.height,
    width  = $.fn.width;

$.fn.extend({
	/**
	 * If used on document, returns the document's height (innerHeight).
	 * If used on window, returns the viewport's (window) height.
	 * See core docs on height() to see what happens when used on an element.
	 *
	 * @example $("#testdiv").height()
	 * @result 200
	 *
	 * @example $(document).height()
	 * @result 800
	 *
	 * @example $(window).height()
	 * @result 400
	 *
	 * @name height
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	height: function() {
		if ( !this[0] ) error();
		if ( this[0] == window )
			if ( $.browser.opera || ($.browser.safari && parseInt($.browser.version) > 520) )
				return self.innerHeight - (($(document).height() > self.innerHeight) ? getScrollbarWidth() : 0);
			else if ( $.browser.safari )
				return self.innerHeight;
			else
                return $.boxModel && document.documentElement.clientHeight || document.body.clientHeight;
		
		if ( this[0] == document ) 
			return Math.max( ($.boxModel && document.documentElement.scrollHeight || document.body.scrollHeight), document.body.offsetHeight );
		
		return height.apply(this, arguments);
	},
	
	/**
	 * If used on document, returns the document's width (innerWidth).
	 * If used on window, returns the viewport's (window) width.
	 * See core docs on width() to see what happens when used on an element.
	 *
	 * @example $("#testdiv").width()
	 * @result 200
	 *
	 * @example $(document).width()
	 * @result 800
	 *
	 * @example $(window).width()
	 * @result 400
	 *
	 * @name width
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	width: function() {
		if (!this[0]) error();
		if ( this[0] == window )
			if ( $.browser.opera || ($.browser.safari && parseInt($.browser.version) > 520) )
				return self.innerWidth - (($(document).width() > self.innerWidth) ? getScrollbarWidth() : 0);
			else if ( $.browser.safari )
				return self.innerWidth;
			else
                return $.boxModel && document.documentElement.clientWidth || document.body.clientWidth;

		if ( this[0] == document )
			if ($.browser.mozilla) {
				// mozilla reports scrollWidth and offsetWidth as the same
				var scrollLeft = self.pageXOffset;
				self.scrollTo(99999999, self.pageYOffset);
				var scrollWidth = self.pageXOffset;
				self.scrollTo(scrollLeft, self.pageYOffset);
				return document.body.offsetWidth + scrollWidth;
			}
			else 
				return Math.max( (($.boxModel && !$.browser.safari) && document.documentElement.scrollWidth || document.body.scrollWidth), document.body.offsetWidth );

		return width.apply(this, arguments);
	},
	
	/**
	 * Gets the inner height (excludes the border and includes the padding) for the first matched element.
	 * If used on document, returns the document's height (innerHeight).
	 * If used on window, returns the viewport's (window) height.
	 *
	 * @example $("#testdiv").innerHeight()
	 * @result 210
	 *
	 * @name innerHeight
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	innerHeight: function() {
		if (!this[0]) error();
		return this[0] == window || this[0] == document ?
			this.height() :
			this.is(':visible') ?
				this[0].offsetHeight - num(this, 'borderTopWidth') - num(this, 'borderBottomWidth') :
				this.height() + num(this, 'paddingTop') + num(this, 'paddingBottom');
	},
	
	/**
	 * Gets the inner width (excludes the border and includes the padding) for the first matched element.
	 * If used on document, returns the document's width (innerWidth).
	 * If used on window, returns the viewport's (window) width.
	 *
	 * @example $("#testdiv").innerWidth()
	 * @result 210
	 *
	 * @name innerWidth
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	innerWidth: function() {
		if (!this[0]) error();
		return this[0] == window || this[0] == document ?
			this.width() :
			this.is(':visible') ?
				this[0].offsetWidth - num(this, 'borderLeftWidth') - num(this, 'borderRightWidth') :
				this.width() + num(this, 'paddingLeft') + num(this, 'paddingRight');
	},
	
	/**
	 * Gets the outer height (includes the border and padding) for the first matched element.
	 * If used on document, returns the document's height (innerHeight).
	 * If used on window, returns the viewport's (window) height.
	 *
	 * The margin can be included in the calculation by passing an options map with margin
	 * set to true.
	 *
	 * @example $("#testdiv").outerHeight()
	 * @result 220
	 *
	 * @example $("#testdiv").outerHeight({ margin: true })
	 * @result 240
	 *
	 * @name outerHeight
	 * @type Number
	 * @param Map options Optional settings to configure the way the outer height is calculated.
	 * @cat Plugins/Dimensions
	 */
	outerHeight: function(options) {
		if (!this[0]) error();
		options = $.extend({ margin: false }, options || {});
		return this[0] == window || this[0] == document ?
			this.height() :
			this.is(':visible') ?
				this[0].offsetHeight + (options.margin ? (num(this, 'marginTop') + num(this, 'marginBottom')) : 0) :
				this.height() 
					+ num(this,'borderTopWidth') + num(this, 'borderBottomWidth') 
					+ num(this, 'paddingTop') + num(this, 'paddingBottom')
					+ (options.margin ? (num(this, 'marginTop') + num(this, 'marginBottom')) : 0);
	},
	
	/**
	 * Gets the outer width (including the border and padding) for the first matched element.
	 * If used on document, returns the document's width (innerWidth).
	 * If used on window, returns the viewport's (window) width.
	 *
	 * The margin can be included in the calculation by passing an options map with margin
	 * set to true.
	 *
	 * @example $("#testdiv").outerWidth()
	 * @result 1000
	 *
	 * @example $("#testdiv").outerWidth({ margin: true })
	 * @result 1020
	 * 
	 * @name outerHeight
	 * @type Number
	 * @param Map options Optional settings to configure the way the outer width is calculated.
	 * @cat Plugins/Dimensions
	 */
	outerWidth: function(options) {
		if (!this[0]) error();
		options = $.extend({ margin: false }, options || {});
		return this[0] == window || this[0] == document ?
			this.width() :
			this.is(':visible') ?
				this[0].offsetWidth + (options.margin ? (num(this, 'marginLeft') + num(this, 'marginRight')) : 0) :
				this.width() 
					+ num(this, 'borderLeftWidth') + num(this, 'borderRightWidth') 
					+ num(this, 'paddingLeft') + num(this, 'paddingRight')
					+ (options.margin ? (num(this, 'marginLeft') + num(this, 'marginRight')) : 0);
	},
	
	/**
	 * Gets how many pixels the user has scrolled to the right (scrollLeft).
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $(window).scrollLeft()
	 * @result 100
	 *
	 * @example $(document).scrollLeft()
	 * @result 100
	 * 
	 * @example $("#testdiv").scrollLeft()
	 * @result 100
	 *
	 * @name scrollLeft
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	/**
	 * Sets the scrollLeft property for each element and continues the chain.
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $(window).scrollLeft(100).scrollLeft()
	 * @result 100
	 * 
	 * @example $(document).scrollLeft(100).scrollLeft()
	 * @result 100
	 *
	 * @example $("#testdiv").scrollLeft(100).scrollLeft()
	 * @result 100
	 *
	 * @name scrollLeft
	 * @param Number value A positive number representing the desired scrollLeft.
	 * @type jQuery
	 * @cat Plugins/Dimensions
	 */
	scrollLeft: function(val) {
		if (!this[0]) error();
		if ( val != undefined )
			// set the scroll left
			return this.each(function() {
				if (this == window || this == document)
					window.scrollTo( val, $(window).scrollTop() );
				else
					this.scrollLeft = val;
			});
		
		// return the scroll left offest in pixels
		if ( this[0] == window || this[0] == document )
			return self.pageXOffset ||
				$.boxModel && document.documentElement.scrollLeft ||
				document.body.scrollLeft;
				
		return this[0].scrollLeft;
	},
	
	/**
	 * Gets how many pixels the user has scrolled to the bottom (scrollTop).
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $(window).scrollTop()
	 * @result 100
	 *
	 * @example $(document).scrollTop()
	 * @result 100
	 * 
	 * @example $("#testdiv").scrollTop()
	 * @result 100
	 *
	 * @name scrollTop
	 * @type Number
	 * @cat Plugins/Dimensions
	 */
	/**
	 * Sets the scrollTop property for each element and continues the chain.
	 * Works on containers with overflow: auto and window/document.
	 *
	 * @example $(window).scrollTop(100).scrollTop()
	 * @result 100
	 * 
	 * @example $(document).scrollTop(100).scrollTop()
	 * @result 100
	 *
	 * @example $("#testdiv").scrollTop(100).scrollTop()
	 * @result 100
	 *
	 * @name scrollTop
	 * @param Number value A positive number representing the desired scrollTop.
	 * @type jQuery
	 * @cat Plugins/Dimensions
	 */
	scrollTop: function(val) {
		if (!this[0]) error();
		if ( val != undefined )
			// set the scroll top
			return this.each(function() {
				if (this == window || this == document)
					window.scrollTo( $(window).scrollLeft(), val );
				else
					this.scrollTop = val;
			});
		
		// return the scroll top offset in pixels
		if ( this[0] == window || this[0] == document )
			return self.pageYOffset ||
				$.boxModel && document.documentElement.scrollTop ||
				document.body.scrollTop;

		return this[0].scrollTop;
	},
	
	/** 
	 * Gets the top and left positioned offset in pixels.
	 * The positioned offset is the offset between a positioned
	 * parent and the element itself.
	 *
	 * For accurate calculations make sure to use pixel values for margins, borders and padding.
	 *
	 * @example $("#testdiv").position()
	 * @result { top: 100, left: 100 }
	 *
	 * @example var position = {};
	 * $("#testdiv").position(position)
	 * @result position = { top: 100, left: 100 }
	 * 
	 * @name position
	 * @param Object returnObject Optional An object to store the return value in, so as not to break the chain. If passed in the
	 *                            chain will not be broken and the result will be assigned to this object.
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	position: function(returnObject) {
		return this.offset({ margin: false, scroll: false, relativeTo: this.offsetParent() }, returnObject);
	},
	
	/**
	 * Gets the location of the element in pixels from the top left corner of the viewport.
	 * The offset method takes an optional map of key value pairs to configure the way
	 * the offset is calculated. Here are the different options.
	 *
	 * (Boolean) margin - Should the margin of the element be included in the calculations? True by default.
	 * (Boolean) border - Should the border of the element be included in the calculations? False by default. 
	 * (Boolean) padding - Should the padding of the element be included in the calculations? False by default. 
	 * (Boolean) scroll - Should the scroll offsets of the parent elements be included in the calculations? True by default.
	 *                    When true it adds the total scroll offsets of all parents to the total offset and also adds two
	 *                    properties to the returned object, scrollTop and scrollLeft.
	 * (Boolean) lite - When true it will use the offsetLite method instead of the full-blown, slower offset method. False by default.
	 *                  Only use this when margins, borders and padding calculations don't matter.
	 * (HTML Element) relativeTo - This should be a parent of the element and should have position (like absolute or relative).
	 *                             It will retreive the offset relative to this parent element. By default it is the body element.
	 *
	 * Also an object can be passed as the second paramater to
	 * catch the value of the return and continue the chain.
	 *
	 * For accurate calculations make sure to use pixel values for margins, borders and padding.
	 * 
	 * Known issues:
	 *  - Issue: A div positioned relative or static without any content before it and its parent will report an offsetTop of 0 in Safari
	 *    Workaround: Place content before the relative div ... and set height and width to 0 and overflow to hidden
	 *
	 * @example $("#testdiv").offset()
	 * @result { top: 100, left: 100, scrollTop: 10, scrollLeft: 10 }
	 *
	 * @example $("#testdiv").offset({ scroll: false })
	 * @result { top: 90, left: 90 }
	 *
	 * @example var offset = {}
	 * $("#testdiv").offset({ scroll: false }, offset)
	 * @result offset = { top: 90, left: 90 }
	 *
	 * @name offset
	 * @param Map options Optional settings to configure the way the offset is calculated.
	 * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
	 *                            chain will not be broken and the result will be assigned to this object.
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	offset: function(options, returnObject) {
		if (!this[0]) error();
		var x = 0, y = 0, sl = 0, st = 0,
		    elem = this[0], parent = this[0], op, parPos, elemPos = $.css(elem, 'position'),
		    mo = $.browser.mozilla, ie = $.browser.msie, oa = $.browser.opera,
		    sf = $.browser.safari, sf3 = $.browser.safari && parseInt($.browser.version) > 520,
		    absparent = false, relparent = false, 
		    options = $.extend({ margin: true, border: false, padding: false, scroll: true, lite: false, relativeTo: document.body }, options || {});
		
		// Use offsetLite if lite option is true
		if (options.lite) return this.offsetLite(options, returnObject);
		// Get the HTMLElement if relativeTo is a jquery collection
		if (options.relativeTo.jquery) options.relativeTo = options.relativeTo[0];
		
		if (elem.tagName == 'BODY') {
			// Safari 2 is the only one to get offsetLeft and offsetTop properties of the body "correct"
			// Except they all mess up when the body is positioned absolute or relative
			x = elem.offsetLeft;
			y = elem.offsetTop;
			// Mozilla ignores margin and subtracts border from body element
			if (mo) {
				x += num(elem, 'marginLeft') + (num(elem, 'borderLeftWidth')*2);
				y += num(elem, 'marginTop')  + (num(elem, 'borderTopWidth') *2);
			} else
			// Opera ignores margin
			if (oa) {
				x += num(elem, 'marginLeft');
				y += num(elem, 'marginTop');
			} else
			// IE does not add the border in Standards Mode
			if ((ie && jQuery.boxModel)) {
				x += num(elem, 'borderLeftWidth');
				y += num(elem, 'borderTopWidth');
			} else
			// Safari 3 doesn't not include border or margin
			if (sf3) {
				x += num(elem, 'marginLeft') + num(elem, 'borderLeftWidth');
				y += num(elem, 'marginTop')  + num(elem, 'borderTopWidth');
			}
		} else {
			do {
				parPos = $.css(parent, 'position');
			
				x += parent.offsetLeft;
				y += parent.offsetTop;

				// Mozilla and IE do not add the border
				// Mozilla adds the border for table cells
				if ((mo && !parent.tagName.match(/^t[d|h]$/i)) || ie || sf3) {
					// add borders to offset
					x += num(parent, 'borderLeftWidth');
					y += num(parent, 'borderTopWidth');

					// Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent
					if (mo && parPos == 'absolute') absparent = true;
					// IE does not include the border on the body if an element is position static and without an absolute or relative parent
					if (ie && parPos == 'relative') relparent = true;
				}

				op = parent.offsetParent || document.body;
				if (options.scroll || mo) {
					do {
						if (options.scroll) {
							// get scroll offsets
							sl += parent.scrollLeft;
							st += parent.scrollTop;
						}
						
						// Opera sometimes incorrectly reports scroll offset for elements with display set to table-row or inline
						if (oa && ($.css(parent, 'display') || '').match(/table-row|inline/)) {
							sl = sl - ((parent.scrollLeft == parent.offsetLeft) ? parent.scrollLeft : 0);
							st = st - ((parent.scrollTop == parent.offsetTop) ? parent.scrollTop : 0);
						}
				
						// Mozilla does not add the border for a parent that has overflow set to anything but visible
						if (mo && parent != elem && $.css(parent, 'overflow') != 'visible') {
							x += num(parent, 'borderLeftWidth');
							y += num(parent, 'borderTopWidth');
						}
				
						parent = parent.parentNode;
					} while (parent != op);
				}
				parent = op;
				
				// exit the loop if we are at the relativeTo option but not if it is the body or html tag
				if (parent == options.relativeTo && !(parent.tagName == 'BODY' || parent.tagName == 'HTML'))  {
					// Mozilla does not add the border for a parent that has overflow set to anything but visible
					if (mo && parent != elem && $.css(parent, 'overflow') != 'visible') {
						x += num(parent, 'borderLeftWidth');
						y += num(parent, 'borderTopWidth');
					}
					// Safari 2 and opera includes border on positioned parents
					if ( ((sf && !sf3) || oa) && parPos != 'static' ) {
						x -= num(op, 'borderLeftWidth');
						y -= num(op, 'borderTopWidth');
					}
					break;
				}
				if (parent.tagName == 'BODY' || parent.tagName == 'HTML') {
					// Safari 2 and IE Standards Mode doesn't add the body margin for elments positioned with static or relative
					if (((sf && !sf3) || (ie && $.boxModel)) && elemPos != 'absolute' && elemPos != 'fixed') {
						x += num(parent, 'marginLeft');
						y += num(parent, 'marginTop');
					}
					// Safari 3 does not include the border on body
					// Mozilla does not include the border on body if an element isn't positioned absolute and is without an absolute parent
					// IE does not include the border on the body if an element is positioned static and without an absolute or relative parent
					if ( sf3 || (mo && !absparent && elemPos != 'fixed') || 
					     (ie && elemPos == 'static' && !relparent) ) {
						x += num(parent, 'borderLeftWidth');
						y += num(parent, 'borderTopWidth');
					}
					break; // Exit the loop
				}
			} while (parent);
		}

		var returnValue = handleOffsetReturn(elem, options, x, y, sl, st);

		if (returnObject) { $.extend(returnObject, returnValue); return this; }
		else              { return returnValue; }
	},
	
	/**
	 * Gets the location of the element in pixels from the top left corner of the viewport.
	 * This method is much faster than offset but not as accurate when borders and margins are
	 * on the element and/or its parents. This method can be invoked
	 * by setting the lite option to true in the offset method.
	 * The offsetLite method takes an optional map of key value pairs to configure the way
	 * the offset is calculated. Here are the different options.
	 *
	 * (Boolean) margin - Should the margin of the element be included in the calculations? True by default.
	 * (Boolean) border - Should the border of the element be included in the calculations? False by default. 
	 * (Boolean) padding - Should the padding of the element be included in the calcuations? False by default. 
	 * (Boolean) scroll - Sould the scroll offsets of the parent elements be included int he calculations? True by default.
	 *                    When true it adds the total scroll offsets of all parents to the total offset and also adds two
	 *                    properties to the returned object, scrollTop and scrollLeft.
	 * (HTML Element) relativeTo - This should be a parent of the element and should have position (like absolute or relative).
	 *                             It will retreive the offset relative to this parent element. By default it is the body element.
	 *
	 * @name offsetLite
	 * @param Map options Optional settings to configure the way the offset is calculated.
	 * @param Object returnObject An object to store the return value in, so as not to break the chain. If passed in the
	 *                            chain will not be broken and the result will be assigned to this object.
	 * @type Object
	 * @cat Plugins/Dimensions
	 */
	offsetLite: function(options, returnObject) {
		if (!this[0]) error();
		var x = 0, y = 0, sl = 0, st = 0, parent = this[0], offsetParent, 
		    options = $.extend({ margin: true, border: false, padding: false, scroll: true, relativeTo: document.body }, options || {});
				
		// Get the HTMLElement if relativeTo is a jquery collection
		if (options.relativeTo.jquery) options.relativeTo = options.relativeTo[0];
		
		do {
			x += parent.offsetLeft;
			y += parent.offsetTop;

			offsetParent = parent.offsetParent || document.body;
			if (options.scroll) {
				// get scroll offsets
				do {
					sl += parent.scrollLeft;
					st += parent.scrollTop;
					parent = parent.parentNode;
				} while(parent != offsetParent);
			}
			parent = offsetParent;
		} while (parent && parent.tagName != 'BODY' && parent.tagName != 'HTML' && parent != options.relativeTo);

		var returnValue = handleOffsetReturn(this[0], options, x, y, sl, st);

		if (returnObject) { $.extend(returnObject, returnValue); return this; }
		else              { return returnValue; }
	},
	
	/**
	 * Returns a jQuery collection with the positioned parent of 
	 * the first matched element. This is the first parent of 
	 * the element that has position (as in relative or absolute).
	 *
	 * @name offsetParent
	 * @type jQuery
	 * @cat Plugins/Dimensions
	 */
	offsetParent: function() {
		if (!this[0]) error();
		var offsetParent = this[0].offsetParent;
		while ( offsetParent && (offsetParent.tagName != 'BODY' && $.css(offsetParent, 'position') == 'static') )
			offsetParent = offsetParent.offsetParent;
		return $(offsetParent);
	}
});

/**
 * Throws an error message when no elements are in the jQuery collection
 * @private
 */
var error = function() {
	throw "Dimensions: jQuery collection is empty";
};

/**
 * Handles converting a CSS Style into an Integer.
 * @private
 */
var num = function(el, prop) {
	return parseInt($.css(el.jquery?el[0]:el,prop))||0;
};

/**
 * Handles the return value of the offset and offsetLite methods.
 * @private
 */
var handleOffsetReturn = function(elem, options, x, y, sl, st) {
	if ( !options.margin ) {
		x -= num(elem, 'marginLeft');
		y -= num(elem, 'marginTop');
	}

	// Safari and Opera do not add the border for the element
	if ( options.border && (($.browser.safari && parseInt($.browser.version) < 520) || $.browser.opera) ) {
		x += num(elem, 'borderLeftWidth');
		y += num(elem, 'borderTopWidth');
	} else if ( !options.border && !(($.browser.safari && parseInt($.browser.version) < 520) || $.browser.opera) ) {
		x -= num(elem, 'borderLeftWidth');
		y -= num(elem, 'borderTopWidth');
	}

	if ( options.padding ) {
		x += num(elem, 'paddingLeft');
		y += num(elem, 'paddingTop');
	}
	
	// do not include scroll offset on the element ... opera sometimes reports scroll offset as actual offset
	if ( options.scroll && (!$.browser.opera || elem.offsetLeft != elem.scrollLeft && elem.offsetTop != elem.scrollLeft) ) {
		sl -= elem.scrollLeft;
		st -= elem.scrollTop;
	}

	return options.scroll ? { top: y - st, left: x - sl, scrollTop:  st, scrollLeft: sl }
	                      : { top: y, left: x };
};

/**
 * Gets the width of the OS scrollbar
 * @private
 */
var scrollbarWidth = 0;
var getScrollbarWidth = function() {
	if (!scrollbarWidth) {
		var testEl = $('<div>')
				.css({
					width: 100,
					height: 100,
					overflow: 'auto',
					position: 'absolute',
					top: -1000,
					left: -1000
				})
				.appendTo('body');
		scrollbarWidth = 100 - testEl
			.append('<div>')
			.find('div')
				.css({
					width: '100%',
					height: 200
				})
				.width();
		testEl.remove();
	}
	return scrollbarWidth;
};

})(jQuery);
/*
 ### jQuery Multiple File Upload Plugin ###
 By Diego A., http://www.fyneworks.com, diego@fyneworks.com
 
 Website:
  http://www.fyneworks.com/jquery/multiple-file-upload/
 Project Page:
  http://jquery.com/plugins/project/MultiFile/
 Forums:
  http://www.nabble.com/jQuery-Multiple-File-Upload-f20931.html
 Blog:
	 http://fyneworks.blogspot.com/2007/04/jquery-multiple-file-upload-plugin-v11.html
  (old) http://fyneworks.blogspot.com/2007/04/multiple-file-upload-plugin-for-jquery.html
 
 12-April-2007: v1.1
                Added events and file extension validation
                See website for details.
 
 06-June-2007: v1.2
                Now works in Opera.
 
 12-June-2007: v1.21
                Preserves name of file input so all current server-side
																functions don't need to be changed on new installations.
 
 24-June-2007: v1.22
                Now works perfectly in Opera, thanks to Adrian Wróbel <adrian [dot] wrobel [at] gmail.com>
*/

/*# AVOID COLLISIONS #*/
if(jQuery) (function($){
/*# AVOID COLLISIONS #*/

	// Fix for Opera: 6-June-2007
	// Stop confusion between null, 'null' and 'undefined'
	function IsNull(i){
		return (i==null || i=='null' || i=='' || i=='undefined');
	};
	
	// extend jQuery - $.MultiFile hook
	$.extend($, {
		MultiFile: function( o /* Object */ ){
			return $("INPUT[@type='file'].multi").MultiFile(o);
		}
	});
	
	// extend jQuery function library
	$.extend($.fn, {
			
			// MultiFile function
			MultiFile: function( o /* Object */ ){
				if(this._MultiFile){ return $(this); }
				this._MultiFile = true;
				
				// DEBUGGING: disable plugin
				//return false;
				
				// Bind to each element in current jQuery object
				return $(this).each(function(i){
							// Remember our ancestors...
							var d = this;
							var x = $(d);
       
       // Copy parent attributes - Thanks to Jonas Wagner
							// we will use this one to create new input elements
       var xclone = x.clone();
							
							//#########################################
							// Find basic configuration in class string
							// debug???
							d.debug = (d.className.indexOf('debug')>0);
							// limit number of files that can be selected?
							if(IsNull(d.max)){
								d.max = x.attr('maxlength');
								if(IsNull(d.max)){
									d.max = ((d.className.match(/\b((max|limit)\-[0-9]+)\b/gi) || [''])[0]);
									if(IsNull(d.max)){
										d.max = -1;
									}else{
										d.max = d.max.match(/[0-9]+/gi)[0];
									}
								}
							}
							d.max = new Number(d.max);
							// limit extensions?
							if(!d.accept){
								d.accept = (d.className.match(/\b(accept\-[\w\|]+)\b/gi)) || '';
								d.accept = new String(d.accept).replace(/^(accept|ext)\-/i,'');
							}
							//#########################################
							
							
							// Attach a bunch of events, jQuery style ;-)
							$.each("on,after".split(","), function(i,o){
								$.each("FileSelect,FileRemove,FileAppend".split(","), function(j,event){
									d[o+event] = function(e, v, m){ // default functions do absolutelly nothing...
										// if(d.debug) alert(''+o+event+'' +'\nElement:' +e.name+ '\nValue: ' +v+ '\nMaster: ' +m.name+ '');
									};
								});
							});
							// Setup a global event handler
							d.trigger = function(event, e){
									var f = d[event];
									if(f){
										var v = $(this).attr('value');
										var r = f(e, v, d);
										if(r!=null) return r;
									}
									return true;
							};
							
							
							// Initialize options
							if( typeof o == 'number' ){ o = {max:o}; };
							$.extend(d, d.data || {}, o);
							
							// Default properties - INTERNAL USE ONLY
							$.extend(d, {
								STRING: d.STRING || {}, // used to hold string constants
								n: 0, // How many elements are currently selected?
								k: 'multi', // Instance Key?
								f: function(z){ return d.k+'_'+String(i)+'_'+String(z); }
							});
							
							// Visible text strings...
							// $file = file name (with path), $ext = file extension
							d.STRING = $.extend({
								remove:'remove',
								denied:'You cannot select a $ext file.\nTry again...',
								selected:'File selected: $file'
							}, d.STRING);
							
							
							// Setup dynamic regular expression for extension validation
							// - thanks to John-Paul Bader: http://smyck.de/2006/08/11/javascript-dynamic-regular-expresions/
							if(String(d.accept).length>1){
								d.rxAccept = new RegExp('\\.('+(d.accept?d.accept:'')+')$','gi');
							};
							
							// Create wrapper to hold our file list
							d.w = d.k+'multi'+'_'+i; // Wrapper ID?
							x.wrap('<div id="'+d.w+'"></div>');
							
							// Bind a new element
							d.add = function( e, ii ){
								
								// Keep track of how many elements have been displayed
								d.n++;
								
								// Add reference to master element
								e.d = d;
								
								// Define element's ID and name (upload components need this!)
								e.i = ii;//d.I;
								e.id = d.f(e.i);
								e.name = (e.name || x.attr('name') || 'file') + (e.i>0?e.i:''); // same name as master element
								
								// If we've reached maximum number, disable input e
								if( (d.max != -1) && ((d.n-1) > (d.max)) ){ // d.n Starts at 1, so subtract 1 to find true count
									e.disabled = true;
								};
								
								// Remember most recent e
								d.current = e;
								
								/// now let's use jQuery
								e = $(e);
								
								// Triggered when a file is selected
								e.change(function(){
										
										//# Trigger Event! onFileSelect
										if(!d.trigger('onFileSelect', this, d)) return false;
										//# End Event!
										
										// check extension
										if(d.accept){
											var v = String(e.attr('value'));
											if(!v.match(d.rxAccept)){
												// Clear element value
												e.val('').attr('value', '');
												e.get(0).value = '';
												
												// OPERA BUG FIX - 2007-06-24
												// Thanks to Adrian Wróbel <adrian [dot] wrobel [at] gmail.com>
 											// we add new input element and remove present one for browsers that can't clear value of input element
												//var f = $('<input name="'+(x.attr('name') || '')+'" type="file"/>');
												var f = xclone.clone();// Copy parent attributes - Thanks to Jonas Wagner
												
												d.n--;
												d.add(f.get(0), this.i);
												e.parent().prepend(f);
												e.remove();
												
												// Show error message
												// TO-DO: Some people have suggested alternative methods for displaying this message
												// such as inline HTML, lightbox, etc... maybe integrate with blockUI plugin?
												alert(d.STRING.denied.replace('$ext', String(v.match(/\.\w{1,4}$/gi))));
												
												return false;
											}
										};
										
										// Hide this element: display:none is evil!
										//this.style.display = 'block';
										this.style.position = 'absolute';
										this.style.left = '-1000px';
          
										// Create a new file input element
										//var f = $('<input name="'+(x.attr('name') || '')+'" type="file"/>');
          var f = xclone.clone();// Copy parent attributes - Thanks to Jonas Wagner
										
										// Add it to the form
										$(this).parent().prepend(f);
										
										// Update list
										d.list( this );
										
										// Bind functionality
										d.add( f.get(0), this.i+1 );
										
										//# Trigger Event! afterFileSelect
										if(!d.trigger('afterFileSelect', this, d)) return false;
										//# End Event!
										
								});
							
							};
							// Bind a new element
						
							// Add a new file to the list
							d.list = function( y ){
								
								//# Trigger Event! onFileAppend
								if(!d.trigger('onFileAppend', y, d)) return false;
								//# End Event!
								
								// Insert HTML
								var
									t = $('#'+d.w),
									r = $('<div></div>'),
									v = $(y).attr('value')+'',
									a = $('<span class="file" title="'+d.STRING.selected.replace('$file', v)+'">'+v.match(/[^\/\\]+$/gi)[0]+'</span>'),
									b = $('<a href="#'+d.w+'">'+d.STRING.remove+'</a>');
								t.append(r);
								r.append('[',b,']&nbsp;',a);//.prepend(y.i+': ');
								b.click(function(){
									
										//# Trigger Event! onFileRemove
										if(!d.trigger('onFileRemove', y, d)) return false;
										//# End Event!
										
										d.n--;
										d.current.disabled = false;
										$('#'+d.f(y.i)).remove();
										$(this).parent().remove();
										
										//# Trigger Event! afterFileRemove
										if(!d.trigger('afterFileRemove', y, d)) return false;
										//# End Event!
										
										return false;
								});
								
								//# Trigger Event! afterFileAppend
								if(!d.trigger('afterFileAppend', y, d)) return false;
								//# End Event!
								
							};
							
							// Bind first file element
							if(!d.ft){ d.add(d, 0); d.ft = true; }
							d.I++;
							d.n++;
							
				});
				// each element
			
			}
			// MultiFile function
	
	});
	// extend jQuery function library



/*
 ### Default implementation ###
 The plugin will attach itself to file inputs
 with the class 'multi' when the page loads
	
	Use the jQuery start plugin to 
*/
if($.start){ $.start($.MultiFile) }
else $(function(){ $.MultiFile() });



/*# AVOID COLLISIONS #*/
})(jQuery);
/*# AVOID COLLISIONS #*/

/* Copyright (c) 2006 Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
 * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
 * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
 *
 * $LastChangedDate: 2007-12-20 09:02:08 -0600 (Thu, 20 Dec 2007) $
 * $Rev: 4265 $
 *
 * Version: 3.0
 * 
 * Requires: $ 1.2.2+
 */

(function($) {

$.event.special.mousewheel = {
	setup: function() {
		var handler = $.event.special.mousewheel.handler;
		
		// Fix pageX, pageY, clientX and clientY for mozilla
		if ( $.browser.mozilla )
			$(this).bind('mousemove.mousewheel', function(event) {
				$.data(this, 'mwcursorposdata', {
					pageX: event.pageX,
					pageY: event.pageY,
					clientX: event.clientX,
					clientY: event.clientY
				});
			});
	
		if ( this.addEventListener )
			this.addEventListener( ($.browser.mozilla ? 'DOMMouseScroll' : 'mousewheel'), handler, false);
		else
			this.onmousewheel = handler;
	},
	
	teardown: function() {
		var handler = $.event.special.mousewheel.handler;
		
		$(this).unbind('mousemove.mousewheel');
		
		if ( this.removeEventListener )
			this.removeEventListener( ($.browser.mozilla ? 'DOMMouseScroll' : 'mousewheel'), handler, false);
		else
			this.onmousewheel = function(){};
		
		$.removeData(this, 'mwcursorposdata');
	},
	
	handler: function(event) {
		var args = Array.prototype.slice.call( arguments, 1 );
		
		event = $.event.fix(event || window.event);
		// Get correct pageX, pageY, clientX and clientY for mozilla
		$.extend( event, $.data(this, 'mwcursorposdata') || {} );
		var delta = 0, returnValue = true;
		
		if ( event.wheelDelta ) delta = event.wheelDelta/120;
		if ( event.detail     ) delta = -event.detail/3;
		if ( $.browser.opera  ) delta = -event.wheelDelta;
		
		event.data  = event.data || {};
		event.type  = "mousewheel";
		
		// Add delta to the front of the arguments
		args.unshift(delta);
		// Add event to the front of the arguments
		args.unshift(event);

		return $.event.handle.apply(this, args);
	}
};

$.fn.extend({
	mousewheel: function(fn) {
		return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
	},
	
	unmousewheel: function(fn) {
		return this.unbind("mousewheel", fn);
	}
});

})(jQuery);
// Copyright 2006 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.


// Known Issues:
//
// * Patterns are not implemented.
// * Radial gradient are not implemented. The VML version of these look very
//   different from the canvas one.
// * Clipping paths are not implemented.
// * Coordsize. The width and height attribute have higher priority than the
//   width and height style values which isn't correct.
// * Painting mode isn't implemented.
// * Canvas width/height should is using content-box by default. IE in
//   Quirks mode will draw the canvas using border-box. Either change your
//   doctype to HTML5
//   (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
//   or use Box Sizing Behavior from WebFX
//   (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
// * Optimize. There is always room for speed improvements.

// only add this code if we do not already have a canvas implementation
if (!window.CanvasRenderingContext2D) {

(function () {

  // alias some functions to make (compiled) code shorter
  var m = Math;
  var mr = m.round;
  var ms = m.sin;
  var mc = m.cos;

  // this is used for sub pixel precision
  var Z = 10;
  var Z2 = Z / 2;

  var G_vmlCanvasManager_ = {
    init: function (opt_doc) {
      var doc = opt_doc || document;
      if (/MSIE/.test(navigator.userAgent) && !window.opera) {
        var self = this;
        doc.attachEvent("onreadystatechange", function () {
          self.init_(doc);
        });
      }
    },

    init_: function (doc) {
      if (doc.readyState == "complete") {
        // create xmlns
        if (!doc.namespaces["g_vml_"]) {
          doc.namespaces.add("g_vml_", "urn:schemas-microsoft-com:vml");
        }

        // setup default css
        var ss = doc.createStyleSheet();
        ss.cssText = "canvas{display:inline-block;overflow:hidden;" +
            // default size is 300x150 in Gecko and Opera
            "text-align:left;width:300px;height:150px}" +
            "g_vml_\\:*{behavior:url(#default#VML)}";

        // find all canvas elements
        var els = doc.getElementsByTagName("canvas");
        for (var i = 0; i < els.length; i++) {
          if (!els[i].getContext) {
            this.initElement(els[i]);
          }
        }
      }
    },

    fixElement_: function (el) {
      // in IE before version 5.5 we would need to add HTML: to the tag name
      // but we do not care about IE before version 6
      var outerHTML = el.outerHTML;

      var newEl = el.ownerDocument.createElement(outerHTML);
      // if the tag is still open IE has created the children as siblings and
      // it has also created a tag with the name "/FOO"
      if (outerHTML.slice(-2) != "/>") {
        var tagName = "/" + el.tagName;
        var ns;
        // remove content
        while ((ns = el.nextSibling) && ns.tagName != tagName) {
          ns.removeNode();
        }
        // remove the incorrect closing tag
        if (ns) {
          ns.removeNode();
        }
      }
      el.parentNode.replaceChild(newEl, el);
      return newEl;
    },

    /**
     * Public initializes a canvas element so that it can be used as canvas
     * element from now on. This is called automatically before the page is
     * loaded but if you are creating elements using createElement you need to
     * make sure this is called on the element.
     * @param {HTMLElement} el The canvas element to initialize.
     * @return {HTMLElement} the element that was created.
     */
    initElement: function (el) {
      el = this.fixElement_(el);
      el.getContext = function () {
        if (this.context_) {
          return this.context_;
        }
        return this.context_ = new CanvasRenderingContext2D_(this);
      };

      // do not use inline function because that will leak memory
      el.attachEvent('onpropertychange', onPropertyChange);
      el.attachEvent('onresize', onResize);

      var attrs = el.attributes;
      if (attrs.width && attrs.width.specified) {
        // TODO: use runtimeStyle and coordsize
        // el.getContext().setWidth_(attrs.width.nodeValue);
        el.style.width = attrs.width.nodeValue + "px";
      } else {
        el.width = el.clientWidth;
      }
      if (attrs.height && attrs.height.specified) {
        // TODO: use runtimeStyle and coordsize
        // el.getContext().setHeight_(attrs.height.nodeValue);
        el.style.height = attrs.height.nodeValue + "px";
      } else {
        el.height = el.clientHeight;
      }
      //el.getContext().setCoordsize_()
      return el;
    }
  };

  function onPropertyChange(e) {
    var el = e.srcElement;

    switch (e.propertyName) {
      case 'width':
        el.style.width = el.attributes.width.nodeValue + "px";
        el.getContext().clearRect();
        break;
      case 'height':
        el.style.height = el.attributes.height.nodeValue + "px";
        el.getContext().clearRect();
        break;
    }
  }

  function onResize(e) {
    var el = e.srcElement;
    if (el.firstChild) {
      el.firstChild.style.width =  el.clientWidth + 'px';
      el.firstChild.style.height = el.clientHeight + 'px';
    }
  }

  G_vmlCanvasManager_.init();

  // precompute "00" to "FF"
  var dec2hex = [];
  for (var i = 0; i < 16; i++) {
    for (var j = 0; j < 16; j++) {
      dec2hex[i * 16 + j] = i.toString(16) + j.toString(16);
    }
  }

  function createMatrixIdentity() {
    return [
      [1, 0, 0],
      [0, 1, 0],
      [0, 0, 1]
    ];
  }

  function matrixMultiply(m1, m2) {
    var result = createMatrixIdentity();

    for (var x = 0; x < 3; x++) {
      for (var y = 0; y < 3; y++) {
        var sum = 0;

        for (var z = 0; z < 3; z++) {
          sum += m1[x][z] * m2[z][y];
        }

        result[x][y] = sum;
      }
    }
    return result;
  }

  function copyState(o1, o2) {
    o2.fillStyle     = o1.fillStyle;
    o2.lineCap       = o1.lineCap;
    o2.lineJoin      = o1.lineJoin;
    o2.lineWidth     = o1.lineWidth;
    o2.miterLimit    = o1.miterLimit;
    o2.shadowBlur    = o1.shadowBlur;
    o2.shadowColor   = o1.shadowColor;
    o2.shadowOffsetX = o1.shadowOffsetX;
    o2.shadowOffsetY = o1.shadowOffsetY;
    o2.strokeStyle   = o1.strokeStyle;
    o2.arcScaleX_    = o1.arcScaleX_;
    o2.arcScaleY_    = o1.arcScaleY_;
  }

  function processStyle(styleString) {
    var str, alpha = 1;

    styleString = String(styleString);
    if (styleString.substring(0, 3) == "rgb") {
      var start = styleString.indexOf("(", 3);
      var end = styleString.indexOf(")", start + 1);
      var guts = styleString.substring(start + 1, end).split(",");

      str = "#";
      for (var i = 0; i < 3; i++) {
        str += dec2hex[Number(guts[i])];
      }

      if ((guts.length == 4) && (styleString.substr(3, 1) == "a")) {
        alpha = guts[3];
      }
    } else {
      str = styleString;
    }

    return [str, alpha];
  }

  function processLineCap(lineCap) {
    switch (lineCap) {
      case "butt":
        return "flat";
      case "round":
        return "round";
      case "square":
      default:
        return "square";
    }
  }

  /**
   * This class implements CanvasRenderingContext2D interface as described by
   * the WHATWG.
   * @param {HTMLElement} surfaceElement The element that the 2D context should
   * be associated with
   */
   function CanvasRenderingContext2D_(surfaceElement) {
    this.m_ = createMatrixIdentity();

    this.mStack_ = [];
    this.aStack_ = [];
    this.currentPath_ = [];

    // Canvas context properties
    this.strokeStyle = "#000";
    this.fillStyle = "#000";

    this.lineWidth = 1;
    this.lineJoin = "miter";
    this.lineCap = "butt";
    this.miterLimit = Z * 1;
    this.globalAlpha = 1;
    this.canvas = surfaceElement;

    var el = surfaceElement.ownerDocument.createElement('div');
    el.style.width =  surfaceElement.clientWidth + 'px';
    el.style.height = surfaceElement.clientHeight + 'px';
    el.style.overflow = 'hidden';
    el.style.position = 'absolute';
    surfaceElement.appendChild(el);

    this.element_ = el;
    this.arcScaleX_ = 1;
    this.arcScaleY_ = 1;
  };

  var contextPrototype = CanvasRenderingContext2D_.prototype;
  contextPrototype.clearRect = function() {
    this.element_.innerHTML = "";
    this.currentPath_ = [];
  };

  contextPrototype.beginPath = function() {
    // TODO: Branch current matrix so that save/restore has no effect
    //       as per safari docs.

    this.currentPath_ = [];
  };

  contextPrototype.moveTo = function(aX, aY) {
    this.currentPath_.push({type: "moveTo", x: aX, y: aY});
    this.currentX_ = aX;
    this.currentY_ = aY;
  };

  contextPrototype.lineTo = function(aX, aY) {
    this.currentPath_.push({type: "lineTo", x: aX, y: aY});
    this.currentX_ = aX;
    this.currentY_ = aY;
  };

  contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,
                                            aCP2x, aCP2y,
                                            aX, aY) {
    this.currentPath_.push({type: "bezierCurveTo",
                           cp1x: aCP1x,
                           cp1y: aCP1y,
                           cp2x: aCP2x,
                           cp2y: aCP2y,
                           x: aX,
                           y: aY});
    this.currentX_ = aX;
    this.currentY_ = aY;
  };

  contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {
    // the following is lifted almost directly from
    // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes
    var cp1x = this.currentX_ + 2.0 / 3.0 * (aCPx - this.currentX_);
    var cp1y = this.currentY_ + 2.0 / 3.0 * (aCPy - this.currentY_);
    var cp2x = cp1x + (aX - this.currentX_) / 3.0;
    var cp2y = cp1y + (aY - this.currentY_) / 3.0;
    this.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, aX, aY);
  };

  contextPrototype.arc = function(aX, aY, aRadius,
                                  aStartAngle, aEndAngle, aClockwise) {
    aRadius *= Z;
    var arcType = aClockwise ? "at" : "wa";

    var xStart = aX + (mc(aStartAngle) * aRadius) - Z2;
    var yStart = aY + (ms(aStartAngle) * aRadius) - Z2;

    var xEnd = aX + (mc(aEndAngle) * aRadius) - Z2;
    var yEnd = aY + (ms(aEndAngle) * aRadius) - Z2;

    // IE won't render arches drawn counter clockwise if xStart == xEnd.
    if (xStart == xEnd && !aClockwise) {
      xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something
                       // that can be represented in binary
    }

    this.currentPath_.push({type: arcType,
                           x: aX,
                           y: aY,
                           radius: aRadius,
                           xStart: xStart,
                           yStart: yStart,
                           xEnd: xEnd,
                           yEnd: yEnd});

  };

  contextPrototype.rect = function(aX, aY, aWidth, aHeight) {
    this.moveTo(aX, aY);
    this.lineTo(aX + aWidth, aY);
    this.lineTo(aX + aWidth, aY + aHeight);
    this.lineTo(aX, aY + aHeight);
    this.closePath();
  };

  contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {
    // Will destroy any existing path (same as FF behaviour)
    this.beginPath();
    this.moveTo(aX, aY);
    this.lineTo(aX + aWidth, aY);
    this.lineTo(aX + aWidth, aY + aHeight);
    this.lineTo(aX, aY + aHeight);
    this.closePath();
    this.stroke();
  };

  contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {
    // Will destroy any existing path (same as FF behaviour)
    this.beginPath();
    this.moveTo(aX, aY);
    this.lineTo(aX + aWidth, aY);
    this.lineTo(aX + aWidth, aY + aHeight);
    this.lineTo(aX, aY + aHeight);
    this.closePath();
    this.fill();
  };

  contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {
    var gradient = new CanvasGradient_("gradient");
    return gradient;
  };

  contextPrototype.createRadialGradient = function(aX0, aY0,
                                                   aR0, aX1,
                                                   aY1, aR1) {
    var gradient = new CanvasGradient_("gradientradial");
    gradient.radius1_ = aR0;
    gradient.radius2_ = aR1;
    gradient.focus_.x = aX0;
    gradient.focus_.y = aY0;
    return gradient;
  };

  contextPrototype.drawImage = function (image, var_args) {
    var dx, dy, dw, dh, sx, sy, sw, sh;

    // to find the original width we overide the width and height
    var oldRuntimeWidth = image.runtimeStyle.width;
    var oldRuntimeHeight = image.runtimeStyle.height;
    image.runtimeStyle.width = 'auto';
    image.runtimeStyle.height = 'auto';

    // get the original size
    var w = image.width;
    var h = image.height;

    // and remove overides
    image.runtimeStyle.width = oldRuntimeWidth;
    image.runtimeStyle.height = oldRuntimeHeight;

    if (arguments.length == 3) {
      dx = arguments[1];
      dy = arguments[2];
      sx = sy = 0;
      sw = dw = w;
      sh = dh = h;
    } else if (arguments.length == 5) {
      dx = arguments[1];
      dy = arguments[2];
      dw = arguments[3];
      dh = arguments[4];
      sx = sy = 0;
      sw = w;
      sh = h;
    } else if (arguments.length == 9) {
      sx = arguments[1];
      sy = arguments[2];
      sw = arguments[3];
      sh = arguments[4];
      dx = arguments[5];
      dy = arguments[6];
      dw = arguments[7];
      dh = arguments[8];
    } else {
      throw "Invalid number of arguments";
    }

    var d = this.getCoords_(dx, dy);

    var w2 = sw / 2;
    var h2 = sh / 2;

    var vmlStr = [];

    var W = 10;
    var H = 10;

    // For some reason that I've now forgotten, using divs didn't work
    vmlStr.push(' <g_vml_:group',
                ' coordsize="', Z * W, ',', Z * H, '"',
                ' coordorigin="0,0"' ,
                ' style="width:', W, ';height:', H, ';position:absolute;');

    // If filters are necessary (rotation exists), create them
    // filters are bog-slow, so only create them if abbsolutely necessary
    // The following check doesn't account for skews (which don't exist
    // in the canvas spec (yet) anyway.

    if (this.m_[0][0] != 1 || this.m_[0][1]) {
      var filter = [];

      // Note the 12/21 reversal
      filter.push("M11='", this.m_[0][0], "',",
                  "M12='", this.m_[1][0], "',",
                  "M21='", this.m_[0][1], "',",
                  "M22='", this.m_[1][1], "',",
                  "Dx='", mr(d.x / Z), "',",
                  "Dy='", mr(d.y / Z), "'");

      // Bounding box calculation (need to minimize displayed area so that
      // filters don't waste time on unused pixels.
      var max = d;
      var c2 = this.getCoords_(dx + dw, dy);
      var c3 = this.getCoords_(dx, dy + dh);
      var c4 = this.getCoords_(dx + dw, dy + dh);

      max.x = Math.max(max.x, c2.x, c3.x, c4.x);
      max.y = Math.max(max.y, c2.y, c3.y, c4.y);

      vmlStr.push("padding:0 ", mr(max.x / Z), "px ", mr(max.y / Z),
                  "px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",
                  filter.join(""), ", sizingmethod='clip');");
    } else {
      vmlStr.push("top:", mr(d.y / Z), "px;left:", mr(d.x / Z), "px;");
    }

    vmlStr.push(' ">' ,
                '<g_vml_:image src="', image.src, '"',
                ' style="width:', Z * dw, ';',
                ' height:', Z * dh, ';"',
                ' cropleft="', sx / w, '"',
                ' croptop="', sy / h, '"',
                ' cropright="', (w - sx - sw) / w, '"',
                ' cropbottom="', (h - sy - sh) / h, '"',
                ' />',
                '</g_vml_:group>');

    this.element_.insertAdjacentHTML("BeforeEnd",
                                    vmlStr.join(""));
  };

  contextPrototype.stroke = function(aFill) {
    var lineStr = [];
    var lineOpen = false;
    var a = processStyle(aFill ? this.fillStyle : this.strokeStyle);
    var color = a[0];
    var opacity = a[1] * this.globalAlpha;

    var W = 10;
    var H = 10;

    lineStr.push('<g_vml_:shape',
                 ' fillcolor="', color, '"',
                 ' filled="', Boolean(aFill), '"',
                 ' style="position:absolute;width:', W, ';height:', H, ';"',
                 ' coordorigin="0 0" coordsize="', Z * W, ' ', Z * H, '"',
                 ' stroked="', !aFill, '"',
                 ' strokeweight="', this.lineWidth, '"',
                 ' strokecolor="', color, '"',
                 ' path="');

    var newSeq = false;
    var min = {x: null, y: null};
    var max = {x: null, y: null};

    for (var i = 0; i < this.currentPath_.length; i++) {
      var p = this.currentPath_[i];

      if (p.type == "moveTo") {
        lineStr.push(" m ");
        var c = this.getCoords_(p.x, p.y);
        lineStr.push(mr(c.x), ",", mr(c.y));
      } else if (p.type == "lineTo") {
        lineStr.push(" l ");
        var c = this.getCoords_(p.x, p.y);
        lineStr.push(mr(c.x), ",", mr(c.y));
      } else if (p.type == "close") {
        lineStr.push(" x ");
      } else if (p.type == "bezierCurveTo") {
        lineStr.push(" c ");
        var c = this.getCoords_(p.x, p.y);
        var c1 = this.getCoords_(p.cp1x, p.cp1y);
        var c2 = this.getCoords_(p.cp2x, p.cp2y);
        lineStr.push(mr(c1.x), ",", mr(c1.y), ",",
                     mr(c2.x), ",", mr(c2.y), ",",
                     mr(c.x), ",", mr(c.y));
      } else if (p.type == "at" || p.type == "wa") {
        lineStr.push(" ", p.type, " ");
        var c  = this.getCoords_(p.x, p.y);
        var cStart = this.getCoords_(p.xStart, p.yStart);
        var cEnd = this.getCoords_(p.xEnd, p.yEnd);

        lineStr.push(mr(c.x - this.arcScaleX_ * p.radius), ",",
                     mr(c.y - this.arcScaleY_ * p.radius), " ",
                     mr(c.x + this.arcScaleX_ * p.radius), ",",
                     mr(c.y + this.arcScaleY_ * p.radius), " ",
                     mr(cStart.x), ",", mr(cStart.y), " ",
                     mr(cEnd.x), ",", mr(cEnd.y));
      }


      // TODO: Following is broken for curves due to
      //       move to proper paths.

      // Figure out dimensions so we can do gradient fills
      // properly
      if(c) {
        if (min.x == null || c.x < min.x) {
          min.x = c.x;
        }
        if (max.x == null || c.x > max.x) {
          max.x = c.x;
        }
        if (min.y == null || c.y < min.y) {
          min.y = c.y;
        }
        if (max.y == null || c.y > max.y) {
          max.y = c.y;
        }
      }
    }
    lineStr.push(' ">');

    if (typeof this.fillStyle == "object") {
      var focus = {x: "50%", y: "50%"};
      var width = (max.x - min.x);
      var height = (max.y - min.y);
      var dimension = (width > height) ? width : height;

      focus.x = mr((this.fillStyle.focus_.x / width) * 100 + 50) + "%";
      focus.y = mr((this.fillStyle.focus_.y / height) * 100 + 50) + "%";

      var colors = [];

      // inside radius (%)
      if (this.fillStyle.type_ == "gradientradial") {
        var inside = (this.fillStyle.radius1_ / dimension * 100);

        // percentage that outside radius exceeds inside radius
        var expansion = (this.fillStyle.radius2_ / dimension * 100) - inside;
      } else {
        var inside = 0;
        var expansion = 100;
      }

      var insidecolor = {offset: null, color: null};
      var outsidecolor = {offset: null, color: null};

      // We need to sort 'colors' by percentage, from 0 > 100 otherwise ie
      // won't interpret it correctly
      this.fillStyle.colors_.sort(function (cs1, cs2) {
        return cs1.offset - cs2.offset;
      });

      for (var i = 0; i < this.fillStyle.colors_.length; i++) {
        var fs = this.fillStyle.colors_[i];

        colors.push( (fs.offset * expansion) + inside, "% ", fs.color, ",");

        if (fs.offset > insidecolor.offset || insidecolor.offset == null) {
          insidecolor.offset = fs.offset;
          insidecolor.color = fs.color;
        }

        if (fs.offset < outsidecolor.offset || outsidecolor.offset == null) {
          outsidecolor.offset = fs.offset;
          outsidecolor.color = fs.color;
        }
      }
      colors.pop();

      lineStr.push('<g_vml_:fill',
                   ' color="', outsidecolor.color, '"',
                   ' color2="', insidecolor.color, '"',
                   ' type="', this.fillStyle.type_, '"',
                   ' focusposition="', focus.x, ', ', focus.y, '"',
                   ' colors="', colors.join(""), '"',
                   ' opacity="', opacity, '" />');
    } else if (aFill) {
      lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity, '" />');
    } else {
      lineStr.push(
        '<g_vml_:stroke',
        ' opacity="', opacity,'"',
        ' joinstyle="', this.lineJoin, '"',
        ' miterlimit="', this.miterLimit, '"',
        ' endcap="', processLineCap(this.lineCap) ,'"',
        ' weight="', this.lineWidth, 'px"',
        ' color="', color,'" />'
      );
    }

    lineStr.push("</g_vml_:shape>");

    this.element_.insertAdjacentHTML("beforeEnd", lineStr.join(""));

    //this.currentPath_ = [];
  };

  contextPrototype.fill = function() {
    this.stroke(true);
  };

  contextPrototype.closePath = function() {
    this.currentPath_.push({type: "close"});
  };

  /**
   * @private
   */
  contextPrototype.getCoords_ = function(aX, aY) {
    return {
      x: Z * (aX * this.m_[0][0] + aY * this.m_[1][0] + this.m_[2][0]) - Z2,
      y: Z * (aX * this.m_[0][1] + aY * this.m_[1][1] + this.m_[2][1]) - Z2
    }
  };

  contextPrototype.save = function() {
    var o = {};
    copyState(this, o);
    this.aStack_.push(o);
    this.mStack_.push(this.m_);
    this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);
  };

  contextPrototype.restore = function() {
    copyState(this.aStack_.pop(), this);
    this.m_ = this.mStack_.pop();
  };

  contextPrototype.translate = function(aX, aY) {
    var m1 = [
      [1,  0,  0],
      [0,  1,  0],
      [aX, aY, 1]
    ];

    this.m_ = matrixMultiply(m1, this.m_);
  };

  contextPrototype.rotate = function(aRot) {
    var c = mc(aRot);
    var s = ms(aRot);

    var m1 = [
      [c,  s, 0],
      [-s, c, 0],
      [0,  0, 1]
    ];

    this.m_ = matrixMultiply(m1, this.m_);
  };

  contextPrototype.scale = function(aX, aY) {
    this.arcScaleX_ *= aX;
    this.arcScaleY_ *= aY;
    var m1 = [
      [aX, 0,  0],
      [0,  aY, 0],
      [0,  0,  1]
    ];

    this.m_ = matrixMultiply(m1, this.m_);
  };

  /******** STUBS ********/
  contextPrototype.clip = function() {
    // TODO: Implement
  };

  contextPrototype.arcTo = function() {
    // TODO: Implement
  };

  contextPrototype.createPattern = function() {
    return new CanvasPattern_;
  };

  // Gradient / Pattern Stubs
  function CanvasGradient_(aType) {
    this.type_ = aType;
    this.radius1_ = 0;
    this.radius2_ = 0;
    this.colors_ = [];
    this.focus_ = {x: 0, y: 0};
  }

  CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {
    aColor = processStyle(aColor);
    this.colors_.push({offset: 1-aOffset, color: aColor});
  };

  function CanvasPattern_() {}

  // set up externs
  G_vmlCanvasManager = G_vmlCanvasManager_;
  CanvasRenderingContext2D = CanvasRenderingContext2D_;
  CanvasGradient = CanvasGradient_;
  CanvasPattern = CanvasPattern_;

})();

} // if

/*
 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
 * Digest Algorithm, as defined in RFC 1321.
 * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for more info.
 */

/*
 * Configurable variables. You may need to tweak these to be compatible with
 * the server-side, but the defaults work in most cases.
 */
var hexcase = 0;  /* hex output format. 0 - lowercase; 1 - uppercase        */
var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
function b64_md5(s){ return binl2b64(core_md5(str2binl(s), s.length * chrsz));}
function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
function b64_hmac_md5(key, data) { return binl2b64(core_hmac_md5(key, data)); }
function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }

/*
 * Perform a simple self-test to see if the VM is working
 */
function md5_vm_test()
{
  return hex_md5("abc") == "900150983cd24fb0d6963f7d28e17f72";
}

/*
 * Calculate the MD5 of an array of little-endian words, and a bit length
 */
function core_md5(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << ((len) % 32);
  x[(((len + 64) >>> 9) << 4) + 14] = len;

  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;

    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);

    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);

    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);

    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
  }
  return Array(a, b, c, d);

}

/*
 * These functions implement the four basic operations the algorithm uses.
 */
function md5_cmn(q, a, b, x, s, t)
{
  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
}
function md5_ff(a, b, c, d, x, s, t)
{
  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t)
{
  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t)
{
  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t)
{
  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}

/*
 * Calculate the HMAC-MD5, of a key and some data
 */
function core_hmac_md5(key, data)
{
  var bkey = str2binl(key);
  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
  return core_md5(opad.concat(hash), 512 + 128);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function bit_rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert a string to an array of little-endian words
 * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
 */
function str2binl(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
  return bin;
}

/*
 * Convert an array of little-endian words to a string
 */
function binl2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
  return str;
}

/*
 * Convert an array of little-endian words to a hex string.
 */
function binl2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
  }
  return str;
}

/*
 * Convert an array of little-endian words to a base-64 string
 */
function binl2b64(binarray)
{
  var tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i += 3)
  {
    var triplet = (((binarray[i   >> 2] >> 8 * ( i   %4)) & 0xFF) << 16)
                | (((binarray[i+1 >> 2] >> 8 * ((i+1)%4)) & 0xFF) << 8 )
                |  ((binarray[i+2 >> 2] >> 8 * ((i+2)%4)) & 0xFF);
    for(var j = 0; j < 4; j++)
    {
      if(i * 8 + j * 6 > binarray.length * 32) str += b64pad;
      else str += tab.charAt((triplet >> 6*(3-j)) & 0x3F);
    }
  }
  return str;
}

/*
    json.js
    2007-08-19

    Public Domain

    This file adds these methods to JavaScript:

        array.toJSONString(whitelist)
        boolean.toJSONString()
        date.toJSONString()
        number.toJSONString()
        object.toJSONString(whitelist)
        string.toJSONString()
            These methods produce a JSON text from a JavaScript value.
            It must not contain any cyclical references. Illegal values
            will be excluded.

            The default conversion for dates is to an ISO string. You can
            add a toJSONString method to any date object to get a different
            representation.

            The object and array methods can take an optional whitelist
            argument. A whitelist is an array of strings. If it is provided,
            keys in objects not found in the whitelist are excluded.

        string.parseJSON(filter)
            This method parses a JSON text to produce an object or
            array. It can throw a SyntaxError exception.

            The optional filter parameter is a function which can filter and
            transform the results. It receives each of the keys and values, and
            its return value is used instead of the original value. If it
            returns what it received, then structure is not modified. If it
            returns undefined then the member is deleted.

            Example:

            // Parse the text. If a key contains the string 'date' then
            // convert the value to a date.

            myData = text.parseJSON(function (key, value) {
                return key.indexOf('date') >= 0 ? new Date(value) : value;
            });

    It is expected that these methods will formally become part of the
    JavaScript Programming Language in the Fourth Edition of the
    ECMAScript standard in 2008.

    This file will break programs with improper for..in loops. See
    http://yuiblog.com/blog/2006/09/26/for-in-intrigue/

    This is a reference implementation. You are free to copy, modify, or
    redistribute.

    Use your own copy. It is extremely unwise to load untrusted third party
    code into your pages.
*/

/*jslint evil: true */

// Augment the basic prototypes if they have not already been augmented.

if (!Object.prototype.toJSONString) {

    Array.prototype.toJSONString = function (w) {
        var a = [],     // The array holding the partial texts.
            i,          // Loop counter.
            l = this.length,
            v;          // The value to be stringified.

// For each value in this array...

        for (i = 0; i < l; i += 1) {
            v = this[i];
            switch (typeof v) {
            case 'object':

// Serialize a JavaScript object value. Ignore objects thats lack the
// toJSONString method. Due to a specification error in ECMAScript,
// typeof null is 'object', so watch out for that case.

                if (v) {
                    if (typeof v.toJSONString === 'function') {
                        a.push(v.toJSONString(w));
                    }
                } else {
                    a.push('null');
                }
                break;

            case 'string':
            case 'number':
            case 'boolean':
                a.push(v.toJSONString());

// Values without a JSON representation are ignored.

            }
        }

// Join all of the member texts together and wrap them in brackets.

        return '[' + a.join(',') + ']';
    };


    Boolean.prototype.toJSONString = function () {
        return String(this);
    };


    Date.prototype.toJSONString = function () {

// Eventually, this method will be based on the date.toISOString method.

        function f(n) {

// Format integers to have at least two digits.

            return n < 10 ? '0' + n : n;
        }

        return '"' + this.getUTCFullYear() + '-' +
                f(this.getUTCMonth() + 1)  + '-' +
                f(this.getUTCDate())       + 'T' +
                f(this.getUTCHours())      + ':' +
                f(this.getUTCMinutes())    + ':' +
                f(this.getUTCSeconds())    + 'Z"';
    };


    Number.prototype.toJSONString = function () {

// JSON numbers must be finite. Encode non-finite numbers as null.

        return isFinite(this) ? '"'+String(this)+'"' : 'null';
    };


    Object.prototype.toJSONString = function (w) {
        var a = [],     // The array holding the partial texts.
            k,          // The current key.
            i,          // The loop counter.
            v;          // The current value.

// If a whitelist (array of keys) is provided, use it assemble the components
// of the object.

        if (w) {
            for (i = 0; i < w.length; i += 1) {
                k = w[i];
                if (typeof k === 'string') {
                    v = this[k];
                    switch (typeof v) {
                    case 'object':

// Serialize a JavaScript object value. Ignore objects that lack the
// toJSONString method. Due to a specification error in ECMAScript,
// typeof null is 'object', so watch out for that case.

                        if (v) {
                            if (typeof v.toJSONString === 'function') {
                                a.push(k.toJSONString() + ':' +
                                       v.toJSONString(w));
                            }
                        } else {
                            a.push(k.toJSONString() + ':null');
                        }
                        break;

                    case 'string':
                    case 'number':
                    case 'boolean':
                        a.push(k.toJSONString() + ':' + v.toJSONString());

// Values without a JSON representation are ignored.

                    }
                }
            }
        } else {

// Iterate through all of the keys in the object, ignoring the proto chain
// and keys that are not strings.

            for (k in this) {
                if (typeof k === 'string' &&
                        Object.prototype.hasOwnProperty.apply(this, [k])) {
                    v = this[k];
                    switch (typeof v) {
                    case 'object':

// Serialize a JavaScript object value. Ignore objects that lack the
// toJSONString method. Due to a specification error in ECMAScript,
// typeof null is 'object', so watch out for that case.

                        if (v) {
                            if (typeof v.toJSONString === 'function') {
                                a.push(k.toJSONString() + ':' +
                                       v.toJSONString());
                            }
                        } else {
                            a.push(k.toJSONString() + ':null');
                        }
                        break;

                    case 'string':
                    case 'number':
                    case 'boolean':
                        a.push(k.toJSONString() + ':' + v.toJSONString());

// Values without a JSON representation are ignored.

                    }
                }
            }
        }

// Join all of the member texts together and wrap them in braces.

        return '{' + a.join(',') + '}';
    };


    (function (s) {

// Augment String.prototype. We do this in an immediate anonymous function to
// avoid defining global variables.

// m is a table of character substitutions.

        var m = {
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        };


        s.parseJSON = function (filter) {
            var j;

            function walk(k, v) {
                var i;
                if (v && typeof v === 'object') {
                    for (i in v) {
                        if (Object.prototype.hasOwnProperty.apply(v, [i])) {
                            v[i] = walk(i, v[i]);
                        }
                    }
                }
                return filter(k, v);
            }


// Parsing happens in three stages. In the first stage, we run the text against
// a regular expression which looks for non-JSON characters. We are especially
// concerned with '()' and 'new' because they can cause invocation, and '='
// because it can cause mutation. But just to be safe, we will reject all
// unexpected characters.

// We split the first stage into 3 regexp operations in order to work around
// crippling deficiencies in Safari's regexp engine. First we replace all
// backslash pairs with '@' (a non-JSON character). Second we delete all of
// the string literals. Third, we look to see if only JSON characters
// remain. If so, then the text is safe for eval.

            if (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/.test(this.
                    replace(/\\./g, '@').
                    replace(/"[^"\\\n\r]*"/g, ''))) {

// In the second stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.

                j = eval('(' + this + ')');

// In the optional third stage, we recursively walk the new structure, passing
// each name/value pair to a filter function for possible transformation.

                return typeof filter === 'function' ? walk('', j) : j;
            }

// If the text is not JSON parseable, then a SyntaxError is thrown.

            throw new SyntaxError('parseJSON');
        };


        s.toJSONString = function () {

// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can simply slap some quotes around it.
// Otherwise we must also replace the offending characters with safe
// sequences.

            if (/["\\\x00-\x1f]/.test(this)) {
                return '"' + this.replace(/[\x00-\x1f\\"]/g, function (a) {
                    var c = m[a];
                    if (c) {
                        return c;
                    }
                    c = a.charCodeAt();
                    return '\\u00' +
                        Math.floor(c / 16).toString(16) +
                        (c % 16).toString(16);
                }) + '"';
            }
            return '"' + this + '"';
        };
    })(String.prototype);
}
/*
CSS Browser Selector v0.2.9
Rafael Lima (http://rafael.adm.br)
http://rafael.adm.br/css_browser_selector
License: http://creativecommons.org/licenses/by/2.5/
Contributors: http://rafael.adm.br/css_browser_selector#contributors
*/
var css_browser_selector = function() {var ua=navigator.userAgent.toLowerCase(),is=function(t){return ua.indexOf(t) != -1;},h=document.getElementsByTagName('html')[0],b=(!(/opera|webtv/i.test(ua))&&/msie\s(\d)/.test(ua))?('ie ie'+RegExp.$1):is('firefox/2')?'gecko ff2':is('firefox/3')?'gecko ff3':is('gecko/')?'gecko':is('opera/9')?'opera opera9':/opera\s(\d)/.test(ua)?'opera opera'+RegExp.$1:is('konqueror')?'konqueror':is('chrome')?'chrome webkit safari':is('applewebkit/')?'webkit safari':is('mozilla/')?'gecko':'',os=(is('x11')||is('linux'))?' linux':is('mac')?' mac':is('win')?' win':'';b+= (navigator.userAgent.toLowerCase().indexOf('adobeair')>-1 ? ' adobeair' : '');var c=b+os+' js'; h.className += h.className?' '+c:c;}();
mj={version:'0.8 alpha'};
$(function(){
	mj.bd = $(document.body);
	window.onresize = function(){
		var l = mj._windowResizeListeners;
		if(l){
			return $(l).eachR(function(){
				if(this.scope.componentClass)
					return this.fn.apply(this.scope);
				else
					return null;
			});
		}
	};
	if($.browser.msie)
		mj.bd.addClass('mj-ie mj-ie'+parseInt($.browser.version));
});
$.fn.hasParent = function(parent){
	var fp;
	$(this[0]).parents().each(function(){
		if(this===parent)
			fp = this;
	});
	return fp;
};
$.fn.hasAbsoluteParent = function(){
	var fp;
	$(this[0]).parents().each(function(){
		var t = $(this);
		if(t.css && (t.css('position')=='absolute' ||t.css('position')=='relative'))
			fp = t;
	});
	return fp;
};
$.eachR = function( obj, fn, args ) {
	if ( obj.length == undefined )
		for ( var i in obj )
			fn.apply( obj[i], args || [i, obj[i]] );
	else
		for ( var i = 0, ol = obj.length; i < ol; i++ )
			if ( fn.apply( obj[i], args || [i, obj[i]] ) === false )
				return false;
	return obj;
};
$.fn.eachR = function( fn, args ) {
	return jQuery.eachR( this, fn, args );
};
$.fn.position = function(ret){
	return this.offset({scroll:false}, ret);
};
$.fn.swapClass = function(c1, c2) {
	return this.each(function() {
		var $this = $(this);
		if ( $.className.has(this, c1) )
			$this.removeClass(c1).addClass(c2);
		else if ( $.className.has(this, c2) )
			$this.removeClass(c2).addClass(c1);
	});
};
$.fn.replaceclass = function(c1, c2) {
	return this.each(function() {
		var $this = $(this);
		if ( $.className.has(this, c1) )
			$this.removeClass(c1).addClass(c2);
	});
};
$.fn.kkresizewidth = function(width, dont){
	if(width>0){
		this[0].style.width = parseInt(width) + 'px';
		if(dont!==true)
			this.trigger('kkresize');
	}		
	return this;
};
$.fn.kkresizeheight = function(height, dont){
	if(height>0){
		this[0].style.height = parseInt(height) + 'px';
		if(dont!==true)
			this.trigger('kkresize');
	}
	return this;
};
$.fn.extend({
	load: function( url, params, callback ) {
		if ( jQuery.isFunction( url ) )
			return this.bind("load", url);

		var off = url.indexOf(" ");
		if ( off >= 0 ) {
			var selector = url.slice(off, url.length);
			url = url.slice(0, off);
		}

		callback = callback || function(){};

		// Default to a GET request
		var type = "GET";

		// If the second parameter was provided
		if ( params )
			// If it's a function
			if ( jQuery.isFunction( params ) ) {
				// We assume that it's the callback
				callback = params;
				params = null;

			// Otherwise, build a param string
			} else {
				params = jQuery.param( params );
				type = "POST";
			}

		var self = this;

		// Request the remote document
		jQuery.ajax({
			url: url,
			type: type,
			data: params,
			complete: function(res, status){
				// If successful, inject the HTML into all the matched elements
				if ( status == "success" || status == "notmodified" )
					// See if a selector was specified
					var ja = jQuery.active;
					self.html( selector ?
						// Create a dummy div to hold the results
						jQuery("<div/>")
							// inject the contents of the document in, removing the scripts
							// to avoid any 'Permission Denied' errors in IE
							.append(res.responseText.replace(/<script(.|\s)*?\/script>/g, ""))

							// Locate the specified elements
							.find(selector) :

						// If not, just inject the full result
						res.responseText );
					jQuery.active = ja;
				// Add delay to account for Safari's delay in globalEval
				setTimeout(function(){
					self.each( callback, [res.responseText, status, res] );
				}, 13);
			}
		});
		return this;
	}
});	
/** 
* @fileoverview Bu dosya kütüphane genelinde kullanılmakta olan genel sabit tanımlamaları ve metodları içerir
* @hazırlayan kk
* @sürüm 0.1
*/
/**
 * global mj objesi. UI'nin tamamında kullanılacak global değişkenlerin tutulduğu obje.
 * @name mj.glb
 */
 
mj.glb = {
	blankImage : 'http://www.bursaakgenclik.com/res/myjui/myjui/images/spacer.gif',
	modalIndex : 500,
	menuDelay : 300,
	messageWidth : 300,
	messageHeight : 150,
	imagePath : '',
	//blankImage : 'http://myjui.com/spacer.gif',
	//editorSettings : {mjPath.php'ye alındı.
	//	root : 'res/openwysiwyg/'
	//},
	views : []
};
/**
 * Tuş değerlerinin tutulduğu obje
 * @name mj.keys
 */
mj.keys = {
	BACKSPACE : 8,
	TAB : 9,
	RETURN : 13,
	ENTER : 13,
	SHIFT : 16,
	CONTROL : 17,
	ESC : 27,
	SPACE : 32,
	PAGEUP : 33,
	PAGEDOWN : 34,
	END : 35,
	HOME : 36,
	LEFT : 37,
	UP : 38,
	RIGHT : 39,
	DOWN : 40,
	DELETE : 46,
	F5 : 116,
	/**
	 * Basılan tuşun özel tuş olması durumunda true döndüren fonksiyon
	 * @name mj.keys.isSpecial
	 * @function
	 * @type {Function}
	 * @param {Object} e Event objesi
	 * @return {Boolean} Özel tuş olması durumunda true döndürür
	 */
	isSpecial : function(e){
		var k = e.keyCode;
		return (e.type == 'keypress' && e.ctrlKey) || k == 9 || k == 13  || k == 40 || k == 27 ||
		(k == 16) || (k == 17) ||
		(k >= 18 && k <= 20) ||
		(k >= 33 && k <= 35) ||
		(k >= 36 && k <= 39) ||
		(k >= 44 && k <= 45);
	}	
};
/**
 * Verilen genişlik ve yükseklikte boşluk oluşturur
 * @name mj.insertSpacer
 * @function
 * @type {Function}
 * @param {Integer} width Genişlik değeri
 * @param {Integer} height Yükseklik değeri
 * @return {HTMLElement} parametrelerinde aldığı boyutta img döndürür
 */
mj.insertSpacer = function(width,height){
	width = width ? width : 1;
	height = height ? height : 1;
	return '<img style="width:'+width+'px;height:'+height+'px;" src="'+mj.glb.blankImage+'"/>';
};
/**
 * document.getElementById metodunun kısa çağırım şekli
 * @name mj.get
 * @function
 * @type {Function}
 * @param {String} id Aranan HTML elemanının id değeri
 * @return {HTMLElement} 
 */
mj.get = function(id){
	return document.getElementById(id);
};
/**
 * HTTP istekleri çalıştırılırken <i>'Yükleniyor...'</i> imgesini göstermek için kullanılan metod
 * @name mj.loaderShow
 * @function
 * @type {Function}
  */
mj.loaderShow = function(){
	if(!mj.loading)
		mj.loading = $(mj.NE(mj.bd, {cls:'mj-loader', html:mj.lng.glb.loadingText}));
	mj.loading.show();
};
/**
 * HTTP istekleri sonuçlandığında <i>'Yükleniyor...'</i> imgesini gizlemek için kullanılan metod
 * @name mj.loaderHide
 * @function
 * @type {Function}
  */
mj.loaderHide = function(){
	mj.loading.hide();
};
/**
 * Bu metod bir elemanın içeriğini güncellemek için kullanılır. İstek süresince <i>'Yükleniyor...'</i> imgesi görüntülenir.
 * @example
var container = mj.get('container');
mj.load(container, 'page.php?id=1&type=a');
 * @example
var container = mj.get('container');
var cb = function(responseText, status, response){
	alert(responseText);
};
mj.load(container, {
	url : 'page.php',
	params : {
		id : 1,
		type : 'a'
	},
	callback : cb
});
 * @name mj.load
 * @function
 * @type {Function}
 * @param {HTMLElement} cnt İçeriği güncellenecek olan eleman.
 * @param {Object/String} config Güncelleme parametreleridir. String olarak verildiğinde parametrenin istek yapılacak sayfa adresi olduğu varsayılır.
 * @config {String} url İstek yapılacak sayfa adresi
 * @config {Object} params İstek yapılacak sayfaya gönderilecek olan parametreler
 * @config {Function} callback İstek sonuçlandığında tetiklenecek olan fonksiyon
  */
mj.load=function(cnt,config){
	var c = (typeof config == 'object') ? config : {url:config};
	var url = c.url, params = c.params, callback = c.callback;
	var cb = function(responseText, status, response){
		if(typeof callback=='function') callback(responseText, status, response);
		mj.loaderHide();
	};
	if(c.dataType=='script')
		$.ajax(c);
	else
	$(cnt).load(url, params, cb);
};
mj.getString = function(config){
	var cnt = $(mj.NE(mj.bd, {cls:'mj-invisible'}));
	var c = (typeof config == 'object') ? config : {url:config};
	var url = c.url, params = c.params, callback = c.callback;
	var cb = function(responseText){
		if(typeof callback=='function') callback(responseText);
		mj.loaderHide();
		cnt.remove();
	};
	cnt.load(url, params, cb);
};
/**
	* @param {Object} source kaynak nesne
	* @param {Object} target hedef nesne
	* @param {String} subKey alt nesnelerin tutulduğu property adı
	var tmpObj = this.cloneObject(source, target ,subKey);
*/
mj.cloneObject = function(source, subKey, target){
	if(!subKey)
		subKey = 'data';
	if(!target)
		target = {};
	for(var i in source)
		if(typeof source[i] != 'function'){
			var c = {};
			if(typeof source[i] !== 'object' || source[i] == null || source[i] == undefined)
				c = source[i];
			else
				for(var j in source[i]){
					if(typeof source[i][j] != 'function')
						if(j!=subKey)
							c[j] = source[i][j];
						else{
							c[j] = source[i][j] instanceof Array?[]:{};
							mj.cloneObject(source[i][j], subKey, c[j]);
						}
				}
			target[i] = c;
		}
	return target;
};

/**
 * config parametresi ile verilen nesnenin tüm özelliklerini obj parametresi ile verilen nesneye kopyalar
 * @name mj.apply
 * @function
 * @type {Function}
 * @param {Object} obj Hedef nesne
 * @param {Object} config Kaynak nesne
 * @return {Object} obj parametresi ile verilen nesne
 */
mj.apply=function(obj,config){
	if(obj&&config&&typeof config=='object')
		for(var p in config)
			obj[p]=config[p];
	return obj;
};
/**
 * config parametresi ile verilen nesnenin özelliklerinden obj parametresi ile verilen nesnede tanımlı olmayanları kopyalar
 * @name mj.applyIf
 * @function
 * @type {Function}
 * @param {Object} obj Hedef nesne
 * @param {Object} config Kaynak nesne
 * @return {Object} obj parametresi ile verilen nesne
 */
mj.applyIf = function(obj,config){
	if(typeof obj!=='object')
		obj = {};
	if(config)
		for(var p in config)
			if(typeof obj[p]=="undefined")
				obj[p]=config[p];
	return obj;
};
/**
 * kaynak sınıftan bir başka sınıf türetmeye yarar
 * @name mj.extend
 * @function
 * @type {Function}
 * @param {Object} sc Kaynak sınıf
 * @param {Object} bc Hedef sınıf
 */
mj.extend = function(sc, bc) {
	var fn = function() {};
	fn.prototype = bc.prototype;
	var scpb = sc.prototype;
	var scp = sc.prototype = new fn();
	scp.constructor = sc;
	if(bc.prototype.constructor == Object.prototype.constructor)
		bc.prototype.constructor = bc;
	mj.apply(scp, scpb);
	sc.superclass = bc.prototype;
};
/**
 * Sıralı olarak artan bir sayısal değer döndürür. Oluşturulan nesnelere id ataması yaparken kullanılıyor
 * @name mj.genId
 * @example
var newEl = mj.NE(document.body, {id: 'kk-'+mj.genId()});
 * @function
 * @type {Function}
 * @return {Integer} Oluşturulan sayısal değer
 */
mj.idCounter = 0;
mj.genId = function(prefix){
	return ((prefix?prefix:'')+(mj.idCounter++));
};
/**
 * DOM üzerinde yeni html elemanları oluşturur.
 * @name mj.NE
 * @function
 * @type {Function}
 * @param {HTMLElement} [container] Yeni elemanın içine oluşturulacağı hedef nesne. Varsayılan değeri <i>document.body</i> olarak ayarlanmıştır.
 * @param {HTMLElement} [config] Yeni elemanın özellikleri. Bu parametre içerisinde aşağıda belirtilenler dışında verilen özellikler
 varsa bunlar yeni elemanın özellikleri(attribute) olarak atanır<br>
 * @example
mj.NE(document.body, {tag:'span', html:'My Text', myattribute:'myvalue'});
<br><pre class="comment">Yukarıdaki kod sonucunda döküman içerisinde<xmp><span myattribute="myvalue">My Text</span></xmp>elemanı oluşur</pre>
 * @config {String} tag Elemanın HTML etiketi. Varsayılan değeri : <i>'div'</i>
 * @config {String} cls Elemanın stil sınıfı 
 * @config {String} html Elemanın içine eklenecek olan html ifadesi
 * @config {Array} children Bu parametre ile dizi halinde gönderilecek olan config nesneleri de oluşturularak yeni nesneye dahil edilir
 * @return {HTMLElement} Oluşturulan HTML elemanı
 */
mj.NE = function(container,config){
	config = !config ? {tag:'div'} : (config.tag ? config : mj.apply(config,{tag:'div'}));
	if(!config.draggable)
		config.draggable = 'false';
	var _c = container ? $(container) : $(document.body), chld = config.children;
	if(typeof config!=='string'){
		var attr = '';
		for(var item in config)
			if(typeof config[item]!=='function' && item!=='cls' && item!=='html' && item!=='tag' && item!=='children' && config[item])
				attr += ' ' + item +'="' + config[item] + '" ';
		var endtag = '</' + config.tag + '>', closetag = '>';
		if(config.tag=='input' || config.tag=='img'){
			endtag = '/>';
			closetag = '';
		}
		config = '<' + config.tag + (config.cls ? (' class="' + config.cls + '" ') : '') + attr + closetag + (config.html ? config.html : '') + endtag;
	}
	_c.append(config);
	var _ch = _c.children();
	_ch = _ch[_ch.length-1];
	if(chld)
		$(chld).each(function(){
			return mj.NE(_ch, this);
		});
	return _ch;
};
/**
 * Bir dizi içerisindeki nesnelerin <i>key</i> parametresinde belirtilen özelliği aranan 
 değere eşit olan ilk nesnenin sırasını verir. Eşleşen nesne olmazsa -1 sonucu döner. Kısa kullanım karşılığı : <b>mj.getIndex</b>
 * @example
var arr = [
	{id:0, name : 'a'},
	{id:1, name : 'b'},
	{id:2, name : 'c'},
	{id:3, name : 'b'}
];
var i = mj.getIndex(arr, 'name', 'b'); // =1
 * @name mj.getArrayElementIndex
 * @function
 * @type {Function}
 * @param {Array} array Nesneleri barındıran dizi
 * @param {String} key Kıyaslama kriteri
 * @param {Object/String/Number, vb...} keyValue Aranan değer
 * @return {Integer} Aranan elemanın sıra değeri. Değer bulunamaması durumunda -1
 */
mj.getIndex = mj.getArrayElementIndex = function(array,key,keyValue){
	if(typeof array.length!='undefined')
		for(var i = 0, len = array.length; i < len; i++){
			if(array[i][key]==keyValue)	return i;
		}
	else
		for(var i in array)
			if(typeof array[i]!='function')
				if(array[i][key]==keyValue)	return i;
	return -1;
};
/**
 * <i>consol</i> üzerinde <i>msg</i> parametresi ile aldığı mesajı yazdırır.
 * @example 
 mj.log('mesaj');
 * @name mj.log
 * @function
 * @type {Function}
 * @param {String} msg Konsolda yazdırılması istenen mesaj
 */
mj.log = function(msg){
	window.console && console.log && console.log(msg);
	window.air && window.air.Introspector && window.air.Introspector.Console.log(msg);
};

/**
 * <i>str</i> parametresi ile aldığı metin içinden <i>+</i> - <i><|p|></i> ve <i>%</i> - <i><|_|></i> değişimini yapar escape eder.
 * @name mj.escape
 * @function
 * @type {Function}
 * @param {String} str Escape edilecek metin
 * @return {String} Escape edilmiş string.
 */
mj.escape = function(str){
	str = str ? str : '';
	str = str.toString().replace(/\+/g,'<|p|>');
	str = str.toString().replace(/\%/g,'<|_|>');
	return encodeURIComponent ? encodeURIComponent(str) : escape(str);
};
/**
 * Ana renderer fonksiyonu
 * @name mj.renderer
 * @function
 * @type {Function}
 */
mj.renderer = function(){
	var trimRe = /^\s+|\s+$/g;
	return{
		bool : function(){
			return function(v){
				return mj.renderer.booleanRenderer(v);  
			};
		},
		/**
		 * <i>v</i> parametresi ile aldığı değeri <i>true</i> olması durumunda <i>Evet</i> değilse <i>Hayır</i> olarak değiştirir. 
		 * @name booleanRenderer
		 * @function
		 * @type {Function}
		 * @param {String} v Render edilecek değer
		 * @memberOf  mj.renderer
		 * @return {String} <i>Evet</i> veya <i>Hayır</i>.
		 */
		booleanRenderer : function(v){
			return v=='1' ? mj.lng.titles.buttons.yes : mj.lng.titles.buttons.no;
		},
		/**
		 * clearZero. 
		 * @name clearZero
		 * @function
		 * @type {Function}
		 * @param {Float} val Render edilecek değer
		 * @memberOf  mj.renderer
		 * @return {String} <i>Para birimi türünde değer</i> veya <i>0,00</i>.
		 */
		check : function(){
			return function(val){
				val = parseInt(val);
				return '<center><div class="mj-checkbox '+(val!=''?'mj-checkbox-checked':'')+' '+(val==-1?'mj-item-disabled':'')+'" style="height:16px;float:none;"></div></center>';
			};
		},
		clearZero : function(val){
			if(val){
				val = val.toString().replace('.',',').split(',');
				if(!val[1]) return val;
				val[1] = val[1].replace('00000000','');
				for(var i=val[1].length;i>0;i--){if(val[1][i-1]!='0'){val[1]=val[1].substr(0,i);break;}}
				return val[0]+(val[1].length>0 ? ',' + val[1] : '');
			}else
				return '0,00';
		},
		color : function(val){
			return '<div style="background: '+val+' none repeat scroll 0%;"><center><img src="'+mj.glb.blankImage+'" style="height:20px;width:100%;" /></center></div>'
		},
		/**
		 * <i>v</i> parametresiyle aldığı değeri <i>format</i> parametresinde belirtilen formatta değeri formatlayacak geri döndürür. 
		 * @name dateRenderer
		 * @function
		 * @type {Function}
		 * @param {String} v Formatlanacak değer
		 * @param {String} format Tarih formatı tipi
		 * @memberOf  mj.renderer
		 * @return {String} Formatlanmış tarih stringi.
		 */
		dateRenderer : function(v, format){
			if(!v){
				return "";
			}
			if(!(v instanceof Date)){
				if (/^\d{8}$/.test(v)){
					v=new Date(Date.parse(v.substring(0,4)+'/'+v.substring(4,6)+'/'+v.substring(6,8)));
				//}else if(/^\d{4}\-\d{2}\-\d{2}\s{1}\d{2}\:\d{2}\:\d{2}/.test(v)){
				//	v = new Date(Date.parse(v.substring(5,7)+'/'+v.substring(8,10)+'/'+v.substring(0,4)));
				}else if(typeof v == 'number')
					v = new Date(v*1000);
				else if(typeof v == 'string' && new Date(parseInt(v)*1000) instanceof Date)
					v = new Date(parseInt(v)*1000);
				else
					v=new Date(Date.parse(v));
					//v=new Date(Date.parseDate(v,format));
			}
			return (isNaN(v.getDay()))?'&#160;':v.formatDate(format || "d/m/Y");
		},
		/**
		 * <i>format</i> parametresinde belirtilen formatta değeri formatlayacak fonksiyonu geri döndürür. 
		 * @name date
		 * @function
		 * @type {Function}
		 * @param {String} format Tarih formatı
		 * @memberOf  mj.renderer
		 * @return {Function} <i>dateRenderer</i> fonksiyonu.
		 */
		date : function(format){
			return function(v){
				return mj.renderer.dateRenderer(v, format);  
			};
		},
		right : function(val){
			return '<div style="text-align:right">'+val+'</div>';
		},
		timeRenderer : function(v, format){
			if(!v){
				return "";
			}
			if(!(v instanceof Date)){
				//if(/^\d{2}\-\d{2}\-\d{4}\s{1}\d{2}\:\d{2}\:\d{2}/.test(v)){
				//	v = new Date(Date.parse(v.substring(5,7)+'/'+v.substring(8,10)+'/'+v.substring(0,4)+' '+v.substring(11)));
				if(typeof v == 'number')
					v = new Date(v*1000);
				else{
					v=new Date(Date.parse(v));
					//v=new Date(Date.parseDate(v,format));
				}
			}
			return (isNaN(v.getDay()))?'&#160;':v.formatDate(format || "d/m/Y H:i:s");
		},
		time : function(format){
			return function(v){
				return mj.renderer.timeRenderer(v, format);  
			};
		}
	}
}();
mj.applyIf(Array.prototype, {
    /**
     * Gönderilen objenin dizi içinde olup olmadığını kontrol eder.
     * @param {Object} o Kontrol edilecek obje
     * @return {Number} o objesinin dizi içindeki indeks değeri (bulunamadığı durumda -1)
     */
    indexOf : function(o){
		for (var i = 0, len = this.length; i < len; i++){
			if(this[i] == o) return i;
		}
		return -1;
    },

    /**
     * Dizi içinden belirli bir objeyi siler.Silinmesi istenen objenin dizi içinde olmaması durumunda hiçbir şey yapmaz.
     * @param {Object} o Silinencek olan obje.
     * @return {Array} this Dizi
     */
    remove : function(o){
		var index = this.indexOf(o);
		if(index != -1){
			this.splice(index, 1);
		}
		return this;
    }
});
mj.apply(Array.prototype,{
	getIndex : function(key,keyValue){
		if(typeof this.length!='undefined')
			for(var i = 0, len = this.length; i < len; i++)
				if(this[i][key]==keyValue)	
					return i;
		else
			for(var i in this)
				if(typeof this[i]!='function')
					if(this[i][key]==keyValue)	
						return i;
		return -1;
	},
	extractKeyValues : function(key, arr, subArr, returnArr){
	    if(!arr)
	        arr = this;
	    if(!subArr)
	        subArr = 'data';
	    if(!returnArr)
	        returnArr = [];
	    for(var i=0,l=arr.length;i<l;i++){
	        returnArr.push(arr[i][key]);
	        if(arr[i][subArr])
	            this.extractKeyValues(key, arr[i][subArr], subArr, returnArr);
	    }
	    return returnArr;
	},
	filter : function(fn,quit,firstIndex){
		var tmp = [];
		if(typeof firstIndex == 'undefined' || firstIndex == -1)
			firstIndex = 0;
		for(var i = 0 + firstIndex ,len = this.length; i<len; i++){
			if(fn(this[i])){
				tmp.push(this[i]);
				if(quit)
					return tmp;
			}
		}
		return tmp;
	},
	_sort : function(key,dir,fn){
		var dKey = String(dir).toUpperCase() == "DESC" ? -1 : 1;
		fn = fn?fn:function(x,y){return x-y;};
		this.sort(function(x,y){
            var ret = fn(x[key], y[key]) * dKey;
            // if(ret == 0)
                // ret = (x.index < y.index ? -1 : 1);
            return ret;
        });
	}
});
/**
 * Ana init fonksiyonu. Http istekleri esnasında loader nesnesinin ekranda görünme ve gizlenme zamanları ile ilgili ayarların yapıldığı bölüm
 * @name mj.init
 * @function
 * @type {Function}
 */
mj.init = function(){
	$().ajaxStart(function(){
		if(!mj.dontShowLoader)
			mj.loaderShow();
	}).ajaxStop(function(){
		if(!mj.dontShowLoader)
			mj.loaderHide();
	});
};
mj.init();
/**
 * Parametre olarak gönderilen elementin parent elementleri içinde <i>mj-resize-handle</i> class'ına sahip ilk div elementini bulur, bu elemente
 <i>kkresize</i> eventi bind eder ve parametrelerde aldığı callback fonksiyonunu scope ile birlikte çalıştırır.
 * @name mj.bindResize
 * @function
 * @type {Function}
 * @param {HTMLElement} el Resize bind edilecek nesnenin içindeki container element.
 * @param {Function} cb resize esnasında çalıştırılacak fonksiyon.
 * @param {Object} scope Scope.
 */
mj.bindResize = function(el,cb,scope){
	var fp=$(el).parents('div.mj-resize-handle:first');
	if(fp.length==0)
		fp = mj.bd;
	window.reM = window.reM || [];
	window.reM.push({fp : fp , el : el,cb : cb});
	if(fp && fp[0] && fp[0].tagName=='BODY')
		mj.onWindowResize(cb, scope);
	else
		fp.bind('kkresize', function(){
			cb.call(scope,arguments);
		});

};
mj.onWindowResize = function(fn, scope){
	if(!mj._windowResizeListeners)
		mj._windowResizeListeners = [];
	mj._windowResizeListeners.push({fn:fn, scope:scope ? scope : this});
};
/**
 * Ana format objesi.Format dönüşümlerini yapacak olan fonksiyonları içerir.
 * @name mj.format
 */
mj.format = {	
	/**
	 * float2Money fonksiyonu
	 * @name mj.format.float2Money
	 * @function
	 * @type {Function}
	 * @param {Float} v Silinencek olan obje.
	 * @param {Integer} dp Ondalık sayısı(Ön tanımlı değeri : 2).
	 * @param {String} ds Ondalık ayracı.
	 * @param {String} gs Binlik ayracı.
	 */
	float2Money : function(v, dp,ds,gs){
		var num=v,decimalPrecision=!isNaN(dp) ? dp : 2;
		if(isNaN(num)){
			return '';
		}
		sign = (num == (num = Math.abs(num)));
		num = Math.floor(num*Math.pow(10,decimalPrecision)+0.50000000001);
		cents = num%Math.pow(10,decimalPrecision);
		num = Math.floor(num/Math.pow(10,decimalPrecision)).toString();
		while(cents.toString().length<(Math.pow(10,decimalPrecision-1)).toString().length)
			cents = "0" + cents;
		for (var i = 0,val=Math.floor((num.length-(1+i))/3); i < val; i++)
			num = num.substring(0,num.length-(4*i+3))+gs+num.substring(num.length-(4*i+3));
		if(decimalPrecision > 0)
			return (((sign)?'':'-') + num + ds + cents);
		else
			return (((sign)?'':'-') + num);
	},
	d2h : function(d){return d.toString(16);},
	h2d : function(h){return parseInt(h,16);}
};
if($.browser.msie){
	try{
		document.execCommand("BackgroundImageCache",false,true);
	}catch(e){
	}
}
/**
 * getNumber fonksiyonu
 * @name mj.getNumber
 * @function
 * @type {Function}
 * @param {String} value
 * @return {Integer} Sayı değeri
 */
mj.getNumber = function(value){
	var x = value.split('0');
	if(x.length==2&&x[0]=='')
		return parseInt(x[1]);
	else 
		return parseInt(value);
};
/**
 * str2date fonksiyonu
 * @name mj.str2date
 * @function
 * @type {Function}
 * @param {String} value '12/02/2007' gibi bir tarih
 * @return {Date} Tarih değeri
 */
mj.str2date = function(value){
	var v = value.split('/');
	var time = new Date();
	time.setDate(mj.getNumber(v[0]));
	time.setMonth((mj.getNumber(v[1])-1));
	time.setFullYear(parseInt(v[2]));
	return time;
};
/**
 * date2str fonksiyonu
 * @name mj.date2str
 * @function
 * @type {Function}
 * @param {Date} date Date tipli değişken
 * @param {String} format Dönüştürülecek tarih formatı
 * @return {String} String olarak tarih değeri
 */
mj.date2str = function(date,format){
	return date.formatDate(format);
};
mj.oLength = function(obj){
	var l=0;
	for(var i in obj)
		if(typeof obj[i]!='function')
			l++;
	return l;
};
// mj.globalEvents = {};
// mj.addEvent = function(event){
	// var mjGlbE = mj.globalEvents;
	// if(!mjGlbE.events)
		// mjGlbE.events = {};
	// if(!mjGlbE.events[event])
		// mjGlbE.events[event] = {listeners : []};
// };
// mj.on = function(event, fn, scope){
		// mj.addEvent(event);
		// mj.globalEvents.events[event].listeners.push({fn:fn, scope:scope ? scope : mj});
// };
// mj.mon = function(event, fn){
	// var e = mj.globalEvents.events[event];
	// if(e && e.listeners){
		// var i = mj.getIndex(e.listeners, 'fn', fn);
		// if(i>-1)
			// e.listeners[i].fn = function(){};
	// }
	// return i>-1;
// };
// mj.trigger = function(){
	// var args = Array.prototype.slice.call(arguments, 0);
	// mj.addEvent(args[0]);
	// var e = mj.globalEvents.events[args[0]], l = e.listeners;
	// if(e && l){
		// return $(l).eachR(function(){
			// return this.fn.apply(this.scope, args.slice(1));
		// });
	// }
// };
// $(window).bind('beforeunload', function(){
	// return "ok1";
// });
// $(window).bind('beforeunload', function(){
	// return "ok2";
// });
mj.removeModified = function(obj){
	if(mj.modified && mj.modified.indexOf(obj)>-1)
		mj.modified.pop(obj);
};
mj.addModified = function(obj){
	if(!mj.modified)
		mj.modified = [];
	if(mj.modified.indexOf(obj)==-1)
		mj.modified.push(obj);
};
mj.translate = function(val){
	return (mj.lng.titles.modules&&mj.lng.titles.modules.general&&mj.lng.titles.modules.general[val])?mj.lng.titles.modules.general[val]:val;
};
// window.onbeforeunload = function() {
	// if(mj.modified && mj.modified.length>0)
		// return mj.lng.glb.exitQuestion;
// };
mj.newWindow = function(config){
	var cnf = mj.applyIf(config,{
		location : 0,
		status : 0,
		scrollbars : 1,
		resizable : 1,
		toolbar : 0,
		width : 800,
		height : 600
	});
	var win = window.open(cnf.url||"",cnf.id||mj.genId("mj-window"),"location="+cnf.location+",toolbar="+cnf.toolbar+",resizable="+cnf.resizable+",status="+cnf.status+",scrollbars="+cnf.scrollbars+",width="+cnf.width+",height="+cnf.height);
	if(cnf.title)
		win.document.title = cnf.title;
	return win;
};
mj.timeShow = function(time, msg, showSec){
	var str = '';
	var y = Math.floor(time/31536000000);
	time -= y*31536000000;
	var m = Math.floor(time/2592000000);
	time -= m*2592000000;
	var w = Math.floor(time/604800000);
	time -= w*604800000;
	var d = Math.floor(time/86400000);
	time -= d*86400000;
	var h = Math.floor(time/3600000);
	time -= h*3600000;
	var i = Math.floor(time/60000);
	time -= i*60000;
	var s=0;
	if(showSec){
		s=Math.floor(time/1000);
		time-=s*1000;
	}
	if(y>0)
		str += y + (msg?" yıl ":":");
	if(m>0)
		str += m + (msg?" ay ":":");
	if(w>0)
		str += w + (msg?" hafta ":":");
	if(d>0)
		str += d + (msg?" gün ":":");
	if(h>0)
		str += h + (msg?" saat ":":");
	if(i>0)
		str += i + (msg?" dakika ":":");
	if(s>0)
		str+=s+(msg?" saniye":":");
	if(str[str.length-1]==':')
		str=str.substring(0,str.length-1);
	return str;
};

mj.timeShowHour = function(time, msg, showSec){
	var str = '';
	var y = Math.floor(time/31536000000);
	time -= y*31536000000;
	var m = Math.floor(time/2592000000);
	time -= m*2592000000;
	var w = Math.floor(time/604800000);
	time -= w*604800000;
	var d = Math.floor(time/86400000);
	time -= d*86400000;
	var h = Math.floor(time/3600000);
	time -= h*3600000;
	var i = Math.floor(time/60000);
	time -= i*60000;
	var s=0;
	if(showSec){
		s=Math.floor(time/1000);
		time-=s*1000;
	}
	// if(y>0)
		// str += y + (msg?" yıl ":":");
	// if(m>0)
		// str += m + (msg?" ay ":":");
	// if(w>0)
		// str += w + (msg?" hafta ":":");
	// if(d>0)
		// str += d + (msg?" gün ":":");
	h += 24*d + 168*w + 720*m + 8760*y;
	if(h>0)
		str += h + (msg?" saat ":":");
	if(i>0)
		str += i + (msg?" dakika ":":");
	if(s>0)
		str+=s+(msg?" saniye":":");
	if(str[str.length-1]==':')
		str=str.substring(0,str.length-1);
	return str;
};

mj.timeShowShort = function(time){
	var str = '', count = 2;
	var y = Math.floor(time/31536000000);
	time -= y*31536000000;
	var m = Math.floor(time/2592000000);
	time -= m*2592000000;
	var w = Math.floor(time/604800000);
	time -= w*604800000;
	var d = Math.floor(time/86400000);
	time -= d*86400000;
	var h = Math.floor(time/3600000);
	time -= h*3600000;
	var i = Math.floor(time/60000);
	time -= i*60000;
	var s=0;
	s=Math.floor(time/1000);
	time-=s*1000;
	if(y>0 && count-->0)
		str += y + " yıl ";
	if(m>0 && count-->0)
		str += m + " ay ";
	if(w>0 && count-->0)
		str += w + " hafta ";
	if(d>0 && count-->0)
		str += d + " gün ";
	if(h>0 && count-->0)
		str += h + " saat ";
	if(i>0 && count-->0)
		str += i + " dk ";
	if(s>0 && count-->0)
		str+=s+" sn";
	if(str[str.length-1]==':')
		str=str.substring(0,str.length-1);
	return str.trim();
};
mj.countDomEls = function(el){
    el = $(el ? el : mj.bd);
    for(var c=1,_c=el.children(),i=0,l=_c.length;i<l;i++)
        c += mj.countDomEls(_c[i]);
    return c;
};

mj.textReplacement = function(input, title){
	//mj.textReplacement($('#inputname')); / mj.textReplacement($('#inputname'), 'title');
	if(title && input.val()=='')
		input.val(title);
	var originalvalue = title || input.attr('title'), originalColor = input.css('color')||'#000'; 
	input.focus( function(){ 
		if( $.trim(input.val()) == originalvalue ){ input.val(''); input.css('color', originalColor);} 
	});
	input.blur( function(){
		if( $.trim(input.val()) == '' ){ input.val(originalvalue); input.css('color', '#565656');}
	});
};

String.prototype.ellipse = function(maxLength){
    if(this.length > maxLength){
        return this.substr(0, maxLength-3) + '...';
    }
    return this;
};

String.prototype.repeat = function(l){
	return new Array(l+1).join(this);
};

String.prototype.LTrim = function( ) {
	var re = /\s*((\S+\s*)*)/;
	return this.replace(re, "$1");
};

String.prototype.RTrim = function( ) {
	var re = /((\s*\S+)*)\s*/;
	return this.replace(re, "$1");
};

String.prototype.trim = function( ) {
	return this.LTrim().RTrim();
};

String.prototype.capitalize = function(){ //v1.0
    return this.replace(/\w+/g, function(a){
        return a.charAt(0).toUpperCase() + a.substr(1).toLowerCase();
    });
};
String.prototype.addPrefix = function(p,l){
	var val = p+this;
	var sl = val.length;
	return val.substring(sl-l,sl);
};
String.prototype.sanitize = function(){
	var tmp = this;
	var r=function(code, keys){
		if(!keys)keys='gi';
		return new RegExp(String.fromCharCode(code), keys);
	};
	var _f = [r(286),r(220),r(350),r(214),r(199),r(304),r(305, 'g'),r(32),r(45),/\W/g],_r = ['g','u','s','o','c','i','i','_','_', ''];
	for (var i=0,l=_f.length;i<l;i++)
	    tmp = tmp.replace(_f[i],_r[i]);
	return tmp.toLowerCase();
};
/*String.prototype.format = function(format){
	var str = this;
    for(var i=0,len=arguments.length;i<len;i++)
    {
        var re = new RegExp('\\{' + (i) + '\\}','gm');
        str = str.replace(re, arguments[i]);
    }
    return str;
};*/

mj.apply(String, {

    /**
     * Parametre olarak gönderilen string içinden ' ve \ karakterlerini temizler
     * @param {String} string Temizlenecek edilecek string
     * @return {String} Temizlenmiş edilmiş string
     * @static
     */
    escape : function(string) {
        return string.replace(/('|\\)/g, "\\$1");
    },

    leftPad : function (val, size, ch) {
        var result = new String(val);
        if(ch === null || ch === undefined || ch === '') {
            ch = " ";
        }
        while (result.length < size) {
            result = ch + result;
        }
        return result;
    },

    format : function(format){
        var args = Array.prototype.slice.call(arguments, 1);
        return format.replace(/\{(\d+)\}/g, function(m, i){
            return args[i];
        });
    }
});
// formatDate :
// a PHP date like function, for formatting date strings
// authored by Svend Tofte <www.svendtofte.com>
// the code is in the public domain
//
// see http://www.svendtofte.com/code/date_format/
// and http://www.php.net/date
//
// thanks to 
//  - Daniel Berlin <mail@daniel-berlin.de>,
//    major overhaul and improvements
//  - Matt Bannon,
//    correcting some stupid bugs in my days-in-the-months list!
//
// input : format string
// time : epoch time (seconds, and optional)
//
// if time is not passed, formatting is based on 
// the current "this" date object's set time.
//
// supported switches are
// a, A, B, c, d, D, F, g, G, h, H, i, I (uppercase i), j, l (lowecase L), 
// L, m, M, n, N, O, P, r, s, S, t, U, w, W, y, Y, z, Z
// 
// unsupported (as compared to date in PHP 5.1.3)
// T, e, o
$(function(){
	Date.strings = {
		daysLong : [mj.lng.glb.dayLSunday,mj.lng.glb.dayLMonday,mj.lng.glb.dayLTuesday,mj.lng.glb.dayLWednesday,mj.lng.glb.dayLThursday,mj.lng.glb.dayLFriday,mj.lng.glb.dayLSaturday],
		daysShort : [mj.lng.glb.daySSunday,mj.lng.glb.daySMonday,mj.lng.glb.daySTuesday,mj.lng.glb.daySWednesday,mj.lng.glb.daySThursday,mj.lng.glb.daySFriday,mj.lng.glb.daySSaturday],
		monthsShort : [mj.lng.glb.monthSJanuary, mj.lng.glb.monthSFebruary, mj.lng.glb.monthSMarch, mj.lng.glb.monthSApril, mj.lng.glb.monthSMay, mj.lng.glb.monthSJune, mj.lng.glb.monthSJuly, mj.lng.glb.monthSAugust, mj.lng.glb.monthSSeptember, mj.lng.glb.monthSOctober, mj.lng.glb.monthSNovember, mj.lng.glb.monthSDecember],
		monthsLong : [mj.lng.glb.monthLJanuary, mj.lng.glb.monthLFebruary, mj.lng.glb.monthLMarch, mj.lng.glb.monthLApril, mj.lng.glb.monthLMay, mj.lng.glb.monthLJune, mj.lng.glb.monthLJuly, mj.lng.glb.monthLAugust, mj.lng.glb.monthLSeptember, mj.lng.glb.monthLOctober, mj.lng.glb.monthLNovember, mj.lng.glb.monthLDecember]
	};
});
Date.prototype.formatDate = function (input,time) {
	
    var switches = { // switches object
        
        a : function () {
            // Lowercase Ante meridiem and Post meridiem
            return date.getHours() > 11? "pm" : "am";
        },
        
        A : function () {
            // Uppercase Ante meridiem and Post meridiem
            return (this.a().toUpperCase ());
        },
    
        B : function (){
            // Swatch internet time. code simply grabbed from ppk,
            // since I was feeling lazy:
            // http://www.xs4all.nl/~ppk/js/beat.html
            var off = (date.getTimezoneOffset() + 60)*60;
            var theSeconds = (date.getHours() * 3600) + 
                             (date.getMinutes() * 60) + 
                              date.getSeconds() + off;
            var beat = Math.floor(theSeconds/86.4);
            if (beat > 1000) beat -= 1000;
            if (beat < 0) beat += 1000;
            if ((String(beat)).length == 1) beat = "00"+beat;
            if ((String(beat)).length == 2) beat = "0"+beat;
            return beat;
        },
        
        c : function () {
            // ISO 8601 date (e.g.: "2004-02-12T15:19:21+00:00"), as per
            // http://www.cl.cam.ac.uk/~mgk25/iso-time.html
            return (this.Y() + "-" + this.m() + "-" + this.d() + "T" + 
                    this.h() + ":" + this.i() + ":" + this.s() + this.P());
        },
        
        d : function () {
            // Day of the month, 2 digits with leading zeros
            var j = String(this.j());
            return (j.length == 1 ? "0"+j : j);
        },
        
        D : function () {
		    return Date.strings.daysShort[self.getDay()];
        },
        
        F : function () {
            // A full textual representation of a month
            return Date.strings.monthsLong[date.getMonth()];
        },
        
        g : function () {
            // 12-hour format of an hour without leading zeros
            return date.getHours() > 12? date.getHours()-12 : date.getHours();
        },
        
        G : function () {
            // 24-hour format of an hour without leading zeros
            return date.getHours();
        },
        
        h : function () {
            // 12-hour format of an hour with leading zeros
            var g = String(this.g());
            return (g.length == 1 ? "0"+g : g);
        },
        
        H : function () {
            // 24-hour format of an hour with leading zeros
            var G = String(this.G());
            return (G.length == 1 ? "0"+G : G);
        },
        
        i : function () {
            // Minutes with leading zeros
            var min = String (date.getMinutes ());
            return (min.length == 1 ? "0" + min : min);
        },
        
        I : function () {
            // Whether or not the date is in daylight saving time (DST)
            // note that this has no bearing in actual DST mechanics,
            // and is just a pure guess. buyer beware.
            var noDST = new Date ("January 1 " + this.Y() + " 00:00:00");
            return (noDST.getTimezoneOffset () == 
                    date.getTimezoneOffset () ? 0 : 1);
        },
        
        j : function () {
            // Day of the month without leading zeros
            return date.getDate();
        },
        
        l : function () {
		    return Date.strings.daysLong[self.getDay()];
        },
        
        L : function () {
            // leap year or not. 1 if leap year, 0 if not.
            // the logic should match iso's 8601 standard.
            // http://www.uic.edu/depts/accc/software/isodates/leapyear.html
            var Y = this.Y();
            if (         
                (Y % 4 == 0 && Y % 100 != 0) ||
                (Y % 4 == 0 && Y % 100 == 0 && Y % 400 == 0)
                ) {
                return 1;
            } else {
                return 0;
            }
        },
        
        m : function () {
            // Numeric representation of a month, with leading zeros
            var n = String(this.n());
            return (n.length == 1 ? "0"+n : n);
        },
        
        M : function () {
            // A short textual representation of a month, three letters
            return Date.strings.monthsShort[date.getMonth()];
        },
        
        n : function () {
            // Numeric representation of a month, without leading zeros
            return date.getMonth()+1;
        },
        
        N : function () {
            // ISO-8601 numeric representation of the day of the week
            var w = this.w();
            return (w == 0 ? 7 : w);
        },
        
        O : function () {
            // Difference to Greenwich time (GMT) in hours
            var os = Math.abs(date.getTimezoneOffset());
            var h = String(Math.floor(os/60));
            var m = String(os%60);
            h.length == 1? h = "0"+h:1;
            m.length == 1? m = "0"+m:1;
            return date.getTimezoneOffset() < 0 ? "+"+h+m : "-"+h+m;
        },
        
        P : function () {
            // Difference to GMT, with colon between hours and minutes
            var O = this.O();
            return (O.substr(0, 3) + ":" + O.substr(3, 2));
        },      
        
        r : function () {
            // RFC 822 formatted date
            var r; // result
            //  Thu         ,     21               Dec              2000
            r = this.D() + ", " + this.d() + " " + this.M() + " " + this.Y() +
            //    16          :    01          :    07               0200
            " " + this.H() + ":" + this.i() + ":" + this.s() + " " + this.O();
            return r;
        },

        s : function () {
            // Seconds, with leading zeros
            var sec = String (date.getSeconds ());
            return (sec.length == 1 ? "0" + sec : sec);
        },        
        
        S : function () {
            // English ordinal suffix for the day of the month, 2 characters
            switch (date.getDate ()) {
                case  1: return ("st"); 
                case  2: return ("nd"); 
                case  3: return ("rd");
                case 21: return ("st"); 
                case 22: return ("nd"); 
                case 23: return ("rd");
                case 31: return ("st");
                default: return ("th");
            }
        },
        
        t : function () {
            // thanks to Matt Bannon for some much needed code-fixes here!
            var daysinmonths = [null,31,28,31,30,31,30,31,31,30,31,30,31];
            if (this.L()==1 && this.n()==2) return 29; // ~leap day
            return daysinmonths[this.n()];
        },
        
        U : function () {
            // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
            return Math.round(date.getTime()/1000);
        },

        w : function () {
            // Numeric representation of the day of the week
            return date.getDay();
        },
        
        W : function () {
            // Weeknumber, as per ISO specification:
            // http://www.cl.cam.ac.uk/~mgk25/iso-time.html
        
            var DoW = this.N ();
            var DoY = this.z ();

            // If the day is 3 days before New Year's Eve and is Thursday or earlier,
            // it's week 1 of next year.
            var daysToNY = 364 + this.L () - DoY;
            if (daysToNY <= 2 && DoW <= (3 - daysToNY)) {
                return 1;
            }

            // If the day is within 3 days after New Year's Eve and is Friday or later,
            // it belongs to the old year.
            if (DoY <= 2 && DoW >= 5) {
                return new Date (this.Y () - 1, 11, 31).formatDate ("W");
            }
            
            var nyDoW = new Date (this.Y (), 0, 1).getDay ();
            nyDoW = nyDoW != 0 ? nyDoW - 1 : 6;

            if (nyDoW <= 3) { // First day of the year is a Thursday or earlier
                return (1 + Math.floor ((DoY + nyDoW) / 7));
            } else {  // First day of the year is a Friday or later
                return (1 + Math.floor ((DoY - (7 - nyDoW)) / 7));
            }
        },
        
        y : function () {
            // A two-digit representation of a year
            var y = String(this.Y());
            return y.substring(y.length-2,y.length);
        },        
        
        Y : function () {
            // A full numeric representation of a year, 4 digits
    
            // we first check, if getFullYear is supported. if it
            // is, we just use that. ppks code is nice, but wont
            // work with dates outside 1900-2038, or something like that
            if (date.getFullYear) {
                var newDate = new Date("January 1 2001 00:00:00 +0000");
                var x = newDate .getFullYear();
                if (x == 2001) {              
                    // i trust the method now
                    return date.getFullYear();
                }
            }
            // else, do this:
            // codes thanks to ppk:
            // http://www.xs4all.nl/~ppk/js/introdate.html
            var x = date.getYear();
            var y = x % 100;
            y += (y < 38) ? 2000 : 1900;
            return y;
        },

        
        z : function () {
            // The day of the year, zero indexed! 0 through 366
            var t = new Date("January 1 " + this.Y() + " 00:00:00");
            var diff = date.getTime() - t.getTime();
            return Math.floor(diff/1000/60/60/24);
        },

        Z : function () {
            // Timezone offset in seconds
            return (date.getTimezoneOffset () * -60);
        }        
    
    }

    function getSwitch(str) {
        if (switches[str] != undefined) {
            return switches[str]();
        } else {
            return str;
        }
    }

    var date;
    if (time) {
        var date = new Date (time);
    } else {
        var date = this;
    }

    var formatString = input.split("");
    var i = 0;
    while (i < formatString.length) {
        if (formatString[i] == "\\") {
            // this is our way of allowing users to escape stuff
            formatString.splice(i,1);
        } else {
            formatString[i] = getSwitch(formatString[i]);
        }
        i++;
    }
    
    return formatString.join("");
}


// Some (not all) predefined format strings from PHP 5.1.1, which 
// offer standard date representations.
// See: http://www.php.net/manual/en/ref.datetime.php#datetime.constants
//

// Atom      "2005-08-15T15:52:01+00:00"
Date.DATE_ATOM    = "Y-m-d\\TH:i:sP";
// ISO-8601  "2005-08-15T15:52:01+0000"
Date.DATE_ISO8601 = "Y-m-d\\TH:i:sO";
// RFC 2822  "Mon, 15 Aug 2005 15:52:01 +0000"
Date.DATE_RFC2822 = "D, d M Y H:i:s O";
// W3C       "2005-08-15T15:52:01+00:00"
Date.DATE_W3C     = "Y-m-d\\TH:i:sP";
Date.firstDayOfWeek=1;
Date.prototype.getDayOld=Date.prototype.getDay;
Date.prototype.getDay=function(){
	return (this.getDayOld()-Date.firstDayOfWeek+7)%7;
};
Date.prototype.addDay=function(days){
	this.setTime(this.getTime()+86400000*days);
};
Date.prototype.getLastDay = function(date){
	var _tmp = new Date(date?date:this), dd = new Date(_tmp.getYear(),_tmp.getMonth(),0);
	return dd.getDate();
};

Number.prototype.toRadian = function(){
	return (Math.PI/180)*this;
};
Number.prototype.addPrefix = function(p,l){
	var val = this.toString();
	return val.addPrefix(p,l);
};
/** 
 * @fileoverview Template nesnesi.
 * @hazırlayan kk yazılım info@mj.com
 * @sürüm 0.1 Beta 15.10.2007
 */
/**
 * Template nesnesi.
 * Örnek kullanımı aşağıdaki gibidir:
 * @example
	var a = eval('[{"title":"Normal Tab","html":"My content was added during construction.","iconCls":"tabs","closable":true,"id":"mj-tab-1"},{"title":"Ajax Tab 1","autoLoad":"ajax1.htm","closable":true,"iconCls":"tabs","refresh":false,"id":"mj-tab-2","loaded":false},{"title":"Ajax Tab 2","autoLoad":{"url":"ajax2.htm","params":"foo=bar&wtf=1"},"refresh":true,"closable":true,"id":"mj-tab-3","loaded":false},{"title":"Disabled Tab","disabled":true,"html":"Cant see me cause Im disabled","closable":true,"id":"mj-tab-4"}]');
	var tmp;
	var template = ['id:{id}', 'text:{title}', 'closable:{closable}'];
	var tt = new mj.template(template);
	for(b in a){
		tmp=a[b];
		if(typeof tmp!='function'){
			var h2=tt.apply(tmp);
			mj.log(h2);
		}
	}
 * @class
 * @name mj.template
 * @param {String/Array} html array ya da string olabilen html template'i.
 */
mj.template = function(html){
    if(html instanceof Array){
        html = html.join(" ");
    }
    this.html = html;
};
mj.template.prototype = {
	/**
	 * template stringinin replace'i için gerekli regularExpression.
	 * @name re
	 * @function
	 * @type {Function}
	 */
	re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
	/**
	 * template stringini <i>obj</i> nesnesi içindeki değerlerle replace eden fonksiyon.
	 * @name apply
	 * @function
	 * @type {Function}
	 * @param {Object} obj template üzerinde değiştirilecek değişkenlerin değerlerini içeren obje.
	 * @return {String} derlenmiş html string.
	 */
	apply : function(obj){
		var html=this.html;
		var token=this.re.exec(html);
		while(token!=null){
			html=html.replace(token[0],obj[token[1]]);
			this.re.lastIndex = 0;
			token=this.re.exec(html);
		}
		return html;
	}
};
function setCookie( name, value, expires, path, domain, secure ) 
{
	// set time, it's in milliseconds
	var today = new Date();
	today.setTime( today.getTime() );

	/*
	if the expires variable is set, make the correct 
	expires time, the current script below will set 
	it for x number of days, to make it for hours, 
	delete * 24, for minutes, delete * 60 * 24
	*/
	if ( expires )
	{
	expires = expires * 1000 * 60 * 60 * 24;
	}
	var expires_date = new Date( today.getTime() + (expires) );

	document.cookie = name + "=" +escape( value ) +
	( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) + 
	( ( path ) ? ";path=" + path : "" ) + 
	( ( domain ) ? ";domain=" + domain : "" ) +
	( ( secure ) ? ";secure" : "" );
}
// this fixes an issue with the old method, ambiguous values 
// with this test document.cookie.indexOf( name + "=" );
function getCookie( check_name ) {
	// first we'll split this cookie up into name/value pairs
	// note: document.cookie only returns name=value, not the other components
	var a_all_cookies = document.cookie.split( ';' );
	var a_temp_cookie = '';
	var cookie_name = '';
	var cookie_value = '';
	var b_cookie_found = false; // set boolean t/f default f
	
	for ( i = 0; i < a_all_cookies.length; i++ )
	{
		// now we'll split apart each name=value pair
		a_temp_cookie = a_all_cookies[i].split( '=' );
		
		
		// and trim left/right whitespace while we're at it
		cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
	
		// if the extracted name matches passed check_name
		if ( cookie_name == check_name )
		{
			b_cookie_found = true;
			// we need to handle case where cookie has no value but exists (no = sign, that is):
			if ( a_temp_cookie.length > 1 )
			{
				cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
			}
			// note that in cases where cookie is initialized but no value, null is returned
			return cookie_value;
			break;
		}
		a_temp_cookie = null;
		cookie_name = '';
	}
	if ( !b_cookie_found )
	{
		return null;
	}
}
function getCookieArray( check_name ) {
	var ret=[],cookies = document.cookie.split( ';' );
	for ( i = 0; i < cookies.length; i++ )
	{
		var cookie = cookies[i].split( '=' );
		if(cookie[0].indexOf(check_name)>-1)
			ret.push(cookie[0]);
	}
	return ret;
}		
// this deletes the cookie when called
function deleteCookie( name, path, domain ) {
	if ( getCookie( name ) ) document.cookie = name + "=" +
	( ( path ) ? ";path=" + path : "") +
	( ( domain ) ? ";domain=" + domain : "" ) +
	";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}
/** 
* @fileoverview Tüm bileşenlerin ortak kullandıkları özellikleri barındıran temel sınıf
* @hazırlayan kk
* @sürüm 0.1
*/

/**
* Tüm bileşenlerde kullanılacak en temel sınıf tanımlaması. Bileşenlerde sık kullanılacak özellikler bu sınıfa eklenmelidir.
* @class
* @name mj.component
* @param {String/Object} config String ya da Object tipinde olabilir. 
<i>config</i> parametresi ile gönderilen nesnenin tüm özellikleri, yeni oluşturulan nesneye atanır. 
<pre><code>
var newObject = new mj.component({width:100, height:50});
</pre></code>
Üstteki şekilde oluşturulan newObject nesnesinin width ve height özellikleri mevcuttur. 
String olarak verildiğinde <a href="#defaultConfigStr">defaultConfigStr</a> ile belirtilmiş olan alana ataması yapılır.
*/
mj.component = function(config){
	if(typeof config=='string'){
		var c = {};
		c[this.defaultConfigStr] = config;
		config = c;
	}
	if(config && config.renderTo)
		config.renderTo = $(config.renderTo);
	if(config && config.store && !config.store.componentClass)
		config.store = new mj.store({data:config.store});
	mj.apply(this, config);
	this.config=config;
	this.on('afterdestroy', this._afterDestroy, this);
	this.init();
};
mj.component.prototype = {
	/**
	 * Ön tanımlı bileşen sınıfı bilgisi. Bileşen tanımlaması ile ataması yapılır ve çalışma esnasında değiştirilmemelidir. 
	 Fonksiyonlara parametre olarak gönderilen nesnelerin hangi sınıftan türetildiğinin kolay bir şekilde anlaşılabilmesi için eklenmiştir. 
	 Örneğin bu sınıftan oluşturulan nesnelerin <i>componentClass</i> alanında 'mj.component' değeri vardır.
	 * @name componentClass
	 * @type {String}
	 * @memberOf  mj.component
	 */
	componentClass : 'mj.component',
	/**
	 * Config parametresinin string tipinde olması durumunda kullanılacak olan ön tanımlı değer. 
	 Standart olarak 'renderTo' değeri atanmıştır. Bu durumda alttaki iki tanımlama da aynı tipte nesneler oluşturmaktadır.
<pre><code>
var newObject1 = new mj.component(document.body);
var newObject2 = new mj.component({renderTo : document.body});
</pre></code>
	 * @name defaultConfigStr
	 * @type {String}
	 * @memberOf  mj.component
	 */
	defaultConfigStr : 'renderTo',
	/**
	 * Nesnenin hazır olup olmadığını gösterir. <a href="#init">bkz : init()</a>
	 * @name ready
	 * @type {boolean}
	 * @memberOf  mj.component
	 */
	ready : false,
	/**
	 * Bir nesne oluşturulduktan sonra, o nesnenin görsel içeriğinin oluşturulmasının gerçekleştirileceği fonksiyondur. 
	 İşlem tamamlandıktan sonra <i>init</i> olayı tetiklenir.
	 * @name init
	 * @function
	 * @type {Function}
	 * @memberOf  mj.component
	 */
	init : function(){
		this.ready = true;
		this.trigger('init', this);
	},
	addEvent : function(event){
		if(!this.events)
            this.events = {};
		if(!this.events[event])
			this.events[event] = {listeners : []};
	},
	/**
	 * Nesnenin bir olayına(event) dinleyici fonksiyon atamak için kullanılır. Olay yönetiminde nesnelerde dinlenecek olayın tanımlı olma şartı aranmaz, 
	 gerekli atama yapılır, <i><a href="#trigger">trigger</a></i> metoduyla tetiklenen olaylar sonrasında dinleyiciler çalıştırılır.
	 * @name on
	 * @function
	 * @type {Function}
	 * @memberOf  mj.component
	 * @param {String} event Dinlenecek olan olayın adı
	 * @param {Handle} fn Olay tetiklendiğinde çağırılacak olan fonksiyon
	 * @param {Scope} [scope] Çağırılan fonksiyonda kullanılacak olan referans nesne(this).
	 * @memberOf  mj.component
	 */
	on : function(event, fn, scope){
		this.addEvent(event);
		this.events[event].listeners.push({fn:fn, scope:scope ? scope : this});
	},
	/**
	 * Nesnenin olayını dinleyen bir fonksiyonun bağlantısının koparılması için kullanılır.
	 * @name mon
	 * @function
	 * @type {Function}
	 * @param {String} event Dinlenen olayın adı
	 * @param {Handle} fn Bağlantısı silinecek olan fonksiyon
	 * @return {Boolean} Dinleyici fonksiyonun bulunup bulunamadığı bilgisi
	 * @memberOf  mj.component
	 */
	mon : function(event, fn){
		var e = this.events[event];
		if(e && e.listeners){
			var i = mj.getIndex(e.listeners, 'fn', fn);
			if(i>-1)
				e.listeners[i].fn = function(){};
		}
		return i>-1;
	},
	onOnce : function(event, fn, scope){
		this.mon(event, fn);
		this.on(event, fn, scope);
	},
	/**
	 * Nesnenin bir olayını(event) tetiklemek için kullanılır. İlk parametre tetiklenecek olayın adı, sonraki parametreler ise opsiyonel olmak üzere
	 kullanıcıya bırakılmıştır. Bu parametreler dinleyici fonksiyonlara gönderilecek olan değerlerdir. Dinleyicilerden <i>false</i> gönderen olması
	 durumunda sonraki dinleyiciler tetiklenmez.
	* @example
var newObject = new mj.component();
var listenerFunction = function(name){
	alert(name);
};
newObject.on('namechange', listenerFunction);

newObject.name = 'New Name';
newObject.trigger('namechange', newObject.name);
	 * @name trigger
	 * @function
	 * @type {Function}
	 * @param {String} event Tetiklenecek olan olayın adı
	 * @return {Boolean} Dinleyici fonksiyonların tümünün çalıştırılması durumunda <i>true</i>, aksi durumda <i>false</i>
	 * @memberOf  mj.component
	 */
	trigger : function(){//parametreler : (, paramA, paramB, ...)
		var args = Array.prototype.slice.call(arguments, 0);
		//console.log(this.componentClass+'.'+args[0]);
		this.addEvent(args[0]);
		var e = this.events[args[0]], l = e.listeners;
		if(e && l){
			return $(l).eachR(function(){
				return this.fn.apply(this.scope, args.slice(1));
			});
		}
	},
	_afterDestroy : function(){
		for(var x in this)
			this[x] = null;
	},
	addRelated : function(el){
		if(!this.relatedItems)
			this.relatedItems = [];
		this.relatedItems.push(el);
	},
	destroy : function(){
		var t = this,_i;
		t.trigger('beforedestroy', t);
		t.destroyEl = t.destroyEl ? t.destroyEl : (t.renderTo ? t.renderTo : t.el);
		if(t.destroyEl){
			if(typeof t.destroyEl.remove != 'function')
				t.destroyEl = $(t.destroyEl);
			t.destroyEl.remove();
		}
		if(t.relatedItems)
			for(var i=0,l=t.relatedItems.length;i<l;i++)
				if(_i = t.relatedItems[i])
					(_i.componentClass && typeof _i.destroy == 'function') ? _i.destroy() : (typeof _i.remove == 'function' ? _i : $(_i)).remove();
		t.trigger('afterdestroy', t);
	}
};
/** 
* @fileoverview Tüm bileşenlerin ortak kullandıkları store sınıfı.
* @hazırlayan kk
* @sürüm 0.1
*/
/**
* Veri kaynağı olarak kullanılacak olan sınıf. Sunucudan gelen JSON ifadesini işleyerek <i>data</i> özelliğine yazar.
* @class
* @name mj.store
* @extends mj.component
* @param {String/Object} config Sunucudan veriyi alabilmek için gerekli olan parametreleri içerir. 
* String olarak verilmesi durumunda gelen değeri <i>url</i> olarak değerlendirir.
* @config {String} url İstek yapılacak olan sayfanın adresi
* @config {Object} params İstek yapılacak olan sayfaya gönderilecek parametreler. Gönderim metodu olarak POST kullanılır
*/
mj.store = function(config){
	mj.store.superclass.constructor.call(this, config);
};
mj.store.prototype = {
	/**
	 * Ön tanımlı bileşen sınıfı bilgisi. Bileşen tanımlaması ile ataması yapılır ve çalışma esnasında değiştirilmemelidir. 
	 Fonksiyonlara parametre olarak gönderilen nesnelerin hangi sınıftan türetildiğinin kolay bir şekilde anlaşılabilmesi için eklenmiştir. 
	 Örneğin bu sınıftan oluşturulan nesnelerin <i>componentClass</i> alanında 'mj.store' değeri vardır.
	 * @name componentClass
	 * @type {String}
	 * @memberOf  mj.store
	 */
	componentClass : 'mj.store',
	defaultConfigStr : 'url',
	showLoader : true,
	localSort : true,
	/**
	 * Sunucudan gerekli isteği yaparak gelen sonucu <i>data</i> özelliğine yazar. 
	 * İşlem tamamlandığında <i>load</i> olayı tetiklenir.
	 * @name load
	 * @function
	 * @type {Function}
	 * @memberOf  mj.store
	 */
	load : function(){
		var t = this;
		t.params = mj.applyIf(t.params,{query:true});
		this.params.toJSONString=null;
		var success=typeof t.success=='function'?t.success:t.callback;
		var failure=typeof t.failure=='function'?t.failure:function(){};
		t.trigger('beforeload', t);
		var render = function(jsonData,cmRenderers){
			for(var d in jsonData){
				var data=jsonData[d];
				if(typeof data[d]!='function')
					for(var r in cmRenderers){
						var renderer=cmRenderers[r];
						if(r!='toJSONString')
							if(typeof data[r] != 'undefined'){
								data[r+'_source'] = data[r];
								if(typeof renderer == 'function')
									data[r]=renderer(data[r]);
								else
									data[r]=renderer;
							}
							else{
								data[r]='';
								data[r+'_source']='';
							}
					}
					if(typeof data.data!='undefined')
						render(data.data,cmRenderers);
			}
		};
		if(t.url){
			t.params.jsoncallback='?';
			t.params.isStore='true';
			$.getJSON(t.url,t.params,function(json){
				if(json && (typeof json.totalProperty != 'undefined' || typeof json.success != 'undefined')){
					t.recordCount = json.totalProperty;
					if(t.renderers)
						render(json.records,t.renderers);
					if(typeof json.records != 'undefined'){
						t.data = json.records;
						t.dm = [];
						if(t.data.length>0){
							for(var cl in t.data[0])
								if(typeof t.data[0][cl]!='function') 
									t.dm.push(cl);
						}
					}
					if(typeof json.detail != 'undefined'){
						t.detail = [];
						for(var i in json.detail){
							if(typeof json.detail[i] != 'function'){
								var cItem = json.detail[i];
								cItem.dm = [];
								if(cItem.records.length>0){
									for(var cl in cItem.records[0])
										if(typeof cItem.records[0][cl]!='function') 
											cItem.dm.push(cl);
								}
								cItem.data = cItem.records;
								delete cItem.records;
								t.detail.push(json.detail[i]);
							}
						}
					}
					if(json.error&&$('.mj-error-message').length==0)
						new mj.message({
							title : 'Bilgi',
							msg : json.msg,
							cls : 'mj-error-message'
						}); 
					t.trigger('load', t, json);
					t.loaded = true;
					if(success)
						success.call(t.scope||t,json,arguments);
				}else if(failure){
					failure.call(t.scope||t, json, arguments);
				}
			});
		}else{
			if(t.showLoader===true)
				mj.loaderShow();
			if(t.renderers)
				render(t.data, t.renderers);
			t.recordCount = t.data && t.data.length ? t.data.length : 0;
			t.trigger('load', t);
			t.loaded = true;
			if(t.showLoader===true)
				mj.loaderHide();
		}
	},
	/**
	 * Store nesnesinin verisinin gruplanmasında kullanılır
	 * @name groupItemsData
	 * @function
	 * @type {Function}
	 * @memberOf  mj.store
	 * @param {String} dataIndex Gruplanacak olan alan bilgisi
	 * @return {Object} Gruplanmış veriyi içeren bir nesne
	 */
	groupItemsData : function(dataIndex){
		var x = {};
		var item;
		for(var i=0,len=mj.oLength(this.data);i<len;i++){
			item = this.data[i][dataIndex];
			if(!x[item]){
				x[item]=[];
			}	
			x[item].push(this.data[i]);
		}
		return x;
	},
	/**
	 * Gruplamanın yapılacağı alanı alır ve veriyi groupItemsData fonksiyonu ile gruplayıp <i>gData</i>ya yazar.
	 * @name groupBy
	 * @function
	 * @type {Function}
	 * @memberOf  mj.store
	 * @param {String} dataIndex Gruplanacak olan alan bilgisi
	 */
	groupBy : function(dataIndex){
		this.gData = this.gData||{};
		this.gData[dataIndex] = this.groupItemsData(dataIndex);
	},
	/**
	 * Gruplamanın yapılacağı alanı veriyi gruplayarak birbirinden farklı olan elemanları bir diziye yazar.
	 * @name groupItems
	 * @function
	 * @type {Function}
	 * @memberOf  mj.store
	 * @param {String} dataIndex Gruplanacak olan alan bilgisi
	 * @return {Array} gruplanmış veriyi içeren dizi
	 */
	groupItems : function(dataIndex){
		var x = [];
		var item;
		for(var i=0,len=mj.oLength(this.data);i<len;i++){
			item = this.data[i][dataIndex];
			if(x.indexOf(item)===-1)
				x.push(item);
		}
		return x;
	},
	/**
	 * Parametre olarak gönderilen <i>dataIndex</i>'e sahip alanların değerlerini tüm node'lardan bulup <i>this.collected</i>'a yazar.
	 * @name collect
	 * @function
	 * @type {Function}
	 * @param {Object} jsonData Node bilgisini içeren JSON objesi
	 * @param {String} dataIndex Bulunacak dataIndex
	 * @memberOf  mj.store
	 */
	collect : function(jsonData, dataIndex){
		if(!this.collected)
			this.collected = [];
		for(var d in jsonData){
			var data=jsonData[d];
			if(typeof data[d]!='function'){
				if(typeof data[dataIndex]!='undefined')
					this.collected.push(data[dataIndex]);
				if(typeof data.data!='undefined')
					this.collect(data.data,dataIndex);
			}
		}
	},
	/**
	 * Parametre olarak gönderilen <i>dataIndex</i> verilerinden <i>val</i> ile benzerlik gösterenleri data'ya yazar,
	 orjinal data ise oData olarak saklanır.
	 * @name filter
	 * @function
	 * @type {Function}
	 * @param {Object} dataIndex Node bilgisini içeren JSON objesi
	 * @param {String} val Bulunacak dataIndex
	 * @memberOf  mj.store
	 */
	filter : function(dataIndex, val, dontrefresh, contains){
		this._isFiltering = true;
		var c=0;
		if(!this.oData){
			this.oData = [];
			for(var i in this.data)
				if(typeof this.data[i]!='function')
					this.oData.push(this.data[i]);
		}
		if(!dontrefresh)
			this.clearFilter();
		var filterData = this.data;
		this.data = [];
		for(var j in filterData)
			if(typeof filterData[j]!='function'&&typeof filterData[j][dataIndex]!='undefined')
				if(filterData[j][dataIndex] instanceof Date){
					if(!val instanceof Date){
						var g=1,a=1,y=1980,md=new Date();
						md.setDate(g);
						md.setMonth(a);
						md.setYear(y);
						val = val.split('/');
						if(val[0])
							md.setDate(val[0]);
						if(val[1])
							md.setMonth(val[1]);
						if(val[2])
							md.setYear(val[2]);
						val=md;
					}
					if(filterData[j][dataIndex]>=val){
						this.data.push(filterData[j]);
						c++;
					}
				}else if(contains && filterData[j][dataIndex].toString().toLowerCase().indexOf(val.toString())>-1){
					this.data.push(filterData[j]);
					c++;
				}else
					if(filterData[j][dataIndex].toString().toLowerCase().substring(0,val.toString().length)===val.toString().toLowerCase()){
						this.data.push(filterData[j]);
						c++;
					}
		this.recordCount=c;
		this.trigger('beforeload', this);
		this.trigger('load', this);
		this._isFiltering = false;
		return this;
	},
	clearFilter : function(){
		if(this.oData)
			this.data = this.oData;
	},
	sort : function(key,dir){
		dir = dir || 'ASC';
		if(this.data instanceof Array){
			var fn = function(r1, r2){
				r1=String(r1).toLowerCase();
				r2=String(r2).toLowerCase();
				return r1 > r2 ? 1 : (r1 < r2 ? -1 : 0);
			};
			this.data._sort(key,dir,fn);
		}
		else
			return false;
	},
	init : function(){
		var t = this;
		t.on('load', function(){
			t.isEmpty = !t.data || t.data.length == 0;
		});
		mj.store.superclass.init.call(this);
	}
};
mj.extend(mj.store, mj.component);
/** 
* @fileoverview Verinin sayfalara bölünerek listelenebilmesini sağlayan sınıf.
* @hazırlayan kk
* @sürüm 0.1
*/
/**
* Verinin sayfalar halinde sunucudan alınabilmesini sağlar.
* @class
* @name mj.pager
* @extends mj.component
* @param {Object} config Sunucudan veriyi sayfalar halinde alabilmek için gerekli olan parametreleri içerir. 
* @config {String} pos Page bar nesnesinin container içindeki konumunu belirtir.'bottom'/'top' olabilir.(Ön tanımlı değeri : 'bottom')
* @config {Integer} start Verinin kaçıncı sayfadan itibaren alınacağın belirtir.
* @config {Integer} limit Sayfa başına listelenecek kayıt sayısını belirtir.
* @config {Boolean} pageInfo Page Bar'ın sağ tarafında toplam kayıt sayısı ve gösterilen kayıtlar ile ilgili bilgi alanının gösterim durumunu 
belirtir.False olması halinde bu alan gösterilmeyecektir.(Ön tanımlı değeri : true)
*/
mj.pager = function(config){
	config = config || {};
	this.params = {limit : 25, start : 0, current:1, pos:'bottom'};
	if(config.limit < 1)
		config.limit = 1;
	if(config.start < 0)
		config.start = 0;
	mj.apply(this.params,config);
	this.beforePageText = mj.lng.objects.pager.beforePageText;
	mj.pager.superclass.constructor.call(this, this.params);
};
mj.pager.prototype = {	
	/**
	 * Ön tanımlı bileşen sınıfı bilgisi. Bileşen tanımlaması ile ataması yapılır ve çalışma esnasında değiştirilmemelidir. 
	 Fonksiyonlara parametre olarak gönderilen nesnelerin hangi sınıftan türetildiğinin kolay bir şekilde anlaşılabilmesi için eklenmiştir. 
	 Örneğin bu sınıftan oluşturulan nesnelerin <i>componentClass</i> alanında 'mj.pager' değeri vardır.
	 * @name componentClass
	 * @type {String}
	 * @memberOf  mj.pager
	 */
	componentClass : 'mj.pager',
	pos : 'bottom',
	afterPageText : '{0}',
	displayMsg : "{0} - {1} / {2} ",
	defaultButtons : true,
	elements : {
		first : true,
		prev : true,
		next : true,
		last : true,
		refresh : true,
		pages : true
	},
	pageInfo : true,
	/**
	 * Verinin bulunduğu sayfa için tekrar yüklenmesini sağlar.
	 * @name refreshPageBar
	 * @function
	 * @type {Function}
	 * @memberOf  mj.pager
	 */
	refreshPageBar : function(){
		var tb = this.tbar;
		if(this.defaultButtons&&this.elements.pages){
			tb.input.val(this.params.current);
			tb.pageTotal.text('/ '+this.getPageCount());
		}
		if(this.pageInfo)
			tb.pageInfo.text(String.format(this.displayMsg, this.params.start+1, this.params.start+this.store.data.length, this.store.recordCount));
	},
	/**
	 * Page Bar nesnesinin oluşturulmasını sağlar.
	 * @name render
	 * @function
	 * @type {Function}
	 * @memberOf  mj.pager
	 * @param {Object} config Sunucudan veriyi sayfalar halinde alabilmek için gerekli olan parametreleri içerir. 
	 * @config {String} pos Page bar nesnesinin container içindeki konumunu belirtir.'bottom'/'top' olabilir.(Ön tanımlı değeri : 'bottom')
	 * @config {Integer} start Verinin kaçıncı sayfadan itibaren alınacağın belirtir.
	 * @config {Integer} limit Sayfa başına listelenecek kayıt sayısını belirtir.
	 * @config {Boolean} pageInfo Page Bar'ın sağ tarafında toplam kayıt sayısı ve gösterilen kayıtlar ile ilgili bilgi alanının gösterim durumunu 
	 belirtir.False olması halinde bu alan gösterilmeyecektir.(Ön tanımlı değeri : true)
	 */
	render : function(config){
		var cs = config.scope, cst = cs.store, pb = cs.pbar, f=false;
		mj.apply(cst.params,pb.params);
		pb.store = cst;
		if(pb.pos&&pb.pos=='top'){
			cs.pageBar = mj.NE(cs.cnt,{tag:'div', cls:'mj-paging'});
			cs.renderTo = mj.NE(cs.cnt,{tag:'div',style:'overflow:auto;height:'+(cs.cnt.height()-25)+'px;'});
		}else{
			cs.renderTo = mj.NE(cs.cnt,{tag:'div',style:'overflow:auto;height:'+((cs.cnt.height()||parseInt(cs.cnt[0].style.height))-25)+'px;'});
			cs.pageBar = mj.NE(cs.cnt,{tag:'div', cls:'mj-paging'});
		}
		pb.renderTo = cs.pageBar;			
		this.tbar ={};
		var t=this, tb = t.tbar, els = t.elements;
		tb.items = [];
		if(t.defaultButtons){
			if(els.first||els.prev||els.next||els.last)
				f=true;
			if(els.first)
				tb.items.push({id:'btnfirst' ,iconCls:'mj-first',alt:mj.lng.glb.first,handler:function(){t.trigger('sourcefirst',t);t.trigger('sourceload',t);t.first();}});
			if(els.prev)
				tb.items.push({id:'btnprev' ,iconCls:'mj-previous',alt:mj.lng.glb.previous,handler:function(){t.trigger('sourceprev',t);t.trigger('sourceload',t);t.prev();}});
			if(els.pages){
				tb.items.push('|');
				tb.items.push({id:'pageTotal'+this.id,html:'<div><span style="float:left;padding:5px;" unselectable="on" class="mj-page-before-text mj-unselectable">'+this.beforePageText+'</span><input type="text" size="1" value="1" class="mj-page-info" style="float:left;"></input><span style="float:left;padding:5px;" unselectable="on" class="mj-page-before-text mj-unselectable">/ '+String.format(this.afterPageText, 1)+'</span></div>'});
				tb.items.push('|');
			}
			if(els.next)
				tb.items.push({id:'btnnext' ,iconCls:'mj-next',alt:mj.lng.glb.next,handler:function(){t.trigger('sourcenext',t);t.trigger('sourceload',t);t.next();}});
			if(els.last)
				tb.items.push({id:'btnlast' ,iconCls:'mj-last',alt:mj.lng.glb.last,handler:function(){t.trigger('sourcelast',t);t.trigger('sourceload',t);t.last();}});
		}
		if(els.refresh){
			if(f)
				tb.items.push('|');	
			tb.items.push({id:'btnrefresh' ,iconCls:'mj-refresh', alt:mj.lng.glb.refresh, handler:function(){t.trigger('sourcerefresh',t);t.trigger('sourceload',t);t.refresh();}});
		}
		if(this.pageInfo)
			tb.items.push({id:'pageInfo'+this.id,html:'<div style="float:right;padding-bottom:5px;padding-top:5px;text-align:right;" unselectable="on" class="mj-page-before-text mj-unselectable"></div>'});
		tb.renderTo=this.renderTo;
		t.tbar = new mj.menu(tb);
		t.tbar.input = t.tbar._el.find('input');
		t.tbar.input.bind('change',function(){
			t.trigger('sourcefind',t);
			t.trigger('sourceload',t);
			t.go2page(this.value);
		});
		t.tbar.pageTotal = $(t.tbar._el.find('span')[1]);
		t.tbar.pageInfo = t.tbar._el.find('div:last');
		t.buttons = t.tbar.buttons;
		t.store.on('load',t.refreshPageBar,t);
	},
	/**
	 * Toplam kayıt sayısını sayfada gösterilecek kayıt sayısına göre hesaplayarak görüntülenecek sayfa sayısını bulur.
	 * @name getPageCount
	 * @function
	 * @type {Function}
	 * @memberOf  mj.pager
	 * @return {Integer} Sayfa sayısı
	 */
	getPageCount : function(){
		return Math.ceil(this.store.recordCount/this.params.limit);
	},
	/**
	 * İstenilen sayfanın görüntülenmesini sağlar. Sayfa bilgisi toplam sayfa sayısından büyük olduğu durumda son sayfayı, 
	1'den küçük olması durumunda ise ilk sayfayı görüntüler.	 
	 * @name go2page
	 * @function
	 * @type {Function}
	 * @memberOf  mj.pager
	 * @param {Integer} pageNumber Gösterilecek sayfanın numarası
	 */
	go2page : function(pageNumber){
		var pc = this.getPageCount();
		pageNumber = isNaN(parseInt(pageNumber))?1:pageNumber;
		if(pageNumber < 1)
			pageNumber = 1;
		if(pageNumber > pc)
			pageNumber = pc;
		this.params.current = pageNumber;
		this.params.start = (pageNumber-1) * this.params.limit;
		mj.apply(this.store.params,this.params);
		this.store.load();
	},
	/**
	 * İlk sayfayı görüntüler.	 
	 * @name first
	 * @function
	 * @type {Function}
	 * @memberOf  mj.pager
	 */
	first : function(){
		if(this.params.current > 1)
			this.go2page(1);
	},
	/**
	 * Önceki sayfayı görüntüler.	 
	 * @name prev
	 * @function
	 * @type {Function}
	 * @memberOf  mj.pager
	 */
	prev : function(){
		if(this.params.current > 1)
			this.go2page(--this.params.current);
	},
	/**
	 * Sonraki sayfayı görüntüler.	 
	 * @name next
	 * @function
	 * @type {Function}
	 * @memberOf  mj.pager
	 */
	next : function(){
		var pc = this.getPageCount();
		if(pc > this.params.current)
			this.go2page(++this.params.current);
	},
	/**
	 * Son sayfayı görüntüler.	 
	 * @name last
	 * @function
	 * @type {Function}
	 * @memberOf  mj.pager
	 */
	last : function(){
		var pc = this.getPageCount();
		if(pc > this.params.current)
			this.go2page(pc);
	},
	/**
	 * Store'u tekrar load eder.	 
	 * @name refresh
	 * @function
	 * @type {Function}
	 * @memberOf  mj.pager
	 */
	refresh : function(){
		this.store.trigger('sourcerefresh',this.store);
		this.store.load();
		this.store.trigger('afterrefresh',this.store);
	}
};
mj.extend(mj.pager, mj.component);
mj.dataFilter = function(config){
	mj.dataFilter.superclass.constructor.call(this, config);
};
mj.dataFilter.prototype = {
	componentClass : 'mj.dataFilter',
	width : 460,
	height : 300,
	labelWidth : 150,
	button : false,
	iconCls : 'mj-filter',
	store : false,
	fields : false,
	grid : false,//bağlı olduğu grid elementi mutlaka olmalı
	filterEvent : 'getFilteredRecords',//değiştirme'
	splitter : '$_$',//değiştirme'
	countStart : 0,
	init : function(){
		var t = this;
		if(!t.store)
			t.store = t.grid.store;
		if(!t.fields)
			t.fields = t.grid.cm;
		if(t.button)
			t.button.els.c.append(t.button.els.ci = $(mj.NE(t.button.els.c, {cls:'mj-tool-btn-center-icon '+t.iconCls})));
		t.cachedParams = {};
		mj.apply(t.cachedParams,t.store.params);
		t.win = new mj.window({
			renderTo : mj.bd,
			title : mj.lng.glb.filterRecords,
			modal : true,
			width : t.width,
			height : t.height,
			minWidth : t.width,
			minHeight : t.height,
			buttons : [
				{title: mj.lng.glb.exit, handler:function(){t.win.hide();}},
				{title: mj.lng.glb.clear, handler:function(){t.clearFilter();}},
				{title: mj.lng.glb.get, handler:function(){t.getFilteredData();}}
			]
		});
		var elements = t.getFilterElements(t.fields);
		t.form = new mj.form({
			renderTo : t.win.getBody(),
			items : elements
		});
		t.addRelated(t.win);
		t.win.addRelated(t.form);
		t.store.on('sourcerefresh',function(){
			t.clearFilter();
		});
	},
	clearFilter : function(){
		var t = this, item;
		t.form.clear();
		t.store.params.q=({}).toJSONString();
	},
	getFilteredData : function(){
		var t = this, values;
		values = t.getFilterItemValues();
		t.store.params.q = values.toJSONString();
		t.store.params.event = t.filterEvent;
		t.grid.pbar.params.current = t.grid.pbar.current;
		t.grid.pbar.params.start = t.grid.pbar.start;
		t.store.params.current = t.grid.pbar.current;
		t.store.params.start = t.grid.pbar.start;
		t.store.load();
		// mj.apply(t.store.params,t.cachedParams);
		// delete t.store.params.q;
		t.win.hide();
	},
	getFilterElements : function(fields){
		var t=this,item,item2,items = [], single, c=t.countStart-(this.tabPanel&&this.tabPanel.hideHeader?1:0);
		for(var i=0,len=fields.length;i<len;i++)
			if(typeof fields[i].filter != 'undefined'){
				single = (fields[i].filter == 'single');
				itemName = fields[i].filterIndex ? fields[i].filterIndex : fields[i].dataIndex;
				switch (fields[i].type){
					case 'combo':
						if(!single){
							item = new mj.form.combo({
								labelWidth : this.labelWidth+'px',
								title : fields[i].header,
								dataIndex : fields[i].dataIndex,
								store : typeof fields[i].store != 'undefined' ? fields[i].store : [{id:0,text:mj.lng.titles.buttons.no},{id:1,text:mj.lng.titles.buttons.yes}],
								width : 117,
								table : fields[i].table,
								mode : 'remote',
								itemStyle : 'float:left;clear:none;',
								name : itemName + t.splitter + "1"
							});
							items.push(item);
							item2 = new mj.form.combo({
								//left : 280,
								//top : c>0?c*27:0,
								itemStyle : 'padding-left:10px;float:left;clear:none;',
								dataIndex : fields[i].dataIndex,
								store : typeof fields[i].store != 'undefined' ? fields[i].store : [{id:0,text:mj.lng.titles.buttons.no},{id:1,text:mj.lng.titles.buttons.yes}],
								width : 117,
								table : fields[i].table,
								mode : 'remote',
								name : itemName + t.splitter + "2"
							});
							items.push(item2);
						}else{
							item = new mj.form.combo({
								labelWidth : this.labelWidth+'px',
								title : fields[i].header,
								dataIndex : fields[i].dataIndex,
								store : typeof fields[i].store != 'undefined' ? fields[i].store : [{id:0,text:mj.lng.titles.buttons.no},{id:1,text:mj.lng.titles.buttons.yes}],
								width : fields[i].width||117,
								table : fields[i].table,
								mode : 'remote',
								name : itemName
							});
							items.push(item);
						}
						break;
					case 'date':
						if(!single){
							item = new mj.form.dateField({
								labelWidth : this.labelWidth+'px',
								title : fields[i].header,
								dataIndex : fields[i].dataIndex,
								initValue : null,
								table : fields[i].table,
								epoch : fields[i].epoch,
								itemStyle : 'float:left;clear:none;',
								name : itemName + t.splitter + "1"
							});
							items.push(item);
							item2 = new mj.form.dateField({
								// left : 280,
								// top : c>0?c*27:0,
								itemStyle : 'padding-left:25px;float:left;clear:none;',
								dataIndex : fields[i].dataIndex,
								initValue : null,
								table : fields[i].table,
								epoch : fields[i].epoch,
								name : itemName + t.splitter + "2"
							});
							items.push(item2);
						}else{
							item = new mj.form.dateField({
								labelWidth : this.labelWidth+'px',
								title : fields[i].header,
								dataIndex : fields[i].dataIndex,
								initValue : null,
								table : fields[i].table,
								epoch : fields[i].epoch,
								name : itemName
							});
							items.push(item);
						}
						break;
					case 'int':
						if(!single){
							item = new mj.form.numberField({
								labelWidth : this.labelWidth+'px',
								title : fields[i].header,
								dataIndex : fields[i].dataIndex,
								suffix : '',
								decimalPrecision : 0,
								table : fields[i].table,
								itemStyle : 'float:left;clear:none;',
								name : itemName + t.splitter + "1"
							});
							items.push(item);
							item2 = new mj.form.numberField({
								// left : 280,
								// top : c>0?c*27:0,
								itemStyle : 'padding-left:10px;float:left;clear:none;',
								dataIndex : fields[i].dataIndex,
								suffix : '',
								decimalPrecision : 0,
								table : fields[i].table,
								name : itemName + t.splitter + "2"
							});
							items.push(item2);
						}else{
							item = new mj.form.numberField({
								labelWidth : this.labelWidth+'px',
								title : fields[i].header,
								dataIndex : fields[i].dataIndex,
								suffix : '',
								decimalPrecision : 0,
								table : fields[i].table,
								name : itemName
							});
							items.push(item);
						}
						break;
					default:
						if(!single){
							item = new mj.form.textField({
								labelWidth : this.labelWidth+'px',
								title : fields[i].header,
								dataIndex : fields[i].dataIndex,
								table : fields[i].table,
								itemStyle : 'float:left;clear:none;',
								name : itemName + t.splitter + "1"
							});
							items.push(item);
							item2 = new mj.form.textField({
								// left : 280,
								// top : c>0?c*27:0,
								itemStyle : 'padding-left:10px;float:left;clear:none;',
								dataIndex : fields[i].dataIndex,
								table : fields[i].table,
								name : itemName + t.splitter + "2"
							});
							items.push(item2);
						}else{
							item = new mj.form.textField({
								labelWidth : this.labelWidth+'px',
								title : fields[i].header,
								dataIndex : fields[i].dataIndex,
								table : fields[i].table,
								name : itemName
							});
							items.push(item);
						}
				}
				t.addRelated(item);
				t.addRelated(item2);
				c++;
			}
		return items;
	},
	getFilterItemValues : function(){
		var t = this, item, val, q = {};
		for(var i=0,len=t.form.items.length;i<len;i++){
			item = t.form.items[i];
			val = item.getValue(); 
			if((val !== '') || (val !== null))
				q[(item.table ? item.table+'.' : '') +item.name] = val;
		}
		return q;
	},
	show : function(){
		this.win.show();
	}
};
mj.extend(mj.dataFilter, mj.component);
mj.dataFilterTrigger = function(config){
	mj.dataFilterTrigger.superclass.constructor.call(this, config);
};
mj.dataFilterTrigger.prototype = {
	componentClass : 'mj.dataFilterTrigger',
	table : '',
	countStart : 1,
	returns : false,
	handler : false,
	filterMode : true,
	localSort : false,
	tabs : {},
	titles : {},
	init : function(){
		var t = this;
		mj.apply(t.titles,{tabs : {filter : mj.lng.glb.filter, records : mj.lng.glb.records}});
		t.store = new mj.store({url : t.url, localSort : t.localSort,params : {event : t.filterEvent, table : t.table}});
		mj.applyIf(t.store.params,t.params);
		var sc = this;
		t.win = new mj.window({
			renderTo : mj.NE(),
			title : mj.lng.glb.filterRecords,
			modal : true,
			width : t.width,
			height : t.height,
			minWidth : t.width,
			minHeight : t.height,
			buttons : [
				{title: mj.lng.glb.exit, handler:function(){
						if(typeof t.handler == 'function')
							t.handler(t, undefined);
						t.win.hide();
					}
				},
				{title: mj.lng.glb.clear, handler:function(){
					t.clearFilter();
					t.tabPanel.setActive(0);
					var str = sc.filterMode?mj.lng.glb.records:mj.lng.glb.filter;
					var x = sc.btns.getIndex('title',str);
					if(x>-1)
						sc.btns[x].setTitle(mj.lng.glb.records);
					sc.filterMode = true;
					}
				},
				{title: mj.lng.glb.records, handler:function(){
					if(sc.filterMode){
						t.getFilteredData();
						this.setTitle(mj.lng.glb.filter);
						sc.filterMode = false;
					}else{
						sc.tabPanel.setActive(0);
						this.setTitle(mj.lng.glb.records);
						sc.filterMode = true;
					}
				}}
			]
		});
		t.win.on('beforeclose',function(){
			this.buttons[0].handler();
		});
		t.btns = t.win.buttons;
		t.mask = new mj.mask({el:t.win.getBody()});
		t.panel = new mj.panel({
			renderTo : t.win.getBody()
		});
		t.tabPanel = new mj.tab({
			renderTo : t.panel.getBody(),
			activeTab : 0,
			border : false,
			hideHeader : true,
			tabWidth : 120,
			maxTitle : 12,
			items :[
				{
					title: t.titles.tabs.filter,
					iconCls:'tabs',
					closable:false
				},{
					title: t.titles.tabs.records,
					iconCls:'tabs',
					closable:false
				}
			]
		});
		t.tabs['filter'] = t.tabPanel.tabs[0];
		t.tabs['records'] = t.tabPanel.tabs[1];
		var elements = t.getFilterElements(t.fields);
		t.form = new mj.form({
			renderTo : t.tabs.filter.getBody(),
			items : elements
		});
		t.grid = new mj.grid({
			renderTo : t.tabs.records.getBody(),
			store : t.store,
			pbar : new mj.pager({pos:'bottom',limit:25}),
			fitToParent : true,
			cm : t.fields
		});
		if(t.handler && typeof t.handler == 'function')
			t.grid.on('rowdblclick',function(g,s){
				if(t.handler(t, g.selectedRow.data)!=false)
					t.win.hide();
			},t);
		else if(t.returns)
			t.grid.on('rowdblclick',function(g,s){
				this.setValue(g.selectedRow.data[t.returns.values[0].name],true);
				this.setValue(g.selectedRow.data[t.returns.values[1].name]);
				this.trigger('dataselect', this, g.selectedRow.data);
				t.win.hide();
			},t.returns.el);
		t.store.on('sourcerefresh',function(){
			t.clearFilter();
		});
	},
	getFilteredData : function(){
		var t = this, values;
		t.mask.show(50);
		var i=0;
		while(++i<t.btns.length)
			t.btns[i].setDisable();
		values = t.getFilterItemValues();
		t.store.params.q = values.toJSONString();
		t.store.params.event = t.filterEvent;
		t.grid.pbar.params.current = t.grid.pbar.current;
		t.grid.pbar.params.start = t.grid.pbar.start;
		t.store.params.current = t.grid.pbar.current;
		t.store.params.start = t.grid.pbar.start;
		t.store.load();
		// delete t.store.params.q;
		// t.store.on('load',function(){
			// t.tabPanel.setActive(1);
			// var i=0;
			// while(++i<t.btns.length)
				// t.btns[i].setEnable();
			// t.mask.hide();
		// });
		t.store.onOnce('load',t._onStoreLoad,t);
	},
	_onStoreLoad : function(){
		this.tabPanel.setActive(1);
		var i=0;
		while(++i<this.btns.length)
			this.btns[i].setEnable();
		this.mask.hide();
	},
	show : function(){
		this.win.show();
		return this.win;
	}
};
mj.extend(mj.dataFilterTrigger, mj.dataFilter);
/**
 * Bir elemanı sürüklenebilir hale getirmek için kullanılan sınıf
 * @class
 * @name mj.drag
 * @extends mj.component
 * @param {Object/String} config Konfigürasyon parametreleri. Sürüklenmek istenen elemanın id değeri string olarak verilebilir.
 * @config.el {HTMLElement/String} 
 */
mj.drag = function(config){
	mj.drag.superclass.constructor.call(this, config);
};

mj.drag.prototype = {
	componentClass : 'mj.drag',
	defaultConfigStr : 'el',
	proxy : true,
	dragType : 'vh',
	clientDrag : true,
	moving : true,
	copy : false,
	cls : '',
	startAction : 'mousedown',
	dropEls : [],
	curDrop : false,
	dropOverCls : 'mj-drag-drop-hover',
	dropBottomCls : 'mj-drag-drop-bottom',
	appendParent : false,
	keepAspectRatio : false,
	proxyOpacity : .5,
	/**
	 * Verilen elemanın sürüklenebilir bir nesne olabilmesi gerekli atamaları yapar.
	 * @name init
	 * @function
	 * @type {Function}
	 * @memberOf  mj.drag
	 */
	initDrops : function(){
		for(var i=0,len=this.dropEls.length;i<len;i++){
			var $el =$(this.dropEls[i]);
			ofs = $el.offset();
			reg = {};
			reg.l = ofs.left;
			reg.t = ofs.top;
			reg.r = ofs.left+$el.width();
			reg.b = ofs.top+$el.height();
			this.dropEls[i].reg = reg;
		}
	}, 
	fromDrops : function(x){
		var t=this;
		t.fromDrop = false;
		for(var i=0,len=t.dropEls.length;i<len;i++){
			var el = t.dropEls[i],$el = $(el);
			var reg = el.reg;
			if(x.left>=reg.l&&x.left<=reg.r&&x.top>=reg.t&&x.top<=reg.b)
				t.fromDrop = el;

		}
	}, 	
	checkDrops : function(sc){
		var t=this;
		t.curDrop = false;
		for(var i=0,len=t.dropEls.length;i<len;i++){
			var el = t.dropEls[i],$el = $(el);
			var reg = el.reg;
			t.bottomDrop = false;
			if(Math.abs(sc.Y-reg.b)<=4&& sc.X>=reg.l&&sc.X<=reg.r){
				$el.addClass(t.dropBottomCls);	
				t.curDrop = el;
				t.bottomDrop = true;
				t.trigger('onDropOver',t,el);
				$el.trigger('onDropOver');		
			}else
				if($el.hasClass(t.dropBottomCls)){
					$el.removeClass(t.dropBottomCls);
					t.trigger('onDropOut',t,el);
					$el.trigger('onDropOut');
				}
			
			if(t.bottomDrop !== true && sc.X>=reg.l&&sc.X<=reg.r&&sc.Y>=reg.t&&sc.Y<=reg.b){
				$el.addClass(t.dropOverCls);	
				t.curDrop = el;
				t.bottomDrop = false;
				t.trigger('onDropOver',t,el);		
				$el.trigger('onDropOver');	
			}else
				if($el.hasClass(t.dropOverCls)){
					$el.removeClass(t.dropOverCls);
					t.trigger('onDropOut',t,el);
					$el.trigger('onDropOut');
				}
		}
	}, 	
	destroy : function(){
		this._el.remove();
	},
	init : function(){
		var t = this,zy=this;
		if(!t.dragEl)
			t.dragEl = t.el;
		var el = t.el = (typeof t.el === 'string' ? mj.get(t.el) : t.el), 
			dragEl = t.dragEl = (typeof t.dragEl === 'string' ? mj.get(t.dragEl) : t.dragEl);
		if(!el)
			return;
		var esize;
		var _el = t._el = $(el), _dragEl = t._dragEl = $(dragEl);
		t.pwidth=0;
		t.pheight=0;
		if(!t.parent)
			t.parent = _el.parent();
		else{
			t.parent = $(t.parent);
			if(t.parent.css('position')!='static'||t.parent[0]==mj.bd[0])
				t.offsetParent = t.parent[0];
		}
		_el.addClass(t.cls);
		var elCss = _el.css('position');
		if(elCss!='relative' && elCss!='static') //buraya ayrıca bakılacak şimdilik relative kullanılmasın
			_el.css('position','absolute');
		if(t.side){
			_dragEl.addClass('mj-resizer-'+t.side);
			t.mode = 'R';
		}
		var width, height, p, lp = {}, dif = {}, ppos = {}, pos={},sc;
		if(t.keepAspectRatio)
			t.aspectRatio = _el.outerHeight()/_el.outerWidth();
		if(t.resizer){
			if(t.resizer.maxWidth){
				var left = parseInt(t.resizer._el.css('left'));
				if(left)
					t.resizer.setMaxWidth(t.resizer.config.maxWidth-left);
				if(!t.resizer.config.parentBorders || !t.resizer.config.parentBorders.maxWidth)
					t.resizer.config.parentBorders.maxWidth = t.resizer.config.maxWidth;
			}
			if(t.resizer.maxHeight){
				var top = parseInt(t.resizer._el.css('top'));
				if(top)
					t.resizer.setMaxHeight(t.resizer.config.maxHeight-top);
				if(!t.resizer.config.parentBorders || !t.resizer.config.parentBorders.maxHeight)
					t.resizer.config.parentBorders.maxHeight = t.resizer.config.maxHeight;
			}
		}
		var _setConstraints,_start,_stop,_move;
		_setConstraints = function(pos){
			var min1,min2,max1,max2;
			if(t.mode=='R'){
				min1 = t.minWidth, max1 = t.maxWidth;//||($.browser.msie?pos.E.target.parentElement.clientWidth-1:pos.E.view.innerWidth-3)-parseInt($(pos.E.target).css('left'));
				min2 = t.minHeight, max2 = t.maxHeight;//||300;
			}else{
				if(t.clientDrag){
					min1 = t.minWidth||t.clientReg.l, max1 = t.maxWidth||t.clientReg.r-width;
					min2 = t.minHeight||t.clientReg.t, max2 = t.maxHeight||t.clientReg.b-height;
				}
			}
			pos.X = pos.X<min1 ? min1 : (pos.X>max1 ? max1 : pos.X);
			pos.Y = pos.Y<min2 ? min2 : (pos.Y>max2 ? max2 : pos.Y);
			if(t.keepAspectRatio){
				if(pos.X * t.aspectRatio<min2 || pos.X * t.aspectRatio > max2)
					pos.X = pos.Y / t.aspectRatio;
				else
					pos.Y = pos.X * t.aspectRatio;
			}
			//mj.log('x='+pos.X+',y='+pos.Y);
			return {X:pos.X,Y:pos.Y};
		},_start = function(e){
			if((t.startAction=='mousedown' && e.which==1) && t.trigger('beforedrag', t, e, lp)!==false&&t.pause!==true){
				e.preventDefault();
				t.dragging = 'half';
				$().mouseup(_stop).mousemove(_move);
				t.trigger('dragstart', t, e, lp);
			}
		}, _stop = function(e){
			if(t.dragging=='half')
				$().unbind('mousemove',_move).unbind('mouseup',_stop);
			else if(t.dragging==true){
				$().unbind('mousemove',_move).unbind('mouseup',_stop);
				e.preventDefault();
				if(t.proxy)
					t.proxy[0].className='';
				if(t.trigger('dragstop', t,t.curDrop,t.fromDrop)!==false){
					if(t.mode=='R'){
						if(_el.hasAbsoluteParent())
							var fx=0,fy=0;
						else
							var fx=$.browser.msie?0:e.view.scrollMaxX,fy=$.browser.msie?0:e.view.scrollMaxY;
						_el.css({width:pos.X-fx, height:pos.Y-fy});
						t.trigger('resize', t, pos.X, pos.Y);
					}else if(t.moving){
						lp = p.offset();
						//alert('lpx='+lp.left+',lpy='+lp.top);
						//mj.log('lpx='+lp.left+',lpy='+lp.top);
						if(t.offsetParent!=mj.bd[0]){
							ppos = $(t.offsetParent).offset({border:true});
							lp.left = lp.left-ppos.left;
							lp.top = lp.top-ppos.top;
						}
						//alert('px='+ppos.left+',py='+ppos.top);
						//mj.log('px='+ppos.left+',py='+ppos.top);
						//lp['z-index'] = '32000';
						if(t.copy){
							t.xel = _el.clone().css(lp).appendTo(t.parent);
							var config = t.config;
							config.el = t.xel[0];
							config.copy = false;
							var ndrag = new mj.drag(config);
							ndrag.on('dragafterstop',function(e,x,y){
								t.trigger('dragafterstop',e,x,y);
							},t);
							ndrag.on('dragstop',function(e,x,y){
								t.trigger('dragstop',e,x,y);
							},t);
						}	
						else	
							_el.css(lp);//.appendTo(t.parent);
							if(t.appendParent)
								_el.appendTo(t.parent);
						if(t.parent && t.resizer){
							if(t.resizer.maxWidth){
								var pWidth = t.resizer.config.parentBorders.maxWidth-lp.left;
								t.resizer.setMaxWidth(pWidth > t.resizer.config.maxWidth ? t.resizer.config.maxWidth : pWidth);
							}
							if(t.resizer.maxHeight){
								var pHeight = t.resizer.config.parentBorders.maxHeight-lp.top;
								t.resizer.setMaxHeight(pHeight > t.resizer.config.maxHeight ? t.resizer.config.maxHeight : pHeight);
							}
						}
					}
					t.trigger('dragafterstop', t,t.curDrop,t.fromDrop);
				}
				if(t.curDrop)
					$(t.curDrop).removeClass(t.dropOverCls);
				if(t.proxy){
					t.proxy.remove();
					t.proxy = true;
				}
				t.dragging = null;
				window.mjDragging = null;
				
			}
			
		}, _move = function(e){
			e.preventDefault();
			if(t.dragging=='half'){
				width = _el.outerWidth();
				height = _el.outerHeight();
				t.pheight = t.parent[0].clientHeight;
				t.pwidth = t.parent[0].clientWidth;		
				t.offsetParent = t.offsetParent||t.el.offsetParent||mj.bd[0];
				if(t.clientDrag){
					var o={left:0,top:0};
					if(t.parent[0]!=t.offsetParent)
						var o = t.parent.offset({relativeTo : t.offsetParent,border:true});
					t.clientReg = { l : o.left, t : o.top, r: o.left + t.pwidth, b : o.top + t.pheight};
				}
				lp = _el.offset({relativeTo:t.offsetParent});
				t.dropEls = t.dropEls.length>0?t.dropEls:window.dropEls||[];				
				if(t.dropEls.length>0){
					t.initDrops();
					t.fromDrops(lp);
				}	
				if(t.proxy){
					if(t._el.hasAbsoluteParent()){
						var _l = parseInt(t._el.css('left')), _t=parseInt(t._el.css('top'));
						_l = !isNaN(_l) ? _l : 0;
						_t = !isNaN(_t) ? _t : 0;
						var off = {left:_l, top:_t};
					}else
						var off = t._el.offset({relativeTo:t.offsetParent});
					p = t.proxy = $(mj.NE(t.parent, {cls:'mj-proxy'})), op = {'z-index':'32001',position : (t.position||_el.css('position')=='static')?'absolute':(t.position||_el.css('position')), width:t.proxyEl?t.proxyEl.width:width, height:t.proxyEl?t.proxyEl.height:height, left:off.left, top:off.top, opacity:t.proxyOpacity};
					p.css(op);
				}else
					p = t._el;
				if(t.mode=='R')
					esize = { width:_el.width(), height:_el.height()};				
				t.dragging = true;
				window.mjDragging = true;
				dif.left = e.pageX;
				dif.top = e.pageY;
			}
			if(t.dragging){				
				if(t.mode=='R'){
					pos = {X : esize.width + e.pageX - dif.left, Y : esize.height + e.pageY - dif.top, E:e};
					sc=_setConstraints(pos);
					p.css({width:sc.X, height:sc.Y});
				}else{
					pos = {X : lp.left + e.pageX - dif.left, Y : lp.top + e.pageY - dif.top};
					sc=_setConstraints(pos);
					//mj.log('scx='+sc.X+',scy='+sc.Y);
					if(t.dragType=='vh')
						p.css({left:sc.X, top:sc.Y});
					else if(t.dragType=='v')
						p.css({top:sc.Y});
					else if(t.dragType=='h')
						p.css({left:sc.X});
					if(t.trigger('dragmove', t, sc.X, sc.Y)==false)
						_stop(e);
					if(t.dropEls.length>0)
						t.checkDrops(sc);
				}
			}
		};
		_dragEl.bind(this.startAction,_start);
		mj.drag.superclass.init.call(this);
	}
};

mj.extend(mj.drag, mj.component);
mj.itemSorter = function(config){
	mj.itemSorter.superclass.constructor.call(this, config);
};

mj.itemSorter.prototype = {
	componentClass : 'mj.itemSorter',
	init : function(){
		var t = this;
		t.items = [];
		t.itemParents = [];
		for(var i=0,l=t.sortItems.length;i<l;i++){
			var el = t.sortItems[i];
			item = {
				el:$(el),
				index : i,
				drag : new mj.drag({
					el : el,
					parent : t.dragParent ? t.dragParent : mj.bd,
					moving : false,
					dropEls : t.sortItems
				})
			};
			var p = item.el.parent();
			p.addClass('mj-item-sorter-parent-'+i);
			t.itemParents.push(p);
			item.drag.on('beforedrag',function(){
				item.drag.dropEls = t.sortItems;
			});
			item.drag.on('dragstop',function(e,target){
				if(target){
					var p=$(target).parent();
					var s = p[0].className;
					var pattern = /mj\-item\-sorter\-parent\-[0-9]+/;
					s=pattern.exec(s);
					s=s[0];
					if(s){
						var pattern = /[0-9]+/;
						s=pattern.exec(s);
						t.moveItem(this, parseInt(s[0]));
					}
				}
			},item);
			item.el.css('cursor', 'move');
			t.items.push(item);
		}
		mj.itemSorter.superclass.init.call(t);
	},
	moveItem : function(item, targetIndex){
		var t = this;
		if(item.index<targetIndex)
			for(var i=item.index,l=targetIndex;i<l;i++){
				t.items[i+1].el.appendTo(t.itemParents[i]);
				t.items[i+1].index--;
			}
		else
			for(var i=item.index,l=targetIndex;i>l;i--){
				t.items[i-1].el.appendTo(t.itemParents[i]);
				t.items[i-1].index++;
			}
		item.el.appendTo(t.itemParents[targetIndex]);
		item.index = targetIndex;
		t.items._sort('index');
	}
};

mj.extend(mj.itemSorter, mj.component);
/**
 * Bir elemanı tekrar boyutlanabilir hale getirmek için kullanılan sınıf
 * @class
 * @name mj.resizer
 * @extends mj.component
 * @param {Object/String} config Konfigürasyon parametreleri. Boyutu değiştirilmek istenen elemanın id değeri string olarak verilebilir.
 * @config.el {HTMLElement/String} 
 */
mj.resizer = function(config){
	mj.resizer.superclass.constructor.call(this, config);
};

mj.resizer.prototype = {
	componentClass : 'mj.resizer',
	defaultConfigStr : 'el',
	proxy : true,
	keepAspectRatio : false,
	init : function(){
		var t = this, el = t.el, _el = t._el = $(el);
		var rel = t.resizeEl = $(mj.NE(el, {html:mj.insertSpacer(10,10)}));
		t.se = new mj.drag({el:el, dragEl:rel, side:'se', minWidth : t.minWidth, maxWidth:t.maxWidth, minHeight:t.minHeight, maxHeight:t.maxHeight, keepAspectRatio : t.keepAspectRatio, proxy:t.proxy});
		t.se.on('resize', function(dragger, width, height){
			_el.trigger('resize');
		});
	},
	setMaxWidth : function(val){
		if(this.se)
			this.se.maxWidth = val;
	},
	setMaxHeight : function(val){
		if(this.se)
			this.se.maxHeight = val;
	}
};

mj.extend(mj.resizer, mj.component);
mj.rating = function(config){
	mj.rating.superclass.constructor.call(this, config);
};

mj.rating.prototype = {
	componentClass : 'mj.rating',
	disabled : false,
	iconPos : 'left',
	cls : 'mj-rating-star',
	count : 5,
	value : 0,
	enabled : true,
	init : function(){
		var t = this, id=t.id || mj.genId('mj-rating-');
		t.cnt = mj.NE(t.renderTo, {cls:t.cls, id: id});
		t._cnt = $(t.cnt);
		t._cnt.bind('mouseout', function(){
			t.setRawValue.call(t, t.value);
		});
		t.icons = [];
		for(var i=0; i<t.count; i++){
			t.icons.push({_el : $(mj.NE(t.cnt, {cls:'mj-rating-icon mj-off', id:id+'-icons-'+(i+1), html:mj.insertSpacer(12,12)}))});
			t.icons[i]._el.bind('mouseover', function(){
				if(t.enabled)
					t.setRawValue.call(t, this.id.toString().replace(id+'-icons-',''));
			});
			t.icons[i]._el.bind('click', function(){
				if(t.enabled){
					var val = this.id.toString().replace(id+'-icons-','');
					t.setValue.call(t, val);
					t.trigger('click', t, val);
				}
			});
		}
		t.setValue(t.value);
	},
	setIcon : function(index, val){
		var t = this, icon = t.icons[index];
		if(icon.value!=val){
			if(val){
				icon._el.removeClass('mj-off');
				icon._el.addClass('mj-on');
			}else{
				icon._el.removeClass('mj-on');
				icon._el.addClass('mj-off');
			}
		}
	},
	setRawValue : function(val){
		var t = this;
		val = parseInt(val);
		if(val>=0 && val<=t.count){
			for(var i=0;i<val;i++)
				t.setIcon(i, true);
			for(var j=val;j<t.count;j++)
				t.setIcon(j, false);
			return true;
		}
		return false;
	},
	setValue : function(val){
		var rVal = this.setRawValue(val);
		if(rVal)
			this.value = val;
		return rVal;
	},
	enable : function(){
		this.enabled = true;
	},
	disable : function(){
		this.enabled = false;
	}
};
mj.extend(mj.rating, mj.component);
/**
 * Temel buton sınıfı.
 * @name mj.button
 * @class
 * @extends mj.component
 * @scope  mj.component
 * @param {Object} config
  */

mj.button = function(config){
	mj.button.superclass.constructor.call(this, config);
};

mj.button.prototype = {
	componentClass : 'mj.button',
	disabled : false,
	iconPos : 'left',
	buttonAlign : 'right',
	cls : '',
	invisible : false,
	insufficientRights : false,
	alt : false,
	//width:50,
	/**
	 * Buton bileşeninin görsel elemanlarının oluşturularak olay dinleyicilerinin atanması işlemini gerçekleştirir.
	 * @name init
	 * @function
	 * @type {Function}
	 * @memberOf  mj.button
	 */
	init : function(){
		var btn = this;
		this._cw = this.width ? ('width:'+(this.width-12)+'px') : '';
		var el = this.el = this.renderTo;
		var _e = this._el = $(el);
		_e.addClass('mj-button '+(this.buttonAlign=='left'?'mj-button-left1':'')+' mj-unselectable '+btn.cls);
		if(btn.invisible)
			_e.addClass('mj-invisible');
		if(btn.alt){
			btn.alt=mj.translate(btn.alt);
			_e.attr('title', btn.alt);
		}
		btn.title = mj.translate(btn.title);
		var insertIcon = function(){
			return btn.icon = $(mj.NE(btn.renderTo, {cls:'mj-button-icon '+btn.iconCls}));
		};
		mj.NE(this.renderTo, {cls:'mj-button-left'});
		var center = this._center = $(mj.NE(this.renderTo, {cls:'mj-button-center mj-unselectable', style:this._cw, unselectable:'on', html:this.title ? ('<center><span style="'+this._cw+'" unselectable="on">'+this.title+'</span></center>'):''}));
		if(this.iconCls)
			if(this.iconPos == 'right')
				center.append(insertIcon(center));
			else
				center.prepend(insertIcon(center));
		mj.NE(this.renderTo, {cls:'mj-button-right'});
		if(this.disabled)
			this.disable();
		
		_e.hover(function(){
			if(!btn.disabled)
				_e.addClass("mj-button-hover");
		},function(){
			if(!btn.disabled)
				_e.removeClass("mj-button-hover");
		});
		_e.mouseout(function(){
			_e.removeClass("mj-button-down");
		});
		_e.mousedown(function(){
			if(!btn.disabled)
				_e.addClass("mj-button-down");
		});
		_e.mouseup(function(){
			_e.removeClass("mj-button-down");
		});
		_e.click(function(e){
			if(!btn.disabled){
				if(mj._activeFormElement && typeof mj._activeFormElement.trigger == 'function')
					mj._activeFormElement.trigger('blur',mj._activeFormElement);
				btn.trigger('click', btn, btn.handlerId, e);
			}	
		});
		if(btn.handler)
			btn.on('click', btn.handler, btn.scope);
		if(btn._customRights){
			var _customRightsId = btn._customRights.split(',');
			_customRightsId = _customRightsId[0];
			if(mj._renderingModule && mj._renderingModule._customRights && mj._renderingModule._customRights.indexOf(_customRightsId)>-1){
				btn._el.addClass('mj-invisible');
				btn.insufficientRights = true;
				btn.setHandler(function(){return false;},this);
			}
		}
		mj.button.superclass.init.call(this);
	},
	setHandler : function(cb, scope){
		if(this.handler)
			this.mon('click', this.handler);
		this.handler = cb;
		this.scope = scope || this.scope || this;
		this.on('click', this.handler, this.scope);
	},
	setDisable : function(){
		this.disable();
	},
	setEnable : function(){
		this.enable();
	},
	disable : function(){
		if(!this._el.hasClass('mj-disabled')){
			this._el.addClass('mj-disabled');
			if(this.icon)
				this.icon.addClass(this.iconCls+'-disabled');
		}
		this.disabled = true;
	},
	enable : function(){
		this._el.removeClass('mj-disabled');
		if(this.icon)
			this.icon.removeClass(this.iconCls+'-disabled');
		this.disabled = false;
	},
	setAlt : function(alt){
		this.alt = mj.translate(alt);
		this._el.attr('title', this.alt);
	},
	setTitle : function(title){
		this.title = mj.translate(title);
		this._center[0].lastChild.innerHTML = this.title ? ('<span style="'+this._cw+'" unselectable="on">'+this.title+'</span>'):''; 
	},
	hide : function(){
		if(!this.invisible)
			this._el.addClass('mj-invisible');
		this.invisible = true;
	},
	show : function(){
		if(this.invisible && !this.insufficientRights)
			this._el.removeClass('mj-invisible');
		this.invisible = false;
	}
};
mj.extend(mj.button, mj.component);
mj.speedButton = function(config){
	mj.speedButton.superclass.constructor.call(this, config);
};

mj.speedButton.prototype = {
	componentClass : 'mj.speedButton',
	init : function(){
		var btn = this;
		var el = this.el = mj.NE(this.renderTo);
		var _e = this._el = $(el);
		_e.addClass('mj-speed-button mj-unselectable '+btn.cls);
		this.icon = $(mj.NE(_e,{cls:'mj-speed-button-icon '+btn.iconCls}));
		if(btn.alt){
			btn.alt=mj.translate(btn.alt);
			_e.attr('title', btn.alt);
		}
		if(this.disabled)
			this.disable();
		
		_e.hover(function(){
			if(!btn.disabled)
				_e.addClass("mj-speed-button-hover");
		},function(){
			if(!btn.disabled)
				_e.removeClass("mj-speed-button-hover");
		});
		_e.mouseout(function(){
			_e.removeClass("mj-speed-button-down");
		});
		_e.mousedown(function(){
			if(!btn.disabled)
				_e.addClass("mj-speed-button-down");
		});
		_e.mouseup(function(){
			_e.removeClass("mj-speed-button-down");
		});
		_e.click(function(e){
			if(!btn.disabled){
				if(mj._activeFormElement && typeof mj._activeFormElement.trigger == 'function')
					mj._activeFormElement.trigger('blur',mj._activeFormElement);
				btn.trigger('click', btn, btn.handlerId, e);
			}	
		});
		if(btn.handler)
			btn.on('click', btn.handler, btn.scope);
		if(btn._customRights){
			var _customRightsId = btn._customRights.split(',');
			_customRightsId = _customRightsId[0];
			if(mj._renderingModule && mj._renderingModule._customRights && mj._renderingModule._customRights.indexOf(_customRightsId)>-1){
				btn._el.addClass('mj-invisible');
				btn.setHandler(function(){return false;},this);
			}
		}
		mj.button.superclass.init.call(this);
	},
	setTitle : function(title){
		return false;
	}
};
mj.extend(mj.speedButton, mj.button);
mj.mask = function(config){
	mj.mask.superclass.constructor.call(this, config);
};
mj.mask.prototype = {
	componentClass : 'mj.mask',
	init : function(){
		var t=this, el = t.el = t.el ? t.el : document.body, _el = t._el = $(el);
		t.mask = $(mj.NE(el, {cls:'mj-mask'}));
		mj.bindResize(t.mask, t.doResize, t);
		mj.mask.superclass.init.call(this);
	},
	doResize : function(){
		var t = this, m = t.mask;
		var el = this.componentClass=='mj.mask'?t._el:undefined;
		if(el){
			var ofs = el.offset();
			var tn = t._el.parent().attr('tagName');
			m.css('left', (($.browser.msie&&tn=='BODY')?ofs.left:t.el.offsetLeft));
			m.css('top', (($.browser.msie&&tn=='BODY')?ofs.top:t.el.offsetTop));
			m.css('height', (typeof(tn)=='undefined' || tn=='HTML' || tn=='BODY' || tn.toString()=='') ? $(document).height() : t.el.offsetHeight);
			m.css('width', t.el.offsetWidth);
		}
	},
	show : function(zIndex){
		this.doResize();
		this.mask.css('z-index', zIndex ? zIndex : this.zIndex);
		this.mask.show();
	},
	hide : function(){
		this.mask.hide();
	},
	destroy : function(){
		this.mask.remove();
	}
}
mj.extend(mj.mask, mj.component);
mj.randomColors = function(config){
	this.colors = ['red', 'blue', 'lights', 'green', 'darks'];
	mj.randomColors.superclass.constructor.call(this, config);
};
mj.randomColors.prototype = {
	componentClass : 'mj.randomColors',
	_activeIndex : 0,
	_autoPallette : true,
	r : 256,
	g : 256,
	b : 256,
	border : 360,
	border2 : 270,
	state : "",
	lights : false,
	darks : false,
	changeTint : function(col){
		var t = this;
		t.v = false;
		t.lights = false;
		t.darks = false;
		t.r = 256;
		t.g = 256;
		t.b = 256;			 
		if (col == "red"){
			t.r = 256;
			t.g = 40;
			t.b = 40; 
			t.state = "red";
		}else if (col == "blue"){
			t.r = 40;
			t.g = 40;
			t.b = 256; 
			t.state = "blue";
		}else if (col == "green") {
			t.r = 40;
			t.b = 40;
			t.g = 256; 
			t.state = "green";
		}else if (col =="darks") {
			darks = true;				
		}else if (col == "lights") { 
			lights = true;
		}else {
			t.r = 256;
			t.g = 256;
			t.b = 256;			 
		}	 
	},
	color : function(r,g,b){
		var t = this;
		t.red = r;
		t.green = g;
		t.blue = b;
	},
	generate : function(returnColor){
	    var t = this;
		if(t._autoPallette)
			t.changeTint(t.colors[t._activeIndex++]);
		t.a = 256;
		var r1 = Math.floor(Math.random() * t.r);
		var r2 = Math.floor(Math.random() * t.g);
		var r3 = Math.floor(Math.random() * t.b);		
		var sum = r1 + r2 + r3;

		if (t.lights) {
			while (t.sum < t.border) {				
				var choose = Math.floor(Math.random() * 3);
				switch (t.choose) {
					case 0:	
						r1 += (t.border - t.sum);
						break;
					case 1:
						r3 += (t.border - t.sum);
						break;
					case 2:
						r2 += (t.border - t.sum);
						break;
				}
				sum = r1 + r2 + r3;
			}
		}else if (t.darks) {
			r1 = Math.min(r1, 170);
			r2 = Math.min(r2, 170);
			r3 = Math.min(r3, 170);						
			while (sum >= t.border2) {
				var choose = Math.floor(Math.random() * 3);
				switch (choose) {
					case 0:	
						r1 = Math.max(r1 - 10, 1);
						break;
					case 1:
						r2 = Math.max(r2 - 10, 1);
						break;
					case 2:
						r3 = Math.max(r3 - 10, 1);
						break;
					default:
						break;
				}
				sum = r1 + r2 + r3;											
			}			
		}
		t.r = r1;
		t.g = r2;
		t.b = r3;
		if(returnColor)
			return {r:t.r, g:t.g, b:t.b};
		else{
			var col = "#" + t.toHex(r1) + t.toHex(r2) + t.toHex(r3);
			return col;
		}
	},
	toHex : function(num) {
		var t=this, x = Math.floor(num / 16);
		var y = num - (x * 16);
		var str = "";			 
		str += t.getHex(x) + t.getHex(y);
		return str;
	},
	getHex : function(digit) {
		var str = "";
		switch (digit) {
			case 10:
				str += "A";
				break;
			case 11:
				str += "B";
				break;						 
			case 12:
				str += "C";
				break;
			case 13:
				str += "D";
				break;						 
			case 14:
				str += "E";
				break;
			case 15:
				str += "F";						 						 						 						 						 
				break;
			default:
				str += digit;						 
		}
		return str;	
	},
	darken : function(minVal){
		var t = this;
		t.r = Math.min(minVal, t.r);
		t.g = Math.min(minVal, t.g);
		t.b = Math.min(minVal, t.b);
		return t;
	},
	limit : function(val,minVal,maxVal) {
		return Math.max(Math.min(val, maxVal), minVal);
	},
	normalize : function(){
		this.r = this.limit(parseInt(this.r), 0, 255);
		this.g = this.limit(parseInt(this.g), 0, 255);
		this.b = this.limit(parseInt(this.b), 0, 255);
		return this;
	},
	getSimilar : function(k){
		var t = this;
		t.r = Math.floor(k*40 + t.r);
		t.b = Math.floor(k*40 + t.b);
		t.g = Math.floor(k*40 + t.g);
		t.normalize();
		var col = "#" + t.toHex(t.r) + t.toHex(t.g) + t.toHex(t.b);
		return col;
	}
};
mj.extend(mj.randomColors, mj.component);
mj.shortcuts = {
	on : function(){
		$.hotkeys.add.apply($.hotkeys, arguments);
	},
	mon : function(){
		$.hotkeys.remove.apply($.hotkeys, arguments);
	}
};
mj.map = function(config){
	mj.map.superclass.constructor.call(this,config);
};
mj.map.prototype = {
	componentClass : 'mj.map',
	_canModify : false,
	allowedBoundsSWLat : false,
	allowedBoundsSWLong : false,
	allowedBoundsNELat : false,
	allowedBoundsNELong : false,
	itemStyle : '',
	maxMapScale : 16,
	minMapScale : 9,
	showOverview : false,
	startPointLat : false,
	startPointLong : false,
	startZoomLevel : 15,
	height : 350,
	width : 350,
	init : function(){
		var t = this, n = mj.NE, v = '';
		if(t.left||t.top){
			t.left = typeof t.left != 'undefined' ? (isNaN(t.left) ? t.left : (t.left+'px')) : '';
			t.top = typeof t.top != 'undefined' ? (isNaN(t.top) ? t.top : (t.top+'px')) : '';
			v = 'position:absolute;left:'+t.left+';top:'+t.top;
		}
		var w = t.width == parseInt(t.width) ? t.width+'px' : t.width;
		var h = t.height == parseInt(t.height) ? t.height+'px' : t.height;
		v += ';width:'+w+';height:'+h+';'+t.itemStyle;
		t.points = t.points ? t.points : [];
		var el = t.el = n(t.renderTo, {cls:t.itemCls+' mj-unselectable',style:v});
		if (GBrowserIsCompatible()){
			var map = new GMap2(t.el);
			map.setMapType(G_HYBRID_MAP);
			map.addControl(new GLargeMapControl());
			map.addControl(new GMapTypeControl());
			map.addControl(new GScaleControl());
			if(t.showOverview)
				map.addControl(new GOverviewMapControl());
			var latlng = new GLatLng(t.startPointLat, t.startPointLong) ; 
			map.setCenter(latlng, t.startZoomLevel);
				GEvent.addListener(map, 'click', function(overlay, point){
					t.trigger('click', t, overlay, point);
					if(t._canModify && t.points.length==0){
						if (overlay){
						}else if (point){
							t.addpoint( {point:point,title:''} ) ;
							t.trigger('addpoint', t, point);
						}
					}
				});

			if(t.allowedBoundsSWLat && t.allowedBoundsSWLong && t.allowedBoundsNELat && t.allowedBoundsNELong){
				t.allowedBounds = new GLatLngBounds(new GLatLng(t.allowedBoundsSWLat, t.allowedBoundsSWLong), new GLatLng(t.allowedBoundsNELat, t.allowedBoundsNELong));
				GEvent.addListener(map, "move", function() {
					t.checkBounds();
				});
			}
			
			var mapTypes = map.getMapTypes();
			for (var i=0; i<mapTypes.length; i++) {
				mapTypes[i].getMinimumResolution = function() {return t.minMapScale;};
				mapTypes[i].getMaximumResolution = function() {return t.maxMapScale;};
			}
			
			t.gMap = map;
		}else{
			// document.getElementById("map").innerHTML = "<h1>ÃzgÃ¼nÃ¼z... TarayÄ±cÄ±nÄ±z Google Maps uygulamasÄ±nÄ± desteklemiyor.</h1>" ;
		}
		mj.map.superclass.init.call(t);
	},
	addpoint : function (point){
		this.points.push(point);
		this.dataDraw();
	},
	checkBounds : function () {
		var t = this;
		if (t.allowedBounds.contains(t.gMap.getCenter()))
			return;
		var C = t.gMap.getCenter();
		var X = C.lng();
		var Y = C.lat();

		var AmaxX = t.allowedBounds.getNorthEast().lng();
		var AmaxY = t.allowedBounds.getNorthEast().lat();
		var AminX = t.allowedBounds.getSouthWest().lng();
		var AminY = t.allowedBounds.getSouthWest().lat();

		if (X < AminX) {X = AminX;}
		if (X > AmaxX) {X = AmaxX;}
		if (Y < AminY) {Y = AminY;}
		if (Y > AmaxY) {Y = AmaxY;}
		t.gMap.setCenter(new GLatLng(Y,X));
	},
	dataClear : function (){
		var t = this;
		t.points = [];
		t.gMap.clearOverlays() ;
	},
	_createMarker : function(lat, lng, title, i){
		var t = this, marker = new GMarker(new GLatLng(lat, lng), {draggable: true, icon: t.customIcons.general, title:title});
		t.points[i].marker = marker;
		marker._arrayItem = t.points[i];
		GEvent.addListener(marker, 'click', function(){
			t.trigger('markerclick', t, marker);
		});
		GEvent.addListener(marker, "dragend", function() {
			marker._arrayItem.point = marker.getLatLng();
			t.trigger('markerdragend', t, marker);
		});
		t.gMap.addOverlay( marker ) ;
	},
	dataDraw : function (){
		var t = this;
		t.gMap.clearOverlays() ;
		for (var i = 0; i < t.points.length; i++){
			var p = t.points[i].point.toUrlValue();
			p = p.split(',');
			t._createMarker(parseFloat(p[0]), parseFloat(p[1]), p.title, i);
		}
	}
};
mj.extend(mj.map, mj.component);
/**
* Menu ve Araç Çubuğu bileşenlerinin ortak sınıfı. 
* @class
* @extends mj.component
* @param {Object} config AÇIKLAMA
*/
mj.menu = function(config){
	mj.menu.superclass.constructor.call(this,config);
};
mj.menu.prototype = {
	componentClass : 'mj.menu',
	width : 200,
	style : 'horizontal',
	visible : true,
	alignTo : 'tl',//tr, bl, br
	subMenuAlign : 'bl',
	canHide : false,
	drag : false,
	cls : '',
	buttons : false,
	init : function(){
		var dsp = this.visible ? 'block' : 'none';	
		var t = this, n = mj.NE, el = t.el = n(t.renderTo, {cls: 'mj-menu-'+t.style+' '+t.cls, style:'display:'+dsp}), _el = t._el = $(el);
		t._renderTo = $(t.renderTo);
		t.menuConfig = t.menuConfig ||t.config;
		t.buttons = [];
		if(t.style=='vertical'){
			var _h = 0;
			$(t.items).each(function(){
				_h += (this=='|' || this[0]=='|') ? (t.style=='horizontal' ? 2 : 1) : 22;
			});
			_el.height(t.height = _h);
			_el.width(t.width);
		}
		$(t.items).each(function(){
			//t.buttons = [];
			if(this[0]=='|' || this=='|')
				t.addSplitter();
			else{
				if(this.html || (this[0]&&this[0].html)){
					t._el.append(this.html||this[0].html);
				}else{
					var btn = t.addButton(this);
					//t.buttons.push(btn);
					if(t.style=='vertical')
						btn.els.c.width(t.width-35-($.browser.msie ? 2 : 0));
				}
			}
		});
		t.on('itemclick', function(tbar, btn, btnId){
			if(t.canHide)
				t.hide();
			if(t.parent)
				t.parent.trigger('itemclick', t.parent, btn, btnId);
		});
		t.on('itemtoggle', function(tbar, btn, btnId){
			if(t.parent)
				t.parent.trigger('itemtoggle', t.parent, btn, btnId);
		});
		mj.menu.superclass.init.call(this);
	},
	addButton : function(config){
		var t = this;
		if(!t.buttons)
			t.buttons = [];
		mj.applyIf(config, {
			renderTo : t.el,
			menuConfig : t.menuConfig,
			parent : t,
			subMenuAlign : t.subMenuAlign,
			drag : t.drag||t.menuConfig.drag||mj.menu.prototype.drag,
			icon : t.icon,
			iconCls : t.iconCls
		});
		var btn = new mj.toolbutton(config);
		t.addRelated(btn);
		t.buttons.push(btn);
		if(t.style=='vertical')
			t._el.height(mj.oLength(t.buttons)*22);
		return btn;
	},
	addSplitter : function(){	
		mj.NE(this.el, {cls:'mj-menu-splitter',html:mj.insertSpacer()});
	},
	show : function(parentEl, position){
		var t=this, _el=t._el, top=0,left=0,x=0,y=0,pel = parentEl._el, ppos = pel.offset({ border: true, padding: true }), pw = pel.width(), ph = pel.height();
		switch(parentEl.subMenuAlign){
			case 'tl' :
				x = ppos.left;
				y = ppos.top;
				break;
			case 'tr' :
				x = ppos.left+pw;
				y = ppos.top;
				break;
			case 'bl' :
				x = ppos.left;
				y = ppos.top+ph;
				break;
			case 'br' :
				x = ppos.left+pw;
				y = ppos.top+ph-4;
				break;
		}
		t.showAt(x, y);
	},
	showAt : function(x,y){
		var t=this, _el=t._el, top=0,left=0,height=parseInt(_el[0].style.height),width=parseInt(_el[0].style.width);
		switch(t.alignTo){
			case 'tl' :
				left = x;
				top = y;
				break;
			case 'tr' :
				top = y;
				left = x-t.width;
				break;
			case 'bl' :
				left = x;
				top = y-height;
				break;
			case 'br' :
				top = y-height;
				left = x-t.width;
				break;
		}
		_el.css({position: 'absolute', top: top, left: left});
		if(t.parent){
			if(t.parent.parent.activeSub)
				t.parent.parent.activeSub.hide();
			t.parent.parent.activeSub=t;
		}
		var _hc = function(e){
			var p = e.target.parentNode, _p = $(p);
			t._hideCheck.call(t, e);
		};
		mj.bd.bind('mousedown', _hc);
		mj.bd.bind('dragstart', _hc);
		t.on('afterdestroy', function(){
			mj.bd.unbind('mousedown', _hc);
			mj.bd.unbind('dragstart', _hc);
		});
		_el.show();
	},
	_hideCheck:function(e){
		var p = $(e.target).hasParent(this.el);
		if(!p&&this.canHide)
			this.hide();
	},
	hide : function(){
		var t=this;
		if(t.canHide){
			if(t.parent)
				t.parent.parent.activeSub = null;
			t._el.hide();
		}
	},
	clear : function(){
		this.items=[];
		this.buttons=[];
		this._el.empty();
	},
	getItem : function(itemId, _items){
		var _items = _items ? _items : this.items;
		for(var i=0,l=_items.length;i<l;i++){
			if(_items[i].id == itemId)
				return _items[i];
			else if(_items[i].items && _items[i].items.length>0)
				return this.getItem(itemId, _items[i].items);
		}
		return false;
	}
};
mj.extend(mj.menu, mj.component);

mj.toolbutton = function(config){
	mj.toolbutton.superclass.constructor.call(this, config);
};
mj.toolbutton.prototype = {
	componentClass : 'mj.toolbutton',
	subMenuAlign : 'bl',
	type : 'default',
	drag : false,
	disabled:false,
	iconCls : '',
	init : function(){
		var elId = this.id ? ('mj-'+mj.genId()+'-'+this.id) : 'mj-'+mj.genId();
		this.id = this.id ? this.id : elId;
		var t = this, n = mj.NE, el = t.el = t.destroyEl = n(t.renderTo, {cls: 'mj-tool-btn mj-unselectable ',style : t.drag?'position:relative;':'',id:elId, title:mj.translate(t.alt), name:(t.name?t.name:elId)}), _el = t._el = $(el);
		t.els = {
			l : $(n(el, {cls:'mj-tool-btn-left',html:mj.insertSpacer(1,1)})),
			c : $(n(el, {cls:'mj-tool-btn-center'})),
			r : $(n(el, {cls:'mj-tool-btn-right',html:mj.insertSpacer(1,1)}))
		};
		if(t.disabled)
			t.setDisable();
		var style = '';
		if(t.iconCls)
			var iconCls = t.iconCls;
		if(t.icon)
			style += ';background:transparent url('+t.icon+') no-repeat';
		if(style!=='' && t.parent && t.parent.style=='horizontal')
			style += ';width:16px';
		if(t.parent.style=='horizontal' && !t.icon && !iconCls)
			style += 'width:0';
		t.els.ci = $(n(t.els.c, {cls:'mj-tool-btn-center-icon '+iconCls,style:style}));
		if(t.title){
			t.els.ct = $(n(t.els.c, {cls:'mj-tool-btn-center-text', html:mj.translate(t.title)}));
			t.els.ct.attr('unselectable','on');
		}
		if(t.items){
			t.els.csi = $(n(t.els.c, {cls:'mj-tool-btn-center-subicon',html:mj.insertSpacer(1,1)}));
			if(t.parent.style=='horizontal')
				_el.width(_el.width()+16);
			t.subMenu = new mj.menu({
				style : 'vertical',
				width : t.subMenuWidth||mj.menu.prototype.width,
				canHide : true,
				visible : false,
				parent : t,
				items : t.items,
				menuConfig : t.menuConfig,
				alignTo : t.alignTo||t.parent.alignTo||mj.menu.prototype.alingTo,
				subMenuAlign : t.subMenuAlign||t.parent.subMenuAlign||mj.menu.prototype.subMenuAlign,
				isSub : true
			});
			t.addRelated(t.subMenu);
		}
		var stopTimer = function(){
			if(t.subTimer){
				clearTimeout(t.subTimer);
				t.subTimer = null;
			}
		};
		if(t.drag){
			t.dragHandle = new mj.drag({el:_el,moving :false,position:'absolute',proxyEl:{width:30,height:30},parent : mj.bd});	
			t.dragHandle.on('beforedrag', function(_t,e){
				return !t.disabled;
			});
			t.dragHandle.on('beforedrag',function(_t,e){
				var p = this;	
				while(p.parent)
					p = p.parent;
				return p.trigger('beforedrag',_t,e,this);
			},t);
			t.dragHandle.on('dragstart',function(_t,e){
				var p = this;	
				while(p.parent)
					p = p.parent;
				p.trigger('dragstart',_t,e,this);
			},t);
			t.dragHandle.on('dragstop' ,function(_t){
				var p = this;	
				while(p.parent)
					p = p.parent;
				p.trigger('dragstop',_t,this);			
			},t);
		}	
		_el.hover(function(){
			if(!t.disabled){
				_el.addClass('mj-tool-btn-hover');
				if(t.subMenu&&!t.disabled)
					t.subTimer = setTimeout(function(){
						t.showSubMenu();
						stopTimer();
					}, mj.glb.menuDelay);
			}
		},function(){
			if(!t.disabled){
				_el.removeClass('mj-tool-btn-hover');
				stopTimer();
			}
		});
		_el.mouseout(function(){
			_el.removeClass("mj-tool-btn-down");
		});
		_el.mousedown(function(e){
			if(!t.disabled){
				_el.addClass("mj-tool-btn-down");
				if(t.type=='toggle'||t.type=='radio')
					e.stopPropagation();
			}
		});
		_el.mouseup(function(){
			_el.removeClass("mj-tool-btn-down");
		});
		_el.click(function(){
			if(!t.disabled)
				if(t.items)
					t.showSubMenu();
				else{
					t.trigger('click', t, t.id);
					if(t.parent && t.parent.events && t.parent.events.itemclick){
						if(t.parent.canHide && t.type=='default'){
							t.parent.hide();
							t.parent.trigger('itemclick', t.parent, t, t.id);
						}else
							t.parent.trigger('itemtoggle', t.parent, t, t.id);
					}
				}
		});
		t.on('itemclick' ,function(_t, b, bId){
			if(_t.parent && _t.parent.events && _t.parent.events.itemclick)
				_t.parent.trigger('itemclick', _t.parent, b, bId);
		});
		t.on('itemtoggle' ,function(_t, b, bId){
			if(_t.parent && _t.parent.events && _t.parent.events.itemclick)
				_t.parent.trigger('itemtoggle', _t.parent, b, bId);
		});
		if(t.handler)
			t.on('click', t.handler, t.scope);
		if(t.type=='toggle'){
			t.setToggle(t.state);
			t.on('click',t.toggle,t);
		}
		if(t.type=='radio'){
			t._el.addClass('mj-radio');
			if(t.state)
				t.setRadio(t.state);
			t.on('click',t.radio,t);
		}
		if(t._customRights){
			var _customRightsId = t._customRights.split(',');
			_customRightsId = _customRightsId[0];
			if(mj._renderingModule && mj._renderingModule._customRights && mj._renderingModule._customRights.indexOf(_customRightsId)>-1){
				t._el.addClass('mj-invisible');
				t.setHandler(function(){return false;},this);
			}
		}
		mj.toolbutton.superclass.init.call(this);
	},
	radio : function(){
		if(!this.disabled)
			this.setRadio(!this.state);
	},
	setRadio : function(value){
			var rBox = this._el.parent().find('div[@name="'+$(this).attr('name')+'"]');
			var items = this.parent.items;
			for(var i=0,len=items.length;i<len;i++){
				var elem = items[i];
				if(elem.type&&elem.type=='radio')
					elem.state=false;
					if(this.id==elem.id)
						elem.state=true;
			}
			rBox.removeClass('mj-radio-checked');
			this._el.addClass('mj-radio-checked');
		this.state = true;
	},
	setHandler : function(cb, scope){
		if(this.handler)
			this.mon('click', this.handler);
		this.handler = cb;
		this.scope = scope || this.scope || this;
		this.on('click', this.handler, this.scope);
	},
	setDisable : function(){
		this.disabled=true;
		this._el.addClass('mj-item-disabled');
	},
	setEnable : function(){
		this.disabled=false;
		this._el.removeClass('mj-item-disabled');
	},
	toggle : function(){
		this.setToggle(!this.state);
	},
	setAlt : function(alt){
		this.alt = alt;
		this._el.attr('title', alt);
	},
	setTitle : function(text){
		this.title = mj.translate(text);
		this.els.ct.text(this.title);
	},
	setToggle : function(value){
		if(value){
			this._el.removeClass('mj-toggle-unchecked');
			this._el.addClass('mj-toggle-checked');
		}else{
			this._el.removeClass('mj-toggle-checked');
			this._el.addClass('mj-toggle-unchecked');
		}
		this.state = value;
	},
	showSubMenu : function(){
		var t=this, m = t.subMenu;
		if(m)
			m.show(t, t.subMenuAlign);
	},
	hide : function(){
		if(!this.invisible){
			this._el.addClass('mj-invisible');
			this.invisible = true;
		}
	},
	show : function(){
		if(this.invisible){
			this._el.removeClass('mj-invisible');
			this.invisible = false;
		}
	}
};
mj.extend(mj.toolbutton, mj.component);
mj.contextmenu = function(config){
	config.clientArea = config._dontBindParent ? false : $(config.parent ? config.parent : mj.bd);
	config.parent = null;
	mj.contextmenu.superclass.constructor.call(this,config);
};
mj.contextmenu.prototype = {
	componentClass : 'mj.contextmenu',
	style : 'vertical',
	subMenuAlign : 'tr',
	canHide : true,
	visible : false,
	init : function(){
		if(this.clientArea)
			this.bindParent(this.clientArea);
		mj.contextmenu.superclass.init.call(this);
	},
	bindParent : function(p){
		var t = this;
		p = $(p);
		p.bind('contextmenu',function(e){
			t.trigger('show',t, e.pageX, e.pageY);
			t.showAt(e.pageX, e.pageY);
			e.preventDefault();
			e.stopPropagation();
		});
	}
};
mj.extend(mj.contextmenu, mj.menu);
/** 
 * @fileoverview View nesnesi.
 * @hazırlayan kk yazılım info@mj.com
 * @sürüm 0.0.1 16.10.2007
 */
/**
 * View nesnesi.
 * Örnek kullanımı aşağıdaki gibidir:
 * @example
	var a=[];
	a.push({id:'v-1',title:'deneme1',url:'../../images/trigger.gif'});
	a.push({id:'v-2',title:'deneme2',url:'../../images/trigger.gif'});
	a.push({id:'v-3',title:'deneme3',url:'../../images/trigger.gif'});
	a.push({id:'v-4',title:'deneme4',url:'../../images/trigger.gif'});
	var t=['<div class="thumb-wrap" id="{id}">',
	'<div class="thumb"><img src="{url}" title="{title}"></div>',
	'<span class="x-editable">{title}</span></div>']
	var view = new mj.view({				
		renderTo : mj.NE(mj.bd,{tag:'div',id:'view-cnt'}),
		store : new mj.store({data:a}),
		tpl : new mj.template(t),
		selector : 'div.thumb-wrap',
		multiSelect : true
	});
	//view.on('itemclick',function(){mj.log("1");});

 * @class
 * @name mj.view
 * @extends mj.component
 * @param {Object} config View objesini oluşturabilmek için gerekli olan parametreleri içerir. 
 * @config {HTMLElement} renderTo View nesnesinin render edileceği container nesnesi.
 * @config {Object} store View nesnesinin store nesnesi.
 * @config {Object} tpl View nesnesinin template'i.
 * @config {String} selector View nesnesinin selector'ü.Seçilebilen nesneleri select edebilecek selector.
 * @config {Boolean} multiSelect Çoklu seçim yapılabilmesi için gerekli parametre.<i>ctrl</i> ile birlikte çoklu seçime imkan verilmektedir.
	Ön tanımlı değeri:false.
 * @config {String} overClass View elementlerinin üzerinden mouse ile geçerken eklenecek class.
 * @config {String} selectedClass View elementlerinden seçilenleri belirtecek class.
 */
mj.view = function(config){
	mj.view.superclass.constructor.call(this, config);
};
mj.view.prototype = {
	componentClass : 'mj.view',
	/** 
	 * <i>ctrl</i> tuşu ile birlikte çoklu seçim yapışabilmesi isteniyorsa <i>true</i> olması gerekmektedir.Ön tanımlı değeri:false.
	 * @name multiSelect 
	 * @type {Boolean}
	 * @memberOf  mj.view
     */
	multiSelect : false,
	/** 
	 * View elementlerinin üzerinden mouse ile geçerken eklenecek class.
	 * @name overClass 
	 * @type {String}
	 * @memberOf  mj.view
     */
	overClass : 'view-over',
	/** 
	 * View elementlerinden seçilenleri belirtecek class.
	 * @name selectedClass 
	 * @type {String}
	 * @memberOf  mj.view
     */
	selectedClass : 'view-selected',
	items : [],
	selections : [],
	selected : [],
	loadMask : true,
	/**
	 * View nesnesi init fonksiyonu.Store'u load eder ve view'in load'unu çağırır.
	 * @name init
	 * @function
	 * @type {Function}
	 */
	init : function(){
		this.sel=[];
		this.cnt = $(this.renderTo);
		if(this.pbar&&typeof this.pbar.render=='function')
			this.pbar.render({scope:this});
		if(this.loadMask)
			this.mask = new mj.mask({el:this.cnt[0]});
		this.store.on('beforeload', function(){
			if(this.loadMask)
				this.mask.show(50);
		}, this);
		this.store.on('load',function(){
			this.load();
		},this);
		mj.bindResize(this.cnt, this.doLayout, this);
	},
	doLayout : function(){
		$(this.renderTo).kkresizeheight(this.cnt.height()-(this.pbar?25:0));
	},
	/**
	 * View'in elementlerini siler.
	 * @name removeAll
	 * @function
	 * @type {Function}
	 */
	removeAll : function(){
		this.clearSelections();
		this.items=[];
		$(this.renderTo).find('div').remove();
	},
	/**
	 * View'in elementlerini load eder.
	 * @name load
	 * @function
	 * @type {Function}
	 */
	load : function(){
		this.removeAll();
		if(this.filter){
			this.store.filter(this.filter.dI,this.filter.v);
			a=this.store.data;
		}else
			var a=this.store.data;
		if(!a)
			this.store.load();
		var tmp;
		for(b in a){
			tmp=a[b];
			if(typeof tmp!='function'){
				var el=this.tpl.apply(tmp);
				//var tplEl=$(mj.NE(this.renderTo,{tag:'div',id:mj.genId('view-el-'),html:el}));
				var tplEl=$(this.renderTo).append(el).find(this.selector+':last').attr('id',mj.genId('view-el-'));
				tmp.el = tplEl;
				if($.browser.msie)
					tplEl.attr('unselectable','on');
				var p={
					id:tplEl.attr('id'),
					el:mj.get(tplEl.attr('id')),
					jEL:tplEl,
					store:a[b],
					storeIndex:parseInt(b)
				};
				this.items.push(p);
				var t=this;
				tplEl.bind('click',{scope:this},function(e){
					var sc=t.view||t;
					sc.onClick(e);
				}).bind('dblclick',{scope:this},function(e){
					var sc=t.view||t;
					sc.onDblClick(e);
				}).bind('contextmenu',{scope:this},function(e){
					var sc=t.view||t;
					sc.onContextMenu(e);
				});
				
		        if(this.overClass){
					tplEl.hover(function(e){
								var sc=t.view||t;
								$(this).addClass(sc.overClass);
								sc.trigger('onItemOver',sc,this,e);
							},
							function(e){
								var sc=t.view||t;
								$(this).removeClass(sc.overClass);
								sc.trigger('onItemOut',sc,this,e);
							}
					);
		        }
			}
		}
		this.trigger('afterload',this);
		if(this.loadMask)
				this.mask.hide();
	},
	/**
	 * Seçilen view elementini geri döndürür.
	 * @name getViewEl
	 * @function
	 * @type {Function}
	 * @param {Object} e Event objesi.
	 * @return {Object} View elementi.
	 */
	getViewEl : function(e){
		return this.items[mj.getIndex(this.items,'id',$(e.target).parents(this.selector).attr('id')||$(e.target).attr('id'))];
	},
	/**
	 * Seçili view elementlerini temziler.
	 * @name clearSelections
	 * @function
	 * @type {Function}
	 */
	clearSelections : function(){
		$(this.renderTo).find(this.selector).removeClass(this.selectedClass);
		this.selections=[];
		this.selected=[];
		this.sel=[];
	},
	/**
	 * View'in onClick fonksiyonu.
	 * @name onClick
	 * @function
	 * @type {Function}
	 * @param {Object} e Event objesi.
	 */
	onClick : function(e){
		var item = this.getViewEl(e);
		this._onSelect(item,e);
		this.trigger('itemclick',this, item, e);
	},
	/**
	 * View'in _onSelect fonksiyonu.
	 * @name _onSelect
	 * @function
	 * @type {Function}
	 * @param {Object} item Seçilen view elementi.
	 * @param {Object} e Event objesi.
	 */
	_onSelect : function(item,e){
		if(e&&(!this.multiSelect||!e.ctrlKey))
			this.clearSelections();
		item.jEL.addClass(this.selectedClass);
		this.selections.push(item);
		var p=this.scope?
			{index:item.storeIndex,id:item.store[this.scope.idField],value:item.store[this.scope.displayField]}
			:{index:item.storeIndex,id:item.id,value:item.store.title};
		if(this.multiSelect){
			this.sel.push(p);
		}else{
			this.sel=p;
		}
		this.selected.push(this.sel);		
	},
	select : function(itemIndex){
		//if(this.selected[0].index!=itemIndex){
			//this.clearSelections();
			var item = this.items[itemIndex];
			if(item)
				this._onSelect(this.items[itemIndex]);
		//}
	},
	/**
	 * View'in onDblClick fonksiyonu.
	 * @name onDblClick
	 * @function
	 * @type {Function}
	 * @param {Object} e Event objesi.
	 */
	onDblClick : function(e){
		this.trigger('dblclick',this);
	},
	/**
	 * View'in onContextMenu fonksiyonu.
	 * @name onContextMenu
	 * @function
	 * @type {Function}
	 * @param {Object} e Event objesi.
	 */
	onContextMenu : function(e){
		e.preventDefault();
		this.trigger('contextmenu',this);
	}
};
mj.extend(mj.view, mj.component);
mj.form = function(config){
	mj.form.superclass.constructor.call(this, config);
};

mj.form.prototype = {
	componentClass : 'mj.form',
	method : 'POST',
	buttonPos : 'bottom',
	hasUpload : false,
	encoded : true,
	fieldSets : false,
	buttons : false,
	buttonAlign : 'right',
	init : function(){
		var t=this,r=t.renderTo,_r=t._r=$(r);
		t.fieldSets = [];
		var fc = {
			tag : 'form',
			method : t.method,
			cls : 'mj-form'
		};
		if(t.hasUpload)
			fc.enctype = 'multipart/form-data';
		
		if(t.buttons){
			if(t.buttonPos=='bottom'){
				t.cnt = $(mj.NE(_r,{tag:'div',style:'overflow:auto;height:'+(_r[0].style.height+';')}));
				t.buttonContainer = $(mj.NE(_r, {tag:'div',cls:'mj-form-buttons-container'}));
			}else if(t.buttonPos=='top'){
				t.buttonContainer = $(mj.NE(_r, {tag:'div',cls:'mj-form-buttons-container'}));
				t.cnt = $(mj.NE(_r,{tag:'div',style:'overflow:auto;height:'+(_r[0].style.height+';')}));
			}
			t.buttonConfigs = t.buttons;
			t.buttons = [];
			$(t.buttonConfigs).each(function(){
				t.addButton.call(t,this);
			});
		}else
			t.cnt = $(mj.NE(_r,{tag:'div',style:'overflow:auto;height:'+(_r[0].style.height+';')}));
		
		t.form = $(mj.NE(t.cnt, fc));
		if(!t.items)
			t.items = [];
		else
			for(var i=0,l=t.items.length;i<l;i++){
				var item = t.items[i];
				item.form = t;
				t.on('render', function(form){
					form.renderItem.call(form, this);
					form.addRelated(this);
				}, item);		
				if(item.componentClass=='mj.form.fileInput')
					t.hasUpload = true;
			}
		t.cachedItems = {};
		if(t.buttons)
			t.cnt.height(_r.height()-t.buttonContainer.height());
			// t.buttonContainer = $(mj.NE(_r, {tag:'div',cls:'mj-form-buttons-container'}));
			// $(t.buttons).each(function(){
				// t.addButton.call(t,this);
			// });
		// }
		mj.form.superclass.init.call(this);
		t.trigger('render' , t, t);
		mj.bindResize(t.cnt, t.doForm, t);
		this.modifiedFields = [];
		if(this.store)
			this.store.on('load',this.loadForm,this);
	},
	doForm : function(){
		this.cnt.height(this.renderTo.height()-(this.buttons?this.buttonContainer.height():0));
	},
	addButton : function(config){
		var t=this;
		if(!t.buttons)
			t.buttons = [];
		var b = config;
		if(!b.componentClass){
			mj.applyIf(b, {renderTo:mj.NE(t.buttonContainer)});
			b = new mj.button(b);
		}
		b.window = t;
		t.buttons.push(b);
	},
	renderItem : function(item,fieldSetIndex){
		if(typeof fieldSetIndex=='undefined')
			item.renderTo = this.form;
		else{
			if(typeof fieldSetIndex=='string'){
				fieldSetIndex = mj.getIndex(this.fieldSets,'id',fieldSetIndex);
				if(fieldSetIndex==-1)
					return;
			}
			item.renderTo = this.fieldSets[fieldSetIndex].fieldSetEl;
		}
		if(item.right){
			var t = this, i = t.items.indexOf(item);
			if(i>0&&typeof t.items[i-1]!='undefined' && t.items[i-1]._el)
				t.items[i-1]._el.css('float','left');
			item.itemStyle +='clear:none;float:left;margin-left:5px;';
		}
		item.render.call(item,this);
	},
	/*
	form.field'dan türetilmiş herhangi bir form elemanı(Ör: add(new mj.form.textField(...)); )
	*/
	add : function(item,fieldSetIndex){
		if(item.componentClass=='mj.form.fileInput'){
			this.hasUpload = true;
		}
		if(item.right){
			var len = this.items.length;
			if(len>0&&typeof this.items[len-1]!='undefined')
				this.items[len-1]._el.css('float','left');
			item.itemStyle +='clear:none;float:left;margin-left:5px;';
		}
		this.renderItem(item,fieldSetIndex);
		item.form = this;
		this.addRelated(item);
		if(typeof fieldSetIndex == 'string')
			this.items[this.items.getIndex('id',fieldSetIndex)].items.push(item);
		if(typeof fieldSetIndex == 'number')
			this.fieldSets[fieldSetIndex].items.push(item);
		this.items.push(item);
	},
	/*
	form.items içindeki elemanlardan name==fieldName olanı / fieldName sayısal verilirse items[fieldName] getirir
	*/
	getField : function(fieldName){
		if(this.cachedItems[fieldName])
			return this.cachedItems[fieldName];
		if(!isNaN(fieldName))
			return this.items[fieldName];
		for(var i=0,l=this.items.length;i<l;i++)
			if(this.items[i].name==fieldName||this.items[i].dataIndex==fieldName){
				this.cachedItems[fieldName] = this.items[i];
				return this.items[i];
			}
	},
	/*
	fN verilmezse tüm elemanların değerleri gelir
	fN string olarak verilirse istenen elemanın değeri gelir
	fN dizi olarak verilirse dizi içindeki elemanların değerleri gelir
	*/
	getValue : function(fieldName, raw){
		var r = {}, t = this;
		if(!fieldName){
			fieldName = [];
			if(!t.items || t.items.length==0)
				return r;
			var item;
			for(var i=0,l=t.items.length;i<l;i++){
				item = t.items[i];
				if(item.componentClass!='mj.form.fieldSet'&&item.componentClass!='mj.panel'&&(item.componentClass=='mj.form.triggerField'||item.componentClass=='mj.form.dateField'||!item.readOnly))
					fieldName.push(item.name ? item.name : (item.dataIndex ? item.dataIndex : i));
			}
		}
		if(typeof fieldName=='string')
			fieldName = [fieldName];
		for(var i=0,l=fieldName.length;i<l;i++){
			if(raw)
				r[fieldName[i]] = t.getField.call(t, fieldName[i]).getElValue();
			else
				r[fieldName[i]] = t.getField.call(t, fieldName[i]).getValue();
		};
		return r;
	},
	/*
	fN parametresi getValue gibi.
	değer olarak dom.value getirir
	*/
	getElValue  : function(fieldName){
		return this.getValue(fieldName, true);
	},
	/*
	nV = {itemName : itemValue, itemName2 : itemValue2, ...}
	*/
	setValue : function(nameValue, raw){
		for(var x in nameValue)
			if(typeof nameValue[x] != 'function'){
				var f;
				if(f = this.getField(x)){
					if(raw)
						f.setElValue(nameValue[x]);
					else
						f.setValue(nameValue[x]);
					if(f.componentClass == 'mj.form.triggerField' && typeof nameValue[x+'_lookup_'] != 'undefined')
						f.setValue(nameValue[x+'_lookup_'],true);
				}
			}
	},
	setElValue : function(nameValue){
		this.setValue(nameValue, true);
	},
	clear : function(){
		$(this.items).each(function(){
			if(typeof this.clear=='function')
				this.clear();
		});
	},
	removeAll : function(){
		this.clear();
		this.form.empty();
		var el;
		while(this.items.length>0){
			el = this.items[this.items.length-1];
			el.destroy();
			this.items.remove(el);
		}
		//this.items = [];
		this.cachedItems = {};
		this.modified = false;
		this.modifiedFields = [];
	},
	/**
	 * Formu submit eder.
	 * @name submit
	 * @function
	 * @type {Function}
	 * @param {Object} opt Parametreler
	 * @config {String} url Gönderilecek sayfa
	 * @config {String} method İstek yöntemi(POST/GET)
	 * @config {Boolean} encoded Kodlanmış(default:true)
	 * @config {Function} success 
	 * @config {Function} error 
	 */
	submit : function(opt){
		var S = opt.success;
		var F = opt.failure;
		if(S)
			delete opt.success;
		if(F)
			delete opt.failure;
		var defOpt = {
			url : this.url,
			type : this.method,
			encoded : this.encoded,
			success : function(data){
				//giyyin upload sorunu için eklendi. kaldırılabilir
				if(data.indexOf('<b>Fatal error</b>')>-1)
					F({msg:'Beklenmeyen bir hata oluştu!'});
				else{
					var d = eval('('+data+')');
					if(d)
						if(d.success&&S)
							S(d);
						if(!d.success&&F)
							F(d);
				}
			}
		};
		if(typeof opt=='string'){
			defOpt.url = opt;
			opt = defOpt;
		}
		mj.applyIf(opt, defOpt);
		var data = opt.encoded ? mj.escape(this.getValue().toJSONString()) : this.getValue().toJSONString();
		opt.data = 'data='+data;
		if(opt.params)
			for(var x in opt.params)
				if(typeof opt.params[x]!='function')
					opt.data += '&'+x+'='+opt.params[x];
		if(opt.url!=''){
			if(!this.hasUpload)
				$.ajax(opt);
			else{
				/*Alttaki bölüm jqForm plugin'inden alınmıştır
				URL : http://www.malsup.com/jquery/form/#getting-started
				SOURCE : http://jqueryjs.googlecode.com/svn/trunk/plugins/form/jquery.form.js
				*/
				var $form=$(this.form),options = opt;
				// private function for handling file uploads (hat tip to YAHOO!)
			    function fileUpload() {
			        var form = $form[0];
			        var opts = $.extend({}, $.ajaxSettings, options);

			        var id = 'jqFormIO' + mj.genId();//$.fn.ajaxSubmit.counter++;
			        var $io = $('<iframe id="' + id + '" name="' + id + '" />');
			        var io = $io[0];
			        var op8 = $.browser.opera && window.opera.version() < 9;
			        if ($.browser.msie || op8) io.src = 'javascript:false;document.write("");';
			        $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });

			        var xhr = { // mock object
			            responseText: null,
			            responseXML: null,
			            status: 0,
			            statusText: 'n/a',
			            getAllResponseHeaders: function() {},
			            getResponseHeader: function() {},
			            setRequestHeader: function() {}
			        };

			        var g = opts.global;
			        // trigger ajax global events so that activity/block indicators work like normal
			        if (g && ! $.active++) $.event.trigger("ajaxStart");
			        if (g) $.event.trigger("ajaxSend", [xhr, opts]);

			        var cbInvoked = 0;
			        var timedOut = 0;

			        // take a breath so that pending repaints get some cpu time before the upload starts
			        setTimeout(function() {
			            $io.appendTo('body');
			            // jQuery's event binding doesn't work for iframe events in IE
			            io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);

			            // make sure form attrs are set
			            var encAttr = form.encoding ? 'encoding' : 'enctype';
			            var t = $form.attr('target');
			            $form.attr({
			                target:   id,
			                method:  'POST',
			                action:   opts.url
			            });
			            form[encAttr] = 'multipart/form-data';

			            // support timout
			            if (opts.timeout)
			                setTimeout(function() { timedOut = true; cb(); }, opts.timeout);

			            form.submit();
			            $form.attr('target', t); // reset target
			        }, 10);

			        function cb() {
			            if (cbInvoked++) return;

			            io.detachEvent ? io.detachEvent('onload', cb) : io.removeEventListener('load', cb, false);

			            var ok = true;
			            try {
			                if (timedOut) throw 'timeout';
			                // extract the server response from the iframe
			                var data, doc;
			                doc = io.contentWindow ? io.contentWindow.document : io.contentDocument ? io.contentDocument : io.document;
			                xhr.responseText = doc.body ? doc.body.innerHTML : null;
			                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;

			                if (opts.dataType == 'json' || opts.dataType == 'script') {
			                    var ta = doc.getElementsByTagName('textarea')[0];
			                    data = ta ? ta.value : xhr.responseText;
			                    if (opts.dataType == 'json')
			                        eval("data = " + data);
			                    else
			                        $.globalEval(data);
			                }
			                else if (opts.dataType == 'xml') {
			                    data = xhr.responseXML;
			                    if (!data && xhr.responseText != null)
			                        data = toXml(xhr.responseText);
			                }
			                else {
			                    data = xhr.responseText;
			                }
			            }
			            catch(e){
			                ok = false;
			                $.handleError(opts, xhr, 'error', e);
			            }

			            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
			            if (ok) {
			                opts.success(data, 'success');
			                if (g) $.event.trigger("ajaxSuccess", [xhr, opts]);
			            }
			            if (g) $.event.trigger("ajaxComplete", [xhr, opts]);
			            if (g && ! --$.active) $.event.trigger("ajaxStop");
			            if (opts.complete) opts.complete(xhr, ok ? 'success' : 'error');

			            // clean up
			            setTimeout(function() {
			                $io.remove();
			                xhr.responseXML = null;
			            }, 100);
			        };

			        function toXml(s, doc) {
			            if (window.ActiveXObject) {
			                doc = new ActiveXObject('Microsoft.XMLDOM');
			                doc.async = 'false';
			                doc.loadXML(s);
			            }
			            else
			                doc = (new DOMParser()).parseFromString(s, 'text/xml');
			            return (doc && doc.documentElement && doc.documentElement.tagName != 'parsererror') ? doc : null;
			        };
			    };
				fileUpload();
			}
		}
	},
	loadForm : function(){
		if(this.store && this.store.data.length>0){
			var items = this.items, data = this.store.data[0];
			for(var i=0,len=items.length;i<len;i++)
				if(items[i].dataIndex){
					//if(typeof items[i].setCmbValue == 'function')
					//	items[i].setCmbValue(data[items[i].dataIndex]);
					//else
					items[i].setValue(data[items[i].dataIndex]);
					if(items[i].componentClass == 'mj.form.triggerField')
						items[i].setValue(data[items[i].dataIndex+'_lookup_'],true);
					if(items[i].componentClass == 'mj.form.combo' && items[i].sameValueDisplay)
						items[i].setElValue(data[items[i].dataIndex]);
				}
		}
	},
	load : function(){
		this.store.load();
	},
	startLoad : function(){
		this.loading = true;
		this.modified = false;
		this.modifiedFields = [];
	},
	finishLoad : function(){
		this.loading = false;
	},
	setModified : function(field){
		this.modified = true;
		if(this.modifiedFields.indexOf(field)==-1)
			this.modifiedFields.push(field);
	}
};

mj.extend(mj.form, mj.component);
mj.form.field = function(config){
	mj.form.field.superclass.constructor.call(this,config);
};
mj.form.field.prototype = {
	componentClass : 'mj.form.field',
	labelWidth : '75px',
	labelAlign : 'left',
	itemCls : 'mj-form-item',
	titleCls : 'mj-form-caption',
	inputCls : 'mj-form-input',
	hidden : false,
	readOnly : false,
	disabled : false,
	left : false,
	top : false,
	type : 'text',
	tag : 'input',
	labelPos : 'left',
	itemStyle : '',
	emptyValue : null,
	render : function(){
		var t = this, n = mj.NE, v='';
		if(t.hidden)
			t.itemCls += ' mj-invisible';
		if(t.left||t.top){
			t.left = typeof t.left != 'undefined' ? (isNaN(t.left) ? t.left : (t.left+'px')) : '';
			t.top = typeof t.top != 'undefined' ? (isNaN(t.top) ? t.top : (t.top+'px')) : '';
			v = 'position:absolute;left:'+t.left+';top:'+t.top;
		}
		var el = t.destroyEl = t.el = n(t.renderTo, {cls:t.itemCls,style:v+';'+t.itemStyle}), _el = t._el = $(el);
		if(t.title)
			t.titleEl = n(el, {html:this.title, cls:t.titleCls+(t.labelPos=='top'?' '+t.titleCls+'-top':''), style:'width:'+t.labelWidth+';text-align:'+t.labelAlign});
		var _w = t.width?('width:'+t.width + (isNaN(t.width)?'':'px;')):'';
		t.input = $(n(el, {tag:t.tag,id:(t.id||mj.genId('mj-form-item-')),style:''+(t.height?'height:'+t.height+'px;':'')+_w,type:t.type,cls:t.inputCls,MAXLENGTH:t.maxLength,readonly:t.readOnly,disabled:t.disabled,name:t.name}));
		//if(t.title && t.labelPos == 'right')
		//	t.titleEl = n(el, {tag:'label',html:this.title, cls:t.titleCls, style:'width:'+t.labelWidth+';text-align:'+t.labelAlign});
		t.input.focus(function(){
			mj._activeFormElement = t;
			t.trigger('focus', t);
		});
		t.input.blur(function(){
			t.trigger('blur', t, t);
		});
		t.on('blur', function(){
			t._onBlur.call(t);
		});
		t.input.keyup(function(){
			t.trigger('change', t);
		});
		if(t._customRights){
			var _customRightsId = t._customRights.split(',');
			_customRightsId = _customRightsId[0];
			if(mj._renderingModule && mj._renderingModule._customRights && mj._renderingModule._customRights.indexOf(_customRightsId)>-1){
				t._el.addClass('mj-invisible');
			}
		}
		t.trigger('render', t);
	},
	setTitle : function(text){
		if(t.titleEl){
			this.title = text;
			$(this.titleEl).text(this.title);
		}
	},
	getValue : function(raw){
		if(raw)
			return this.input[0].value;
		else
			return this.value;//return this.value!==''?this.value:null;
	},
	getElValue : function(){
		return this.getValue(true);
	},
	formatValue : function(value){
		return value;
	},
	setValue : function(val){
		//val = this.readOnly && val == '' ? this.emptyValue : val;
		if(this.validate(val)!==false){
			this.value = val;
			this.setElValue(this.formatValue(val));
			if(this.form && !this.form.loading)
				this.form.setModified(this);
		}
	},
	setElValue : function(val){
		this.input[0].value = val;
	},
	clear : function(){
		this.setValue('');
	},
	validate : function(val){
	},
	clearValidate : function(){
		this.orjValidate = this.validate;
		this.validate = function(){return true;};
	},
	setOldValidate : function(){
		this.validate = this.orjValidate;
		this.orjValidate = null;
	},
	clearInvalid : function(){
		if(this.input){
			this.input.removeClass('mj-text-input-invalid');
			this.invalid=false;
		}
	},
	markInvalid : function(msg){
		if(this.input){
			this.input.addClass('mj-text-input-invalid');
			this.invalid=true;
			this.trigger('invalid',this,msg);
		}
	},
	setPos : function(x, y){
		this._el.css({
			position : 'absolute',
			left : x,
			top : y
		});
	},
	setWidth : function(width){
		this._el.width(width);
		if(this.title)
			width-=this.labelWidth;
		this.input.width(width-($.browser.msie?6:5));
	},
	_onBlur : function(){
		if(!this.readOnly){
			this.setValue(this.getElValue());
			if(mj._activeFormElement==this)
				mj._activeFormElement = null;
		}
	},
	_onChange : function(){
		if(!this.readOnly)
			this.setValue(this.getElValue());
	},
	setDisable : function(){
		this.input.attr('readonly', 'true');
		this.input.attr('disabled', 'true');
		this.disabled = true;
	},
	setEnable : function(){
		this.input.attr('readonly', 'false');
		this.input.attr('disabled', 'false');
		this.disabled = false;
	}
};
mj.extend(mj.form.field, mj.component);
mj.form.textField = function(config){
	mj.form.textField.superclass.constructor.call(this,config);
};
mj.form.textField.prototype = {
	componentClass : 'mj.form.textField',
	inputCls : 'mj-text-editor',
	init : function(){
		var t = this;
		t.on('render', t._onRender, t);	
		if(t.renderTo)
			t.render();
		//t.on('render', t._onRender, t);	
		mj.form.textField.superclass.init.call(this);
	},
	_onRender : function(){
		var t=this;
		if(t.width)
			t.input.width(t.width);
		t.input.focus(function(){
			t.input.addClass('focus');
			//t.trigger('focus', t);
		});
		t.input.blur(function(){
			t.input.removeClass('focus');
			//t.trigger('blur', t);
		});
	},
	focus : function(){
		this.input.focus();
	}
};
mj.extend(mj.form.textField, mj.form.field);
mj.initEditor = function(id, config){
	if(config && config.style=='small'){
		var small = new WYSIWYG.Settings();
		small.ImagesDir = mj.glb.openwysiwyg+"images/";
		small.PopupsDir = mj.glb.openwysiwyg+"popups/";
		small.Width = "355px";
		small.Height = "100px";
		small.DefaultStyle = "font-family: Tahoma, helvetica, arial, sans-serif;font-size:11px;";
		small.Toolbar[0] = new Array("font", "fontsize", "bold", "italic", "underline","unorderedlist","orderedlist","outdent", "indent","inserttable","viewSource"); // small setup for toolbar 1
		small.Toolbar[1] = ""; // disable toolbar 2
		small.StatusBarEnabled = false;
		var settings = small;
	}else{
		var full = new WYSIWYG.Settings();
		full.ImagesDir = mj.glb.openwysiwyg+"images/";
		full.PopupsDir = mj.glb.openwysiwyg+"popups/";
		//::full.CSSFile = "../res/openwysiwyg/styles/wysiwyg.css";
		full.Width = "410px";
		full.Height = "200px";
		// customize toolbar buttons
		full.addToolbarElement("font", 3, 1); 
		full.addToolbarElement("fontsize", 3, 2);
		// openImageLibrary addon implementation
		full.ImagePopupFile = mj.glb.openwysiwyg+"addons/imagelibrary/insert_image.php";
		full.ImagePopupWidth = 600;
		full.ImagePopupHeight = 245;

		var settings = full;
	}
	if(config && config.toolbar){
		if(config.toolbar[0])
			settings.Toolbar[0] = settings.Toolbar[0].concat(config.toolbar[0]);
		if(config.toolbar[1])
			settings.Toolbar[1] = settings.Toolbar[1].concat(config.toolbar[1]);
	}
	mj.apply(settings, config);
	WYSIWYG.setSettings(id, settings);
	//::WYSIWYG_Core.includeCSS(WYSIWYG.config[id].CSSFile);
	WYSIWYG._generate(id, settings);
};

mj.form.textArea = function(config){
	mj.form.textArea.superclass.constructor.call(this, config);
};

mj.form.textArea.prototype = {
	componentClass : 'mj.form.textArea',
	inputCls : 'mj-text-area',
	type : 'textarea',
	tag : 'textArea',
	editor : false,
	init : function(){
		var t = this;
		t.on('render', t._onRender, t);
		if(t.renderTo)
			t.render();
		mj.form.textArea.superclass.init.call(this);
	},
	_onRender : function(){
		if(this.editor)
			mj.initEditor(this.id, this.config);
		//mj.form.textArea.superclass.init.call(this);
	},
	/*getEditorValue : function(raw){
		if(!this.editor) return false;
		var val=this.input.next().find('iframe:first')[0].contentDocument.body.innerHTML
		this.setValue(val)
		return this.getValue(raw);
	},*/
	getValue : function(raw){
		if(this.editor){
			var val=$('div#'+this.input[0].id+'_1 iframe')[0].contentWindow.document.body.innerHTML;
			this.setValue(val);
		}
		if(raw)
			return this.input[0].value;
		else
			return this.value;
	},
	setValue : function(val){
		if(this.validate(val)!==false){
			this.value = val;
			this.setElValue(this.formatValue(val));
			if(this.editor)
				$('div#'+this.input[0].id+'_1 iframe')[0].contentWindow.document.body.innerHTML=val;
		}
	}
};

mj.extend(mj.form.textArea, mj.form.field);
mj.form.regExField = function(config){
	mj.apply(this, {
	    invalidText : mj.lng.objects.regExField.invalidText
	});
	mj.form.regExField.superclass.constructor.call(this,config);
};
mj.form.regExField.prototype = {
	componentClass : 'mj.form.regExField',
	regEx : false,
	init : function(){
		var t = this;
		t.on('render', t._onRender, t);	
		if(t.renderTo)
			t.render();
		t.on('invalid', function(a,b,c,d){
			new mj.message({
				title : mj.lng.glb.info,
				msg : b,
				modal : true
			});
		}, t);	
		mj.form.regExField.superclass.init.call(this);
	},
	validate : function(val){
		this.clearInvalid();
		var ret = true;
		if(val!=''&&val!=null){
			ret = this.regEx.test(val);
			if(!ret)
				this.markInvalid(this.invalidText);
		}
		return ret;
	}
};
mj.extend(mj.form.regExField, mj.form.textField);
mj.form.timeField = function(config){
	mj.form.timeField.superclass.constructor.call(this,config);
	// mj.apply(this, {
	    // invalidText : mj.lng.objects.timeField.invalidText
	// });
};
mj.form.timeField.prototype = {
	componentClass : 'mj.form.timeField',
	regEx : /^([01]\d|2[0-3]):([0-5][0-9])$/,
	init : function(){
		this.invalidText = mj.lng.objects.timeField.invalidText;
		mj.form.timeField.superclass.init.call(this);
	}
};
mj.extend(mj.form.timeField, mj.form.regExField);
mj.form.mailField = function(config){
	mj.form.mailField.superclass.constructor.call(this,config);
};
mj.form.mailField.prototype = {
	componentClass : 'mj.form.mailField',
	regEx : /^(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}$/,
	init : function(){
		this.invalidText = mj.lng.objects.mailField.invalidText;
		mj.form.mailField.superclass.init.call(this);
	}
};
mj.extend(mj.form.mailField, mj.form.regExField);
mj.form.passField = function(config){
	mj.form.passField.superclass.constructor.call(this,config);
	// mj.apply(this, {
		// invalidText : mj.lng.objects.passField.invalidText
	// });
};
mj.form.passField.prototype = {
	componentClass : 'mj.form.passField',
	//regEx : /^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{4,15}$/,
	regEx : /^[a-zA-Z]\w{3,15}$/,
	init : function(){
		this.type = 'password';
		this.invalidText = mj.lng.objects.passField.invalidText;
		mj.form.passField.superclass.init.call(this);
	}
};
mj.extend(mj.form.passField, mj.form.regExField);
mj.form.checkBox = function(config){
	mj.form.checkBox.superclass.constructor.call(this,config);
};
mj.form.checkBox.prototype = {
	componentClass : 'mj.form.checkBox',
	inputCls : 'mj-text-editor',
	type : 'checkbox',
	labelPos : 'left',
	checked : false,
	cls : 'mj-checkbox',
	init : function(){
		var t = this;
		t.on('render', t._onRender, t);		
		if(t.renderTo)
			t.render();
		mj.form.checkBox.superclass.init.call(this);
	},
	_onRender : function(){
		var t=this;
		t.check = $(mj.NE(t._el,{tag:'div',cls:t.cls,disabled:t.disabled}));
		t.input.addClass('mj-invisible');
		if(t.disabled){
			t.check.attr('disabled',true);
			t.check.addClass('mj-item-disabled');
		}
		if(t.readOnly){
			t.check.attr('readonly',true);
			t.check.addClass('mj-item-readOnly');
		}
		if(!t.readOnly&&!t.disabled){
			t.check.click(function(){
				var cBox = $(this);
				var ch = cBox.prev()[0].checked == true;
				cBox.toggleClass(t.cls+'-checked');
				cBox.prev()[0].checked = !ch;
				t.checked = !ch;
				if(typeof t.handler == 'function')
					t.handler();
			});
		}
		if(t.checked)
			t.setValue(t.checked);
	},
	getValue : function(raw){
		if(raw)
			return this.input[0].checked;
		else
			return this.checked;
	},
	setValue : function(val){
		if(typeof val == "string")
			val = parseInt(val);
		if(this.validate(val)!==false){
			this.checked = Boolean(val);
			this.setElValue(this.formatValue(Boolean(val)));
		}
	},
	setElValue : function(val){
		if(typeof val == "string")
			val = parseInt(val);
		this.input[0].checked = val;
		if(val==true)
			this.check.addClass(this.cls+'-checked');
		else
			this.check.removeClass(this.cls+'-checked');
	}
};
mj.extend(mj.form.checkBox, mj.form.field);
mj.form.radio = function(config){
	mj.form.radio.superclass.constructor.call(this,config);
};
mj.form.radio.prototype = {
	componentClass : 'mj.form.radio',
	inputCls : 'mj-text-editor',
	//type : 'radio',
	labelPos : 'left',
	width : 50,
	checks : false,
	checked : false,
	template : ['<div class="mj-radio" name="{name}" style="width:{width}px;">',
		'<input class="mj-invisible" type="text" value="{id}"/>',
		'<span unselectable="on" class="mj-unselectable" title="{desc}" style="padding-left: 16px; cursor: default;">{text}</span>',
		'</div>'],
	init : function(){
		var t = this;
		t.tpl = new mj.template(this.template);
		if(t.items&&!t.store)
			t.store = new mj.store({data:t.items});
		if(t.store&&!t.items)
			t.items = t.store.data;
		t.on('render', t._onRender, t);		
		if(t.renderTo)
			t.render();
		mj.form.radio.superclass.init.call(this);
	},
	_onRender : function(){
		var t=this;
		this.input.addClass('mj-invisible');
		if(this.items){
			this.checks=[];
			this.radioContainer = $(mj.NE(this._el,{style:'float:left;',disabled:this.disabled,readonly:this.readOnly}));
			for(var i=0,len=this.items.length;i<len;i++){
				var item = this.items[i];
				this.addItem(item,true);
			}
		}
	},
	addItem : function(item,noAdd){
		//var itemEl = $(mj.NE(this.radioContainer,{tag:'div',cls:'mj-radio',disabled:item.disabled,readonly:item.readOnly,name:this.name,html:'<input type="text" class="mj-invisible" value="'+item.id+'"></input><span style="padding-left:15px;cursor:default;">'+item.text+'</span>'}));
		item.name=this.dataIndex;
		if(!item.width)
			item.width=this.width;
		var el=this.tpl.apply(item);
		var itemEl=this.radioContainer.append(el).find('div:last');
		if(item.checked)
			$(itemEl).addClass('mj-radio-checked');
		if(item.disabled){
			itemEl.attr('disabled',true);
			itemEl.addClass('mj-item-disabled');
		}
		if(item.readOnly){
			itemEl.attr('readonly',true);
			itemEl.addClass('mj-item-readOnly');
		}
		if(!noAdd)
			this.items.push(item);
		if(!this.readOnly&&!this.disabled&&!item.readOnly&&!item.disabled){
			itemEl.bind('click',{scope:this},function(e){
				var scp = e.data.scope;
				scp.trigger('itemclick',item);
				var rBox = $(this).parent().find('div[@name="'+$(this).attr('name')+'"]');
				rBox.removeClass('mj-radio-checked');
				scp.setValue($(this).find('input').val());
				if(typeof scp.handler == 'function')
					scp.handler();
			});
		}
		this.checks.push(itemEl);
	},
	setElValue : function(val){
		if(typeof val == "string")
			val = parseInt(val);
		this.input[0].value = val;
		for(var i=0,len=this.items.length;i<len;i++){
			var item = this.items[i];
			if(item.id==val)
				this.checks[i].addClass('mj-radio-checked');
			else
				this.checks[i].removeClass('mj-radio-checked');
		}
	}
};
mj.extend(mj.form.radio, mj.form.field);
mj.form.numberField = function(config){
	mj.apply(this, {
		minText : mj.lng.objects.numberField.minText,
	    maxText : mj.lng.objects.numberField.maxText,
	    nanText : mj.lng.objects.numberField.nanText
	});
	mj.form.numberField.superclass.constructor.call(this,config);
};
mj.form.numberField.prototype = {
	componentClass : 'mj.form.numberField',
	inputCls : 'mj-text-editor',
	decimalSeparator:',',
	groupingSeparator:'.',
	decimalPrecision:2,
	decimalPrecisionReal:2,
	prefix:'',
	suffix:' YTL',
	defaultZero : false,
	allowDecimals:true,
	allowNegative:true,
	allowGroupingEnter:true,
	money : false,
    minValue : Number.NEGATIVE_INFINITY,
    maxValue : Number.MAX_VALUE,
	_onRender : function(){
		var t = this;	
		if(!t.money){
			t.allowDecimals=false;
			t.allowGroupingEnter=false;
			t.decimalSeparator='';
			t.groupingSeparator='';
			t.decimalPrecision=0;
			t.decimalPrecisionReal=0;
			t.suffix='';
		}
		mj.form.numberField.superclass._onRender.call(this);
        var keyPress = function(e){
            var k = e.keyCode || e.charCode;
            if(!$.browser.msie && (mj.keys.isSpecial(e) || k == mj.keys.BACKSPACE || k == mj.keys.DELETE)){
                return;
            }
			var allowed = "0123456789";
			var val = t.input[0].value;
			allowed+=t.allowDecimals&&val.indexOf(t.decimalSeparator)===-1?t.decimalSeparator:'';
			allowed+=t.allowNegative&&val.indexOf('-')===-1?'-':'';
			allowed+=t.allowGroupingEnter?t.groupingSeparator:'';
            if(allowed.indexOf(String.fromCharCode(k)) === -1){
                return false;
            }
        };
		t.on('focus', t._onFocus);
        t.input.keypress(keyPress);	
		t.input[0].style.textAlign = 'right';
	},
	_onBlur : function(){
		if(!this.readOnly){
			this.clearValue();
			this.setValue(this.getElValue());
		}
	},
	_onFocus : function(){
		if(!this.readOnly){
			this.value=this.value||'';
			var val = (this.decimalSeparator!='.')?(this.value+'').replace(/\./g,this.decimalSeparator):this.value;
			this.setElValue(val);
		}
	},
	clearValue : function(){
		var val=this.input[0].value;
		if(this.allowGroupingEnter){
			var pattern = new RegExp(('\\'+this.groupingSeparator),"g");
			val = val.replace(pattern,'');
		}
		if(this.decimalSeparator!=''&&this.decimalSeparator!='.'){
			var pattern = new RegExp(('\\'+this.decimalSeparator),"g");
			val = val.replace(pattern,'.');
		}
		this.input[0].value = val;
	},
	setValue : function(val){
		//if(typeof val=='number'&&this.validate(val)!==false){
		val = ((this.defaultZero&&val=='')?0:((val=='' && !this.emptyValue && typeof this.emptyValue == 'object') ? this.emptyValue : val));
		//val = this.readOnly && val == '' ? this.emptyValue : val;
		if(val==this.emptyValue){
			this.value = val;
			this.setElValue('');
			if(this.form && !this.form.loading)
				this.form.setModified(this);
		}else
			if(((val!=''&&val!=null)||typeof val=='number')&&this.validate(val)!==false){
				this.value = parseFloat(val);
				if(this.decimalPrecisionReal&&!isNaN(this.decimalPrecisionReal))
					val=parseFloat(val).toFixed(this.decimalPrecisionReal);
				this.setElValue(this.formatValue(val));
				if(this.form && !this.form.loading)
					this.form.setModified(this);
			}
	},
	clearInvalid : function(){
		this.input.removeClass('mj-text-input-invalid');
	},
	markInvalid : function(msg){
		this.input.addClass('mj-text-input-invalid');
		this.trigger('invalid',this,msg);
	},
	validate : function(val){
		this.clearInvalid();
		if(isNaN(val)){
            this.markInvalid(String.format(this.nanText, this.minValue));
			return false;
		}
        if(val < this.minValue){
            this.markInvalid(String.format(this.minText, this.minValue));
			return false;
        }
        if(val > this.maxValue){
            this.markInvalid(String.format(this.maxText, this.maxValue));
			return false;
        }
		return true;
	},
	formatValue : function(value){
		return this.prefix + mj.format.float2Money(value,this.decimalPrecision,this.decimalSeparator,this.groupingSeparator) + this.suffix;
	},
	clear : function(){
		this.value = null;
		this.setElValue('');
	}
};
mj.extend(mj.form.numberField, mj.form.textField);
/** 
 * @fileoverview triggerField nesnesi.
 * @hazırlayan kk yazılım info@mj.com
 * @sürüm 0.0.1 02.10.2007
 */
 /**
 * triggerField nesnesi.
 * Örnek kullanımı aşağıdaki gibidir:
 * @example
	var edt1 = new mj.form.triggerField({
		renderTo :  mj.NE(mj.bd,{style:'padding:10px'}),
		triggerClass:'trigger-field',
		title : 'eww',
		onTriggerClick : function(){
			alert("1");
		}
	});

 * @class
 * @name mj.form.triggerField
 * @extends mj.form.textField
 * @param {Object} config triggerField objesini oluşturabilmek için gerekli olan parametreleri içerir. 
 * @config {HTMLElement} renderTo triggerField nesnesinin render edileceği container nesnesi.
 * @config {String} triggerClass Özel trigger buton imajı kullanımı gerektiğinde kullanılmalıdır.
 * @config {String} title triggerField yanındaki form elementi başlık değeri.
 * @config {Function} onTriggerClick triggerField trigger butonuna tıklandığında olan olayları içeren fonksiyon.
 */
mj.form.triggerField = function(config){
	if(config.width)
		config.width-=17;
	mj.form.triggerField.superclass.constructor.call(this,config);
};
mj.form.triggerField.prototype = {
	componentClass : 'mj.form.triggerField',
	inputCls : 'mj-text-editor',
	triggerClass : 'trigger-field',
	/** 
	 * .Ön tanımlı değeri:false.
	 * @name readOnly 
	 * @type {Boolean}
	 * @memberOf mj.form.triggerField
     */
	readOnly : true,
	_onRender : function(){
		mj.form.triggerField.superclass._onRender.call(this);
		var tag, t = this;
		//if($.browser.msie)
			tag='div';
		//else
			//tag='img';
		t.triggerField =  $(mj.NE(t.input[0].parentNode,{tag: tag, cls: "trigger " + t.triggerClass}));
		t.triggerField.hover(function(){
				$(this).addClass('trigger-arrow-over');
			},
			function(){
				$(this).removeClass('trigger-arrow-over');
			}
		);
		t.triggerField.mousedown(function(){
			t.triggerField.addClass('trigger-arrow-click');
		});
		t.triggerField.mouseup(function(){
			t.triggerField.removeClass('trigger-arrow-click');
		});
		t.triggerField.click(function(e){
			if(!t.disabled){
				t.trigger('triggerclick', t);
				e.stopPropagation();
			}
		});
		t.on('triggerclick',t.onTriggerClick);
		mj.bd.bind('click', t.hideAll);
		t.on('afterdestroy', function(){
			mj.bd.unbind('click', t.hideAll);
		});
	},
	hideAll : function(){
		el = mj.glb.views;
		for(var i=0,len=el.length;i<len;i++)
			if(typeof el[i]._hide == 'function')
				el[i]._hide();
		mj.glb.views = [];
	},
	onTriggerClick : function(){
		this.hideAll();
		if(typeof this.handler == 'function')
			this.handler();
	},
	getPosition : function(){
		var ofs = $.browser.msie?this.input.prev().offset():this.input.offset();
		if ($.browser.msie&&this.labelAlign=='left') ofs.left=ofs.left+parseInt(this.labelWidth);
		return ofs;
	},
	getValue : function(raw){
		if(raw)
			return this.input[0].value;
		else
			return this.value!==''?this.value:null;
	},
	setWidth : function(width){
		this._el.width(width);
		if(this.title)
			width-=this.labelWidth;
		this.input.width(width-($.browser.msie?23:22));	
	},
	setValue : function(val,trigger){
		if(trigger)
			this.value = val;
		else
			if(this.validate(val)!==false){
				this.displayValue = val;
				this.setElValue(this.formatValue(this.displayValue));
			}
	},
	clear : function(){
		this.setValue('');
		this.setValue('',true);
	},
	setDisable : function(){
		this.triggerField.addClass(this.triggerClass+'-disabled');
		mj.form.triggerField.superclass.setDisable.call(this);
	},
	setEnable : function(){
		this.triggerField.removeClass(this.triggerClass+'-disabled');
		mj.form.triggerField.superclass.setEnable.call(this);
	}
};
mj.extend(mj.form.triggerField, mj.form.textField);
/** 
 * @fileoverview Combo nesnesi.
 * @hazırlayan kk yazılım info@mj.com
 * @sürüm 0.0.1 17.10.2007
 */
 /**
 * Combo nesnesi.
 * Örnek kullanımı aşağıdaki gibidir:
 * @example
	var a=[];
	a.push({id:'deneme1',text:'../'});
	a.push({id:'deneme2',text:'../../'});
	a.push({id:'deneme3',text:'../../images/'});
	a.push({id:'deneme4',text:'../../images/trigger.gif'});
	var cmb1 = new mj.form.combo({
		renderTo :  mj.NE(mj.bd,{style:'padding:10px'}),
		title : 'wwwwww',
		store : new mj.store({data:a}),
		width : 200
	});
	cmb1.setValue('deneme2');
	var cmb2 = new mj.form.combo({
		renderTo :  mj.NE(mj.bd,{style:'padding:10px'}),
		title : 'cccc',
		mode : 'remote',
		store : new mj.store({
				url : '../tree/data.php',
				params : {
					event : 'getCombo'
				}
			}),
		width : 250
	});

 * @class
 * @name mj.Combo
 * @extends mj.form.triggerField
 * @param {Object} config Combo objesini oluşturabilmek için gerekli olan parametreleri içerir. 
 * @config {HTMLElement} renderTo Combo nesnesinin render edileceği container nesnesi.
 * @config {Object} store Combo store objesi.
 * @config {String} title Combo yanındaki form elementi başlık değeri.
 * @config {Number} width Combo genişlik değeri.
 * @config {String} mode Combo çalışma modu.Ön tanımlı değeri:local.
 * @config {Number} maxHeight Combo view yükseklik değeri.Ön tanımlı değeri:200.
 * @config {String} idField Combo elementi id alan adı.Ön tanımlı değeri:id.
 * @config {String} displayField Combo elementi display alan adı.Ön tanımlı değeri:text.
 */
mj.form.combo = function(config){
	mj.form.combo.superclass.constructor.call(this,config);
};
mj.form.combo.prototype = {
	componentClass : 'mj.form.combo',
	triggerClass : '',
	/** 
	 * Combo elementi id alan adı.Ön tanımlı değeri:id.
	 * @name idField 
	 * @type {String}
	 * @memberOf  mj.combo
     */
	idField : 'id',
	/** 
	 * Combo elementi display alan adı.Ön tanımlı değeri:text.
	 * @name displayField 
	 * @type {String}
	 * @memberOf  mj.combo
     */
	displayField : 'text',
	/** 
	 * Combo çalışma modu.Ön tanımlı değeri:local.
	 * @name mode 
	 * @type {String}
	 * @memberOf  mj.combo
     */
    mode: 'local',
	/** 
	 * Combo view yükseklik değeri.Ön tanımlı değeri:200.
	 * @name maxHeight 
	 * @type {Number}
	 * @memberOf  mj.combo
     */
	maxHeight : 200,
	typeAhead: true,
    //emptyText:'Seçiniz...',
	viewing	: false,
	sameValueDisplay : false,
	first : false,
	readOnly : false,
	sel : false,
	change : false,
	clearOnTriggerClick : false,
	/**
	 * Combo nesnesi init fonksiyonu.Store'u load eder.
	 * @name init2
	 * @function
	 * @type {Function}
	 */
	init : function(){
		mj.form.combo.superclass.init.call(this);
		this.sel=[];
		/*if(!this.multiRow)
			this.store.load();
		*/
		t=this;
		t.cmbTpl = '<div class="combo-list-item mj-unselectable">{'+this.displayField+'}</div>';
		var clx=this.multiRow?'':'mj-invisible';
		this.first=true;
		t.viewEl = $(mj.NE(mj.bd,{tag:'div',id:mj.genId('mj-combo-view-'),cls:'combo-list '+clx}));
		t.viewInner = $(mj.NE(t.viewEl,{tag:'div',cls:'combo-list-inner'}));
		t.view = new mj.view({
			renderTo : t.viewInner,
			store : this.store,
			tpl : new mj.template(t.cmbTpl),
			selector : 'div.combo-list-item',
			overClass : 'combo-over',
			selectedClass : 'combo-selected',
			multiSelect : this.multiSelect,
			loadMask : false,
			//pbar : new mj.pager({limit:15,pos:'bottom'}),
			filter : false,
			scope : t
		});
		t.addRelated(t.view);
		t.addRelated(t.viewEl);
		var _itemClick = function(){
			if(this.selected[0]){
				var val = this.selected[0].id;
				var s = this.scope;
				s.setValue(val);
				if(this.view)
					this.sel=[];
				else{
					s.sel=[];
					if(this.sel.length)
						s.sel=this.sel;
					else
						s.sel.push(this.sel);
				}
				if(!s.multiRow)
					s._hide();
				if(s._el.hasClass('grid-editor-item'))
					s.trigger('editcomplete',this);
			}
		};
		this.view.on('itemclick',_itemClick);
		if(this.multiRow){
			this.viewShow();
			this.view.store.on('load',function(){
				t._show();
				t.viewing=false;
			});
			this.view.load();
		}
		if(this.typeAhead){
			this.on('change',function(){
				this.change = true;
				if(this.mode=='local'){
					this.view.filter ={dI:this.displayField,v:this.getValue(true)};
					this.view.load();
					this._show();
				}else{
					this.store.params['dI']=this.displayField;
					this.store.params['v']=mj.escape(this.getValue(true));
					this.view.store.onOnce('load', this._show, this);
					this.view.store.load();
				}
			},this);
		}
		this.on('beforedestroy',function(){
			this.view.mon('itemclick',_itemClick);
			this.view.store.events['load'].listeners = [];
		});	
	},
	/**
	 * Combo nesnesi onTriggerClick fonksiyonu.Trigger butonuna basıldığında çalışır.
	 * @name onTriggerClick
	 * @function
	 * @type {Function}
	 */
	onTriggerClick : function(){
		this.hideAll();
		this.viewShow();
		if(this.clearOnTriggerClick)
			this.setValue(typeof this.emptyValue != 'undefined' ? this.emptyValue : '');
		if(!this.viewing){
			if(!this.first)
				this.view.store.load();
			if(this.mode=='remote')
				this.view.store.on('load',function(){
					this._show();
				},this);
			else
				this._show();
		}else
			this._hide();
	},
	/**
	 * Combo nesnesi viewShow fonksiyonu.
	 * @name viewShow
	 * @function
	 * @type {Function}
	 */
	viewShow : function(){
		t=this;
		t.cmbTpl = '<div class="combo-list-item mj-unselectable">{'+this.displayField+'}</div>';
		var clx=this.multiRow?'':'mj-invisible';
		if(!t.view){
			/*this.first=true;
			t.viewEl = $(mj.NE(mj.bd,{tag:'div',id:mj.genId('mj-combo-view-'),cls:'combo-list '+clx}));
			t.viewInner = $(mj.NE(t.viewEl,{tag:'div',cls:'combo-list-inner'}));
			t.view = new mj.view({
				renderTo : t.viewInner,
				store : this.store,
				tpl : new mj.template(t.cmbTpl),
				selector : 'div.combo-list-item',
				overClass : 'combo-over',
				selectedClass : 'combo-selected',
				multiSelect : this.multiSelect,
				scope : t
			});
			this.view.on('itemclick',function(){
				this.scope.setValue(this.selected[0].value);
				if(this.view)
					this.sel=[];
				else{
					this.scope.sel=[];
					if(this.sel.length)
						this.scope.sel=this.sel;
					else
						this.scope.sel.push(this.sel);
				}
				if(!this.scope.multiRow)
					this.scope._hide();
			});*/
		}else
			this.first=false;
		this.view.store.on('load',function(){
			if(!this.typeAhead)
				for(s in this.sel)
					if(typeof this.sel[s]!='function'){
						this.view._onSelect(this.view.items[this.sel[s].index]);
					}
		},this);
		if(this.mode=='local')
			if(this.view.items.length>0)
				for(s in this.sel)
					if(typeof this.sel[s]!='function')
						this.view._onSelect(this.view.items[this.sel[s].index]);
			else
				this.view.store.load();
	},
	/**
	 * Combo nesnesi findIndex fonksiyonu.Store'u load eder ve view'in load'unu çağırır.
	 * @name findIndex
	 * @function
	 * @type {Function}
	 * @param {String} val Combo store'u içinde aranacak elementin id değeri.
	 * @return {Number} Store içinde bulunan elementin index değeri,bulunamadığı durumda -1.
	 */
	findIndex : function(val){
		var ret = mj.getIndex(this.store.data,this.idField,val);
		if(ret==-1)
			ret = mj.getIndex(this.store.data,this.displayField,val);
		return ret;
	},
	/**
	 * Combo nesnesi getValue fonksiyonu.
	 * @name getValue
	 * @function
	 * @type {Function}
	 * @param {String} val Combo'dan get edilecek id değeri.
	 */
	getValue : function(raw){
		if(raw)
			return this.input[0].value;
		else
			return this.sameValueDisplay?this.displayValue:this.value!==''?this.value:null;
	},
	/**
	 * Combo nesnesi setValue fonksiyonu.
	 * @name setValue
	 * @function
	 * @type {Function}
	 * @param {String} val Combo'ya set edilecek id değeri.
	 */
	setValue : function(val){
		if(!this.multiSelect)
			this.sel=[];
		if(this.mode=='local'||(this.view.store.loaded && !this.store.params.v)){
			if(this.mode=='remote')
				this.store=this.view.store;
			if(val!=='' && val!=null){
				var fId=this.findIndex(val);
				if(fId!=-1){
					var data=this.store.data[fId];
					this.sel.push({index:fId,id:data.id,value:data[this.displayField]});
					this.value = data.id;
					this.displayValue = data[this.displayField];
					this.setElValue(this.formatValue(this.displayValue));
				}
			}else{
				if(this.store.params && this.store.params.v)
					delete this.store.params.v;
				this.value = ((this.clearOnTriggerClick && typeof this.emptyValue != 'undefined') ? this.emptyValue : val);
				//this.value = val;
				this.displayValue = val;
				this.setElValue(val);
			}
		}else{
			var t=this;
			this._oVal = val;
			this.view.store.onOnce('load', this._oLoad, this);
			if(!this.view.store.loaded)
				this.view.store.load();
			else if(this.mode=='remote'){
				var fId=t.findIndex(val);
				if(fId==-1){
					delete this.store.params.v;
					delete this.store.params.dI;
					this.view.clearSelections();
					this.view.store.load();
				}else{
					var data=t.store.data[fId];
					t.sel.push({index:fId,id:data.id,text:data[t.displayField]});
					t.view._onSelect(t.view.items[t.sel[t.sel.length-1].index]);
					t.value = data.id;
					t.lookupValue = data[t.displayField];
					t.setElValue(t.formatValue(t.lookupValue));
				}
			}
		}
		if(this.form && !this.form.loading)
			this.form.setModified(this);
	},
	_oLoad : function(){
		var t = this;
		if(!t.change){
			val = this._oVal;
			val = t.sel.length==1?t.sel[0].value:val;
			var fId=t.findIndex(val);
			if(fId>-1){
				var data=t.store.data[fId];
				t.sel.push({index:fId,id:data.id,text:data[t.displayField]});
				t.view._onSelect(t.view.items[t.sel[t.sel.length-1].index]);
				t.value = data.id;
				t.lookupValue = data[t.displayField];
				t.setElValue(t.formatValue(t.lookupValue));
			}
		}else
			t.change = false;
	},
	/**
	 * Combo nesnesi _show fonksiyonu.Combo'nun view'ını gösterir.
	 * @name _show
	 * @function
	 * @type {Function}
	 */
	_show : function(){
		this.view.store.mon('load', this._show);
		this.viewEl.removeClass('mj-invisible');
		//this.viewEl.parent().find('div').filter('div.combo-list').not(this.viewEl).not('.mj-invisible').css('z-index',1);
		//var ofs = $.browser.msie?this.input.prev().offset():this.input.offset();
		//if ($.browser.msie&&this.labelAlign=='left') ofs.left=ofs.left+parseInt(this.labelWidth);
		var ofs = this.getPosition();
		var elWidth = ($.browser.msie ? this.input.outerWidth() : this.input.outerWidth())+15;
		var elHeight=this.maxHeight>(this.view.store.recordCount*20)?this.view.store.recordCount*20:this.maxHeight;
		this.viewEl.css('top',ofs.top+(this.multiRow?0:21)).css('left',ofs.left).css('width',elWidth).css('height',elHeight).css('z-index',this.multiRow?550:552);
		if(this.multiRow)
			$(this.el).css('height',elHeight<this.maxHeight?elHeight:this.height);
		this.viewInner.css('width',elWidth).css('height',elHeight);
		this.viewing = true;
		mj.glb.views.push(this);
	},
	/**
	 * Combo nesnesi _hide fonksiyonu.Combo'nun view'ını gizler.
	 * @name _hide
	 * @function
	 * @type {Function}
	 */
	_hide : function(){
		//this.viewEl.parent().find('div').filter('div.combo-list').not(this.viewEl).not('.mj-invisible').css('z-index',2);
		this.viewEl.css('z-index',0).addClass('mj-invisible');
		this.viewing = false;
	},
	_onBlur : function(){
		return false;
	}
};
mj.extend(mj.form.combo, mj.form.triggerField);
mj.form.datePicker = function(config){
	mj.form.datePicker.superclass.constructor.call(this,config);
};
mj.form.datePicker.prototype = {
	componentClass : 'mj.form.datePicker',
	inputCls : 'mj-datepicker',
	weekend : [5,6],
	initValue : false,
	init : function(){
		this.render();
		if(this.initValue === false)
			this.initValue = new Date();
		this.fillMonth(this.initValue);
		mj.form.datePicker.superclass.init.call(this);
	},
	render : function(){
		var t = this, n = mj.NE, v='z-index:10000;';
		if(t.hidden)
			t.itemCls += ' mj-invisible mj-absolute';
		if(t.left||t.top){
			t.left = typeof t.left != 'undefined' ? (isNaN(t.left) ? t.left : (t.left+'px')) : '';
			t.top = typeof t.top != 'undefined' ? (isNaN(t.top) ? t.top : (t.top+'px')) : '';
			v += 'position:absolute;left:'+t.left+';top:'+t.top;
		}
		var el = t.destroyEl = t.el = n(t.renderTo, {cls:t.itemCls+' mj-unselectable',style:v}), _el = t._el = $(el);
		if(!t.inline)
		t.titleEl = n(el, {html:this.title, cls:t.titleCls, style:'width:'+t.labelWidth+';text-align:'+t.labelAlign});
		var c = t.input = $(n(el, {cls:t.inputCls,readOnly:t.readOnly}));
		t.cnts = {
			header : $(n(c,{cls:'mj-date-header'})),
			days : $(n(c,{cls:'mj-date-days'})),
			dates : $(n(c,{cls:'mj-date-dates'})),
			buttons : $(n(c,{cls:'mj-date-buttons'}))
		};
		var setHover = function(item){
			item.hover(function(){
				item.addClass('hover');
			},function(){
				item.removeClass('hover');
			});
			return item;
		};
		var h = t.cnts.header;
		t.headerEls = {
			prevYear : setHover($(n(h, {cls:'mj-date-prevyear', html:mj.insertSpacer(18,18)}))),
			prevMonth : setHover($(n(h, {cls:'mj-date-prevmonth', html:mj.insertSpacer(18,18)}))),
			current : setHover($(n(h, {cls:'mj-date-current'}))),
			nextMonth : setHover($(n(h, {cls:'mj-date-nextmonth', html:mj.insertSpacer(18,18)}))),
			nextYear : setHover($(n(h, {cls:'mj-date-nextyear', html:mj.insertSpacer(18,18)})))
		};
		var tmp = $(n(t.headerEls.current,{tag:'span',cls:'mj-date-currenttext'}));
		t.headerEls.dateSelect = setHover($(n(t.headerEls.current, {tag:'img',cls:'mj-date-select',src:mj.glb.blankImage})));
		var showMY = function(e){
			e.stopPropagation();
			t.showMonthYearSelect(t.current);
		};
		t.headerEls.dateSelect.click(showMY);
		tmp.click(showMY);
		t.headerEls.current=tmp;
		t.headerEls.prevYear.click(function(e){
			e.stopPropagation();
			t.fillMonth(t.getPrevYear(t.current));
		});
		t.headerEls.nextYear.click(function(e){
			e.stopPropagation();
			t.fillMonth(t.getNextYear(t.current));
		});
		t.headerEls.prevMonth.click(function(e){
			e.stopPropagation();
			t.fillMonth(t.getPrevMonth(t.current));
		});
		t.headerEls.nextMonth.click(function(e){
			e.stopPropagation();
			t.fillMonth(t.getNextMonth(t.current));
		});
		var d = t.cnts.days;
		t.dayTitles = [];
		for(var i=-1;i<7;i++){
			t.dayTitles.push($(n(d,{cls:'mj-date-daytitle', html:(i>-1?Date.strings.daysShort[(i + Date.firstDayOfWeek) % 7]:'')})));
		}
		var d = t.cnts.dates;
		t.dayButtons = [];
		var dayClick = function(item){
			item.click(function(){
				var datesplit = item[0].name.split('-');
				var selectedDate = new Date(), day = datesplit[5], month = datesplit[4], year = datesplit[3];
				selectedDate.setDate(1);
				selectedDate.setFullYear(year);
				selectedDate.setMonth(month-1);
				selectedDate.setDate(day);
				t.setValue(selectedDate);
				t.trigger('selectdate', t, selectedDate ,day, month, year);
			});
			return item;
		};
		for(i=0;i<6;i++){
			var a = [];
			for(var j=0;j<8;j++){
				var cell;
				if(j==0)	
					cell = $(n(d, {cls:'mj-date-week'}));
				else
					cell = dayClick(setHover($(n(d, {cls:'mj-date-day'}))));
				a.push(cell);
			}
			t.dayButtons.push(a);
		}
		var d = t.cnts.buttons;
		var todayClick = function(){
			var selectedDate = new Date();
			t.fillMonth(selectedDate);
			t.setValue(selectedDate);
			t.trigger('selectdate', t, selectedDate);
		};
		t.buttons = {
			today : new mj.button({renderTo : n(d,{cls:'mj-date-button-today'}),title : mj.lng.glb.today, handler:todayClick})
			//,reset : new mj.button({renderTo : n(d,{cls:'mj-date-button-reset'}),title : mj.lng.glb.reset})
		};
		var m = t.mySelect = $(n(c,{cls:'mj-date-myselect mj-invisible'}));
		var mc = n(m,{cls:'mj-date-monthcontainer'}), yc=n(m,{cls:'mj-date-yearcontainer'}), bc=n(m,{cls:'mj-date-buttoncontainer'});
		bc = n(bc,{cls:'mj-date-buttonalign'});
		var ms = t.monthSelectors = [];
		var assignMonthSelect = function(item, index){
			var select = function(e){
				e.stopPropagation();
				ms.selectedMonthCell.removeClass('mj-date-selected');
				ms.selectedMonth = index;
				ms.selectedMonthCell = item;
				item.addClass('mj-date-selected');
			};
			item.click(select);
			return item;
		};
		for(var i = 0;i<12;i++){
			var j = parseInt(i/2)+(i%2==1?6:0);
			ms.push(assignMonthSelect(setHover($(n(mc,{cls:'mj-date-monthselect',html:(Date.strings.monthsShort[j])}))),j));
		}
		var ys = t.yearSelectors = [];
		var assignYearSelect = function(item, index){
			var select = function(e){
				e.stopPropagation();
				ys.selectedYearCell.removeClass('mj-date-selected');
				ys.selectedYear = ys.firstYear + index;
				item.addClass('mj-date-selected');
				ys.selectedYearCell = item;
			};
			item.click(select);
			return item;
		};
		for(var i = 0;i<10;i++)
			t.yearSelectors.push(assignYearSelect(setHover($(n(yc,{cls:'mj-date-yearselect'}))),(i%2?parseInt(i/2)+5:parseInt(i/2))));
		t.buttons.prevYearGroup = new mj.button({renderTo : n(yc,{cls:'mj-date-button-prevyear'}),title : '<<'});
		t.buttons.prevYearGroup.on('click', function(btn,handlerId,e){
			e.stopPropagation();
			t.fillYears(t.curYear-10);
		});
		t.buttons.nextYearGroup = new mj.button({renderTo : n(yc,{cls:'mj-date-button-nextyear'}),title : '>>'});
		t.buttons.nextYearGroup.on('click', function(btn,handlerId,e){
			e.stopPropagation();
			t.fillYears(t.curYear+10);
		});
		t.buttons.ok = new mj.button({renderTo : n(bc,{cls:'mj-date-button-yearok'}),title : mj.lng.titles.buttons.ok});
		t.buttons.cancel = new mj.button({renderTo : n(bc,{cls:'mj-date-button-yearcancel'}),title : mj.lng.titles.buttons.cancel});
		t.buttons.ok.on('click', function(btn,handlerId,e){
			e.stopPropagation();
			var _tmp = new Date(t.current);
			_tmp.setMonth(ms.selectedMonth);
			_tmp.setFullYear(ys.selectedYear);
			t.fillMonth(_tmp);
			t.hideMonthYearSelect();
		});
		t.buttons.cancel.on('click', function(btn,handlerId,e){
			e.stopPropagation();
			t.hideMonthYearSelect();
		});
		t.trigger('render', t);
	},
	getPrevMonth : function(date){
		var _tmp = new Date(date);//, _d = _tmp.getDate(), _ld = _tmp.getLastDay();
		_tmp.setDate(1);
		_tmp.setMonth(_tmp.getMonth()-1);
		//_tmp.setDate(_d>_ld?_ld:_d);
		return _tmp;
	},
	getNextMonth : function(date){
		var _tmp = new Date(date);//, _d = _tmp.getDate(), _ld = _tmp.getLastDay();
		_tmp.setDate(1);
		_tmp.setMonth(_tmp.getMonth()+1);
		//_tmp.setDate(_d>_ld?_ld:_d);
		return _tmp;
	},
	getPrevYear : function(date){
		var _tmp = new Date(date);//, _d = _tmp.getDate(), _ld = _tmp.getLastDay();
		_tmp.setDate(1);
		_tmp.setYear(_tmp.getFullYear()-1);
		//_tmp.setDate(_d>_ld?_ld:_d);
		return _tmp;
	},
	getNextYear : function(date){
		var _tmp = new Date(date);//, _d = _tmp.getDate(), _ld = _tmp.getLastDay();
		_tmp.setDate(1);
		_tmp.setYear(_tmp.getFullYear()+1);
		//_tmp.setDate(_d>_ld?_ld:_d);
		return _tmp;
	},
	getFirstDayOfMonth : function(date){
		var _tmp = new Date(date);
		_tmp.setDate(1);
		return _tmp.getDay();
	},
	setCell : function(cell, type, value){
		cell[0].className='mj-date-day';
		if(this.value && this.value.getDate()==value.getDate()&&this.value.getMonth()==value.getMonth()&&this.value.getFullYear()==value.getFullYear()){
			if(this.selectedCell)
				this.selectedCell.removeClass('mj-date-selected');
			this.selectedCell = cell;
			cell[0].className+=' mj-date-selected';
		}else
			cell[0].className+=' mj-date-'+type;
		if(this.weekend.indexOf(value.getDay())>-1)
			cell[0].className+=' mj-date-weekend';
		var day = value.getDate();
		var month = value.getMonth() + 1;
		var year = value.getFullYear();
		cell[0].innerHTML = day;
		cell[0].name = 'mj-date-day-' + year + '-' + month + '-' + day;
	},
	fillYears : function(year){
		this.curYear = year;
		this.yearSelectors.firstYear = this.curYear - 4;
		for(var i = 0; i<10; i++){
			var t = this.curYear + i - 4, c = this.yearSelectors[i<5?(i*2):(i-5)*2+1];
			c.removeClass('mj-date-selected');
			c[0].innerHTML = t;
			if(this.current.getFullYear()==t){
				c.addClass('mj-date-selected');
				this.yearSelectors.selectedYear = t;
				this.yearSelectors.selectedYearCell = c;
			}
		}
		var ms = this.monthSelectors, m = this.current.getMonth();
		if(ms.selectedMonthCell)
			ms.selectedMonthCell.removeClass('mj-date-selected');
		ms.selectedMonth = m;
		var mi = m<6?(m*2):(m-6)*2+1;
		ms.selectedMonthCell = ms[mi];
		ms[mi].addClass('mj-date-selected');
	},
	showMonthYearSelect : function(date){
		this.mySelect.removeClass('mj-invisible');
		this.fillYears(date.getFullYear());
	},
	hideMonthYearSelect : function(){
		this.mySelect.addClass('mj-invisible');
	},
	fillMonth : function(date){
		var t = this, firstDay = t.getFirstDayOfMonth(date), b = t.dayButtons;
		var _tmp = new Date(date);
		_tmp.setDate(1);
		for(var i=firstDay+1;i>1;i--){
			_tmp.setDate(_tmp.getDate()-1);
			t.setCell(b[0][i-1], 'passive', _tmp);
		}
		var _tmp = new Date(date);
		_tmp.setDate(1);
		var cMonth = _tmp.getMonth(), cls = 'active';
		for(var i=0;i<6;i++){
			for(var j=1;j<8;j++){
				if(i>0||j>firstDay){
					t.setCell(b[i][j], cls, _tmp);
					_tmp.setDate(_tmp.getDate()+1);
					if(_tmp.getMonth()!=cMonth)
						cls = 'passive';
				}
			}
			b[i][0][0].innerHTML = _tmp.formatDate('W');
		}
		t.current = date;
		t.headerEls.current[0].innerHTML = date.formatDate('F Y');
	},
	setValue : function(value){
		var refresh = false;
		var val = this.value || this.initValue;
		if(value.getMonth()!=val.getMonth()||value.getFullYear()!=val.getFullYear())
			refresh = true;
		this.value = value;
		if(refresh)
			this.fillMonth(value);
		else{
			if(this.selectedCell)
				this.selectedCell.removeClass('mj-date-selected');
			var item = $('div[name*="mj-date-day-'+value.getFullYear()+'-'+(value.getMonth()+1)+'-'+value.getDate()+'"]',this.cnts.dates);
			this.selectedCell = item;
			item[0].className+=' mj-date-selected';
		}
	},
	_hide : function(){
		this._el.addClass('mj-invisible');
	},
	_show : function(){
		this._el.removeClass('mj-invisible');
	}
};
mj.extend(mj.form.datePicker, mj.form.field);
/** 
 * @fileoverview dateField nesnesi.
 * @hazırlayan kk yazılım info@mj.com
 * @sürüm 0.1 22.10.2007
 */
mj.form.dateField = function(config){
	//Kullanıldığı yerlerde her dateField için farklı metinler verilebilmesi için constructor içine yerleştirildi. Ör: minText : 'Sevk tarihi en fazla {0} olabilir' 
	mj.apply(this, {
		minText : mj.lng.objects.dateField.minText,
		maxText : mj.lng.objects.dateField.maxText,
		invalidText : mj.lng.objects.dateField.invalidText
	});
	mj.form.dateField.superclass.constructor.call(this,config);
};
mj.form.dateField.prototype = {
	componentClass : 'mj.form.dateField',
	inputCls : 'mj-date-field',
	width : '85px',
	format : "d/m/Y",
	altFormats : "d/m/Y|d-m-y|d-m-Y|d/m|d-m|dm|dmy|dmY|m",
	disabledDays : null,
	disabledDaysText : "",
	disabledDates : null,
	disabledDatesText : "",
	minValue : null,
	maxValue : null,
	clearOnTriggerClick : true,
	epoch : false,
	initValue : false,
	_onRender : function(){
		mj.form.dateField.superclass._onRender.call(this);
		var t = this;
		t.picker = new mj.form.datePicker({
			inline : true,
			hidden : true,
			renderTo : mj.bd
		});
		t.addRelated(t.picker);
		t.picker.on('selectdate', function(picker, date){
			t.setValue(t.formatValue(date));
			picker._hide();
			if(t._el.hasClass('grid-editor-item'))
				t.trigger('editcomplete',this);
		});
		if(this.initValue === false){
			var tmp = new Date();
			this.initValue = tmp.formatDate(this.format);
		}
		this.setValue(this.initValue);
		t._el.addClass('mj-date-field-cnt');
	},
	onTriggerClick : function(){
		if(this.disabled){
            return;
        }
		if(this.clearOnTriggerClick)
			this.clear();
		this.hideAll();
		ofs = this.getPosition();
		var _p = this.picker;
		_p._el.css('top',ofs.top+16).css('left',ofs.left+($.browser.msie?0:-1));
		if(window.windowManager)
			_p._el.css('z-index',window.windowManager.activeIndex+1);
		this.viewing = true;
		mj.glb.views.push(_p);		
		var time = this.value?mj.str2date(this.epoch?this.input[0].value:this.value):new Date();
		_p.fillMonth(time);
		_p.setValue(time);
		_p._show();
	},
	formatValue : function(value){
		return (new Date(Date.parse(value))).formatDate(this.format);
	},
	validate : function(value){
		return !isNaN(Date.parse(value));
	},
	setWidth : function(width){
		this._el.width(width);
		if(this.title)
			width-=this.labelWidth;
		this.input.width(width-($.browser.msie?23:22));	
	},
	setValue : function(val){
		if(this.validate(val)!==false||val==''||(this.epoch&&(typeof val == 'number'||new Date(parseInt(val)*1000) instanceof Date))){
			if(this.epoch){
				if(val!=''&&val!=null){
					if(typeof val == 'string' && val.indexOf('/')>-1){
						var valx=val.split('/');
						if(valx.length==3){
							var tmp = [];
							tmp.push(valx[1]);
							tmp.push(valx[0]);
							tmp.push(valx[2]);
							this.value = new Date(tmp.join('/')).getTime()/1000;
						}else
							this.value = '';
					}else if(typeof val == 'number'){
						var tmp = new Date(val*1000);
						var dx = this.validate(tmp);
						if(dx!==false){
							this.value = val;
							this.setElValue(tmp.formatDate(this.format));
							return;
						}else{
							
						}
					}else if(new Date(parseInt(val)*1000) instanceof Date){
						var tmp = new Date(parseInt(val)*1000);
						var dx = this.validate(tmp);
						if(dx!==false){
							this.value = val;
							this.setElValue(tmp.formatDate(this.format));
							return;
						}else{
							
						}
					}
				}else
					this.value = 0;
			}else
				this.value = val;
			this.setElValue(val);
		}
	},
	setElValue : function(val){
		if(this.epoch&&(val==''||val==0)){
			this.input[0].value='';
			return;
		}
		this.input[0].value = val;
	}
};
mj.extend(mj.form.dateField, mj.form.triggerField);
mj.form.fileInput = function(config){
	mj.form.fileInput.superclass.constructor.call(this,config);
	this.init();
};
mj.form.fileInput.prototype = {
	componentClass : 'mj.form.fileInput',
	itemCls : 'mj-form-item',
	titleCls : 'mj-form-caption',
	inputCls : 'mj-form-input',
	maxFile : 0,
	accept : false, //'jpg|gif|png'
	hidden : false,
	left : false,
	top : false,
	accept : '',
	render : function(){
		var t = this, n = mj.NE, v='';
		if(t.hidden)
			t.itemCls += ' mj-invisible';
		if(t.left||t.top){
			t.left = typeof t.left != 'undefined' ? (isNaN(t.left) ? t.left : (t.left+'px')) : '';
			t.top = typeof t.top != 'undefined' ? (isNaN(t.top) ? t.top : (t.top+'px')) : '';
			v = 'position:absolute;left:'+t.left+';top:'+t.top;
		}
		var el = t.el = n(t.renderTo, {cls:t.itemCls,style:v}), _el = t._el = $(el);
		t.titleEl = n(el, {html:this.title, cls:t.titleCls, style:'width:'+t.labelWidth+';text-align:'+t.labelAlign});
		t.input = $(n(el, {tag:'input',type:'file',cls:t.inputCls}));
		t.input.MultiFile({
			max: t.maxFile,
			accept: t.accept,
			afterFileSelect : function(element, value, master){
				
			},/*
onFileSelect:
onFileAppend: 
afterFileAppend: 
afterFileSelect: 
onFileRemove: 
afterFileRemove: 
*/

			STRING: {
				remove:'Kaldır',
				selected:'Seçilen: $file',
				denied:'Geçersiz dosya tipi: $ext!'
			}
		});

		t.trigger('render', t);
	},
	init : function(){
		var t = this;

		if(t.renderTo)
			t.render();
		mj.form.fileInput.superclass.init.call(t);
	},
	getValue : function(raw){
		return '_isFile';
	},
	setValue : function(val){
		return;
	},
	setElValue : function(val){
		return;
	},
	clear : function(){
		return;
	},
	validate : function(val){
	}
};
mj.extend(mj.form.fileInput, mj.form.field);
mj.form.imageField = function(config){
	mj.form.imageField.superclass.constructor.call(this,config);
};
mj.form.imageField.prototype = {
	componentClass : 'mj.form.imageField',
	inputCls : 'mj-image-field',
	triggerCls : 'mj-image-upload',
	width : 100,
	height : 100,
	init : function(){
		var t = this;
		if(t.renderTo)
			t.render();
		mj.form.imageField.superclass.init.call(t);
	},
	render : function(){
		var t = this, n = mj.NE, v = '';
		if(t.left||t.top){
			t.left = typeof t.left != 'undefined' ? (isNaN(t.left) ? t.left : (t.left+'px')) : '';
			t.top = typeof t.top != 'undefined' ? (isNaN(t.top) ? t.top : (t.top+'px')) : '';
			v = 'position:absolute;left:'+t.left+';top:'+t.top;
		}
		var el = t.el = n(t.renderTo, {cls:t.itemCls,style:v+';'+t.itemStyle}), _el = t._el = $(el);
		if(t.title)
			if(t.labelPos == 'left')
				t.titleEl = n(el, {html:this.title, cls:t.titleCls, style:'width:'+t.labelWidth+';text-align:'+t.labelAlign});
		t.input = $(n(el, {tag:'img',id:(t.id||mj.genId('mj-form-item-')),style:''+(t.height?'height:'+t.height+'px;':'')+(t.width?'width:'+t.width+'px;':''),type:t.type,cls:t.inputCls, src:mj.glb.blankImage}));
		t.triggerEl = $(n(el, {cls:t.triggerCls, html:mj.insertSpacer(16,16)}));
		t.triggerEl.hover(function(){
			t.triggerEl.addClass('mj-image-upload-hover');
		},function(){
			t.triggerEl.removeClass('mj-image-upload-hover');
		});
		t.triggerEl.click(function(){
			if(t.trigger('triggerclick', t, t)!==false)
				t._triggerClick.call(t, t);
		});
	},
	getElValue : function(){
		return this.input.attr('src');
	},
	setElValue : function(val){
		//this.input.attr('src', val);
		mj.get(this.id).src=val;
	},
	setValue : function(val){
		this.value = val;
		this.setElValue(val?val:mj.glb.blankImage);
	},
	_triggerClick : function(imageField){
		return true;
	}
};
mj.extend(mj.form.imageField, mj.form.field);
mj.form.fieldSet = function(config){
	mj.form.superclass.constructor.call(this, config);
};
mj.form.fieldSet.prototype = {
	componentClass : 'mj.form.fieldSet',
	fieldsetCls : 'mj-fieldset',
	legendCls : 'mj-legend',
	style : '',
	itemStyle : '',
	_onRender : function(){
		var f=this;
		f.fieldSetEl = f.destroyEl = $(mj.NE(f.renderTo, {tag : 'fieldset', cls : f.fieldsetCls, style : f.style+f.itemStyle+''+(f.height?'height:'+f.height+'px;':'')+(f.width?'width:'+f.width+'px;':'')}));
		var x = f.scope.form;
		if(f.title){
			f.legendEl = $(mj.NE(f.fieldSetEl,{tag:'legend', cls : f.legendCls}));
			f.titleEl = $(mj.NE(f.legendEl,{tag:'span', html:f.title}));
		}
		f.scope.form = f.fieldSetEl;
		if(!f.items)
			f.items = [];
		else
			for(var i=0,l=f.items.length;i<l;i++){
				var item = f.items[i];
				f.scope.add(item);
			}
		f.scope.form = x;
		f.scope.fieldSets.push(f);
		mj.form.fieldSet.superclass.init.call(this);
	},
	render : function(scope){
		this.scope = scope;
		this._onRender();
	},
	clear : function(){
		$(this.items).each(function(){
			this.clear();
		});
	}
};

mj.extend(mj.form.fieldSet, mj.component);
mj.form.mapField = function(config){
	mj.form.mapField.superclass.constructor.call(this,config);
};
mj.form.mapField.prototype = {
	componentClass : 'mj.form.mapField',
	inputCls : 'mj-map-point-editor',
	itemCls : 'mj-map-field',
	itemStyle : '',
	width : 250,
	height : 150,
	maxMapScale : 16,
	minMapScale : 9,
	init : function(){
		this.render();
		mj.form.mapField.superclass.init.call(this);
	},
	render : function(){
		var t = this, n = mj.NE, v='';
		if(t.hidden)
			t.itemCls += ' mj-invisible mj-absolute';
		if(t.left||t.top){
			t.left = typeof t.left != 'undefined' ? (isNaN(t.left) ? t.left : (t.left+'px')) : '';
			t.top = typeof t.top != 'undefined' ? (isNaN(t.top) ? t.top : (t.top+'px')) : '';
			v += ';position:absolute;left:'+t.left+';top:'+t.top;
		}
		if(t.width){
			var w = t.width == parseInt(t.width) ? t.width+'px' : t.width;
			v += 'width:'+w+';';
		}
		if(t.width){
			var h = t.height == parseInt(t.height) ? t.height+'px' : t.height;
			v += 'height:'+h+';';
		}
		v += t.itemStyle;
		var el = t.el = n(t.renderTo, {cls:t.itemCls+' mj-unselectable',style:v+';'+t.itemStyle});
		var _el = t._el = $(el);
		if(!t.inline && t.title)
			t.titleEl = n(el, {html:this.title, cls:t.titleCls, style:'width:'+t.labelWidth+';text-align:'+t.labelAlign});
		var c = t.input = $(n(el, {cls:t.inputCls,readOnly:t.readOnly}));
		t.mapCnt = n(el, {style:'width:100%;height:100%;'});
		
		t.map = new mj.map({
			renderTo : t.mapCnt,
			_canModify : true,
			customIcons : t.customIcons,
			allowedBoundsSWLat : t.allowedBoundsSWLat,
			allowedBoundsSWLong : t.allowedBoundsSWLong,
			allowedBoundsNELat : t.allowedBoundsNELat,
			allowedBoundsNELong : t.allowedBoundsNELong,
			height : t.height,
			maxMapScale : t.maxMapScale,
			minMapScale : t.minMapScale,
			showOverview : t.showOverview,
			startPointLat : t.startPointLat,
			startPointLong : t.startPointLong,
			startZoomLevel : t.startZoomLevel,
			width : t.width
		});

		t.trigger('render', t);
	}
};
mj.extend(mj.form.mapField, mj.form.field);
mj.grid = function(config){
	mj.grid.superclass.constructor.call(this, config);
};
mj.grid.prototype={
	componentClass : 'mj.grid',
	width:50,
	height:40,
	contextMenuWidth : 130,
	selectMode : 'row',
	fitToParent : false,
	selectedRow : {},
	loadMask : true,
	noWrap : true,
	scroll : 'auto',
	sortable : true,
	getSize : function(){
		if(this.fitToParent){
			this.height = this.initialRenderTo.height()||parseInt(this.initialRenderTo[0].style.height);
			this.width = this.initialRenderTo.width()||parseInt(this.initialRenderTo[0].style.width);
		}
	},
	doGrid : function(){
		if(this.initialRenderTo[0].offsetHeight>0){
			this.getSize();
			if(this.height!=this.lastHeight||this.width!=this.lastWidth){
				this.cnt1.width(this.width);
				this.cnt1.height(this.height);
				$(this.cnt).width(this.width);
				$(this.headerWrap).width(this.width);
				var newHeight = this.height-(this.pageBar?$(this.pageBar).height():0);
				$(this.cnt).height(newHeight);
				$(this.drag.el).height(newHeight-16);
				newHeight -= $(this.header).height();
				$(this.gridScroll).width(this.width);
				$(this.gridScroll).height(newHeight);
				//$(this.dataContainer).height(newHeight-16);
				$(this.drag.el).css('left','0px');
				$(this.drag.el).css('top','0px');
				this.lastWidth = this.width;
				this.lastHeight = this.height;
			}
		}
	},
	init : function(){
		var t = this;
		this.initialRenderTo = this.renderTo;
		this.getSize();
		this.cnt = this.cnt1 = $(mj.NE(this.renderTo, {style:'width:'+this.width+'px;height:'+this.height+'px;overflow:hidden', cls:'mj-grid mj-unselectable'}));
		if(this.pbar&&typeof this.pbar.render=='function'){
			this.pbar.render({scope:this});
			this.cnt=$(this.renderTo);
			this.pbar.on('sourceload',function(){
				t.selectedRow = {};
			});
		}
		this.cnt.css('width',this.width+'px');
		this.cnt.css('overflow','hidden');
		//this.width = parseInt(this.cnt.width());
		var _h = parseInt(this.cnt.css('height'));
		this.height = _h>0 ? _h : this.height;
		var gridStyle ='', gi = this.gridId = mj.genId(), ce = $.cssEngine, w = this.width, h = this.height;
		var cw = 0;
		this.clientHeight = 0;
		var _ci=0, _l=0, _cc=this.cm.length, _sw = this.width, t = this,_cw = this.width ;
		$(this.cm).each(function(){
			this.colIndex=_ci++;
			this.isLast = _ci==_cc;
			this.width = (this.isLast && (this.width+cw<_cw || !this.width)) ? _cw-cw-16 : (this.width ? this.width : 100);
			if(!this.hide){
				_l += this.width;
				cw += this.width;
			}
		});
		this._cw = cw;
		this.noWrapStyle = this.noWrap ? 'white-space : nowrap;':'';  		
		var pos = $.browser.msie?'':'position:relative';
		this.headerWrap =  mj.NE(this.cnt, {tag:'div', cls:'mj-grid-header-row',style:'width:'+this.width+'px;'});  
		this.header = mj.NE(mj.NE(this.headerWrap, {tag:'table', align:'left', cellpadding:'0', cellspacing:'0', width:cw, style:pos}), {tag:'tr', cls:'mj-grid-header-row'}).parentNode;
		this.dragEl = $(mj.NE(this.cnt, {tag:'div', cls:'',style : 'position:absolute;width:2px;background:transparent;height:'+this.height+'px;'})); 
		this.drag = new mj.drag({
			el : this.dragEl[0],
			parent : this.cnt[0],
			dragType : 'h',
			cls : 'mj-drag-col'
		});
		this.drag.on('dragstop',function(e){
			var proxy=$(e.proxy), t = this;
			proxy=e.proxy[0].style;	
			tOfP=t.drag.el.offsetParent==mj.bd[0]?{left:0,top:0}:$(t.drag.el.offsetParent).offset();
			var el = $('td[name="column-'+t.curColumn+'"]',t.cnt);
			var eldiv = $('td[name="column-'+t.curColumn+'"] div.mj-cell-inner',t.cnt);
			var initWidth=t.cm[t.curColumn].width||60;
			var elOf=el.offset();
			var oldWidth = parseInt(el[0].style.width);
			var width = (parseInt(proxy.left)+tOfP.left) - (el.offset().left);
			var widthDiff = (width-oldWidth);
			$(t.header).width($(t.header).width() + widthDiff);
			$(t.dataContainer).width($(t.dataContainer).width() + widthDiff);
			el.css('width',width + 'px');
			eldiv.css('width',(width-10) + 'px');
			t.cm[t.curColumn].curWidth = width ;
		},this);
		var hd = t.header.rows[0];
		var _gs = this.gridScroll = mj.NE(this.cnt, {style:'position:relative;overflow:'+ this.scroll +';width:'+this.width+'px;height:'+(this.height-parseInt($(this.headerWrap).css('height')))+'px;'});
		var items = this._renderColumns();
		var tb = new mj.contextmenu({
			renderTo : mj.NE(mj.bd,{cls:'mj-grid-columns-menu'}),
			parent : hd,
			menuScope : this,
			width : this.contextMenuWidth,
			items : [
				{id:'_1', title:mj.lng.objects.grid.columns,subMenuWidth : this.contextMenuWidth, items : items},
				'|',
				{id:'_2', title:mj.lng.objects.grid.sortAZ,iconCls:'mj-menu-sort-asc',handler:function(){
					t.sort(t._contextCol,'ASC');
				}},
				{id:'_3', title:mj.lng.objects.grid.sortZA,iconCls:'mj-menu-sort-desc',handler:function(){
					t.sort(t._contextCol,'DESC');
				}}
			]
		});
		t.addRelated(tb);
		tb.on('itemtoggle',function(a,b,c,d){
			if(t.cm[b.index].hide)
				t.showColumn(b.index);
			else{
				t.hideColumn(b.index);
			}	
		},this);	
		this.clientWidth = cw;
		var _gd = this.dataContainer = mj.NE(_gs, {tag:'table', align:'left', cellpadding:'0', cellspacing:'0', width:(cw)+'px'});
		var _gh = this.header;
		$(_gs).scroll(function(e){
			$(_gd).css("top", -e.target.scrollTop);
			if(!$.browser.msie)
				$(_gh).css("left", -e.target.scrollLeft);
			else
				$(_gh).css("margin-left", -e.target.scrollLeft);
			$(_gd).css("left", -e.target.scrollLeft);
		});
		if(this.loadMask)
			this.mask = new mj.mask({el:this.cnt1[0]});
		this.store.on('beforeload', function(){
			if(this.loadMask)
				this.mask.show(50);
		}, this);
		this.store.on('load', this._onLoad, this);
		this.on('rowclick', this.selectRow, this);
		this.on('cellclick', this.selectCell, this);
		mj.grid.superclass.init.call(this);
		mj.bindResize(this.cnt1, this.doGrid, this);
	},
	clearSortImages : function(){
		$('img',this.cnt)
			.not($('div img.mj-invisible'))
			.addClass('mj-invisible')
			.removeClass('mj-sorter-asc')
			.removeClass('mj-sorter-desc');
	},
	setFieldSort : function(c,d){
		$('img',this.cm[c].el).removeClass('mj-invisible').addClass('mj-sorter-'+(String(d).toLowerCase()));
		this.cm[c].sortDir = d;
	},
	clientSort : function(c,d){
		this.clearSortImages();
		this.setFieldSort(c,d);
		this.store.sort(this.cm[c].dataIndex,d);
		this._onLoad();
	},
	remoteSort : function(c,d){
		var t = this;
		t.clearSortImages();
		var col = this.cm[c];
		t._sortParams = {
			sort : (col.table?col.table+'.':'')+(col.sortField||col.dataIndex),
			dir : d,
			colIndex : c
		};
		mj.apply(t.store.params,t._sortParams);
		t.store.on('load',function(){
			if(typeof this.params.colIndex != 'undefined'&&this.params.dir)
				t.setFieldSort(this.params.colIndex,this.params.dir);
		});
		t.load();
	},
	sort : function(c,d){
		if(this.sortable){
			if(this.store.localSort||(this.pbar&&this.pbar.getPageCount()==1))
				this.clientSort(c,d);
			else
				this.remoteSort(c,d);
		}else
			return false;
	},
	_renderColumn : function(colConfig, colIndex){
		var t = this, hd = t.header.rows[0];
		if(colConfig.hide)
			var hideCls = ' mj-invisible';
		else
			var hideCls = '';
		var x = colConfig.el = $(mj.NE(hd, {tag:'td',unselectable :'on',name : 'column-'+ (colIndex),cls : 'mj-unselectable mj-column-'+ (colIndex) + hideCls , html:'<div unselectable="on" class="mj-cell-inner mj-unselectable"><span class="mj-cell-inner-header-text">'+colConfig.header+'</span>'+mj.insertSpacer(13,10)+'</div>', style:'width:'+(colConfig.width-1)+'px'}));
		var sImg = $('img',x);
		sImg.attr('name','sorter-'+(colIndex));
		sImg.addClass('mj-unselectable mj-invisible mj-sorter');
		x.mouseover(function(e){
			var xOf=x.offset();
			if(e.clientX-xOf.left<6){
				t.curColumn = parseInt(colIndex);
				t.curColumn--;
				tOfP=t.drag.el.offsetParent==mj.bd[0]?{left:0,top:0}:$(t.drag.el.offsetParent).offset();
				t.drag.el.style.left = (xOf.left - tOfP.left) + 'px';
				t.drag.el.style.top = (xOf.top - tOfP.top) + 'px';
			}
		});
		x.click(function(e){
			var firstSort = typeof t.cm[colIndex].sortDir=='undefined';
			var dir = (firstSort||(!firstSort&&t.cm[colIndex].sortDir=='DESC'))?'ASC':'DESC';
			t.sort(colIndex,dir);
		});
		x.bind('contextmenu',function(){
			t._contextCol = colIndex;
		});
		return {index:colIndex ,title : colConfig.header,type : 'toggle',state : !colConfig.hide};
	},
	_renderColumns : function(){
		var t = this;
		var items = [], colIndex = 0;
		$(t.cm).each(function(){
			items.push(t._renderColumn(this, colIndex++));
		});
		return items;
	},
	selectRow : function(g, rowIndex, row){
		if(this.selectMode=='row'){
			if(this.selectedRow && this.selectedRow.el)
				this.selectedRow.el.removeClass('mj-grid-selected');
			//this.selectedRow.el = $(this.rows[rowIndex].el)
			this.selectedRow = this.rows[rowIndex];
			//this.selectedRow.data = this.store.data[rowIndex];
			this.selectedRow.index = rowIndex;
			this.selectedRow.el.addClass('mj-grid-selected');
		}
	},
	getSelected : function(){
		if(this.selectedRow)
			return this.selectedRow;
		else
			return false;
	},
	clearSelectedRow : function(){
		if(this.selectMode=='row'){
			if(this.selectedRow && this.selectedRow.el){
				this.selectedRow.el.removeClass('mj-grid-selected');
				this.selectedRow = {};
			}
		}
	},
	selectCell : function(g, rowIndex, colIndex, cell){
		if(this.selectMode=='cell'){
			if(this.selectedCell)
				this.selectedCell.removeClass('mj-grid-selected');
			this.selectedCell = cell;
			this.selectedCell.addClass('mj-grid-selected');
		}
	},
	getCellValue : function(rowIndex,colIndex){
		return this.rows[rowIndex].cols[colIndex].data;
	},
	setCellValue : function(rowIndex,colIndex,value,renderer,isHtml){
		var row = this.rows[rowIndex];
		var cell = row.cols[colIndex];
		var align = this.cm[colIndex].align || false;
		cell.data = value;
		row.data[cell.dataIndex] = value;
		if(renderer){
			value = renderer(value);
			if(align)
				value = '<div style="text-align:'+align+';">'+value+'</div>';
			if(isHtml)
				cell.el.find('div:first').html(value);
			else
				cell.el.find('div:first').text(value);
		}else if(typeof value == 'number' && !align){
			value = '<div style="text-align:right;">'+value+'</div>';
			cell.el.find('div:first').empty().append(value.toString());
		}else{
			if(align)
				value = '<div style="text-align:'+align+';">'+value+'</div>';
			cell.el.find('div:first').html(value);
		}
	},
	load : function(){
		this.store.load();
	},
	showColumn : function(index){
		var el = $('td[name="column-'+index+'"]',this.cnt);
		if (el.hasClass('mj-invisible')){
			var oldWidth = parseInt(el[0].style.width);
			var hw = $(this.header).width();
			var dw = $(this.dataContainer).width();
			el.removeClass('mj-invisible');
			$(this.header).width( hw+ oldWidth);
			$(this.dataContainer).width(dw+ oldWidth);				
		}
		this.cm[index].hide=false;

	},
	hideColumn : function(index){
		var el = $('td[name="column-'+index+'"]',this.cnt);
		if (!el.hasClass('mj-invisible')){
			var oldWidth = parseInt(el[0].style.width);
			var hw = $(this.header).width();
			var dw = $(this.dataContainer).width();
			el.addClass('mj-invisible');
			$(this.header).width( hw- oldWidth);
			$(this.dataContainer).width(dw- oldWidth);		
		}
		this.cm[index].hide=true;
	},
	_onLoad : function(){
		var g = this, cnt = this.dataContainer, cm = this.cm, gi = this.gridId;
		$(cnt).empty();
		var _r = this.rows = [], oeCls = 'odd';
		$(this.store.data).each(function(){
			oeCls = oeCls=='even' ? 'odd' : 'even';
			var r = mj.NE(cnt, {tag:'tr', cls:'mj-grid-data-row mj-'+oeCls}).rows, d = this, _ri=r.length-1;
			var r = r[_ri], _jqr=$(r);
			_jqr.click(function(){
				g.trigger('rowclick', g, _ri);
			});
			_jqr.dblclick(function(){
				g.trigger('rowdblclick', g, _ri);
			});
			var colCount = 0;
			var robj = {};
			robj.cols = [];
			r.cols = [];
			$(cm).each(function(){
				if(g.cm[colCount].hide)
					var hideCls = ' mj-invisible';
				else
					var hideCls = '';
				//var tdwidth = (g.cm[colCount].curWidth||(this.isLast?this.width-(g.width<g._cw?0:1):this.width))-1;
				var tdwidth = (g.cm[colCount].curWidth||this.width)-1;
				var data = (!(d[this.dataIndex]==null || d[this.dataIndex]==undefined)?d[this.dataIndex]:'&nbsp;');
				if (typeof data=='string'&&(!g.store.renderer||!g.store.renderer[this.dataIndex]))
					data = data.replace(/\</g,'&lt;').replace(/\>/g,'&gt;');
					
				var cell = $(mj.NE(r, {tag:'td',name : 'column-'+ (colCount),cls : 'mj-column-'+ (colCount), style:($.browser.mozilla?'height:23px;':'')+'width:'+tdwidth+'px', cls:'mj-cell mj-grid'+gi+'-col-'+this.colIndex + hideCls, html:'<div class="mj-cell-inner" unselectable="on" style="'+g.noWrapStyle+'width:'+(tdwidth-10)+'px;"></div>'}));
				var cellInner = $('.mj-cell-inner',cell);
				var align = g.cm[colCount].align || false;
				if (this.renderer)
					data = this.renderer(data,d,cellInner);
				else if(typeof data == 'number' && !align)
					data = '<div style="text-align:right;">'+data+'</div>';
				if(align)
					data = '<div style="text-align:'+align+';">'+data+'</div>';
				cellInner.append(data.toString());
				robj.cols.push({el:cell,data:d[this.dataIndex],dataIndex:this.dataIndex});
				var _ci = r.cols.push(cell);
				if(g.selectMode=='cell'){
					cell.click(function(e){
						e.stopPropagation();
						g.trigger('cellclick', g, _ri, _ci, cell);
					});
					cell.dblclick(function(e){
						e.stopPropagation();
						g.trigger('celldblclick', g, _ri, _ci, cell);
					});
				}
				colCount++;
			});
			_jqr.mouseover(function(){
				$(this).addClass("mj-grid-hover");
			});
			_jqr.mouseout(function(){
				$(this).removeClass("mj-grid-hover");
			});
			robj.el = $(r);
			robj.data = d;
			_r.push(robj);
		});
		if(this.loadMask)
			this.mask.hide();
		this.trigger('afterload', this);
	},
	getValue : function(rowIndex){
		var r = [], t = this;
		if(rowIndex)
			r.push(t.store.data[rowIndex]);
		else
			r=t.store.data;
		return r;
	},
	_saveLoadTrigger : function(store){
		store.params.limit = store._limitBackup;
		store.params.current = store._currentBackup;
		store.mon('load', this._saveLoadTrigger);
		this._saveAsXLS(this._filename);
	},
	saveAsXLS : function(filename){
		var t = this;
		if(parseInt(t.store.recordCount)!=t.store.data.length){
			t.store._limitBackup = t.store.params.limit;
			t.store._currentBackup = t.store.params.current;
			t.store.params.limit = parseInt(t.store.recordCount);
			t.store.params.current = 1;
			t._filename = filename;
			t.store.on('load', t._saveLoadTrigger, this);
			t.store.load();
		}else
			this._saveAsXLS(filename);
	},
	_saveAsXLS : function(filename){
		var t = this, n=mj.NE;
		var copyTo = $(n(mj.bd, {style:'display:none'}));
		copyTo.append(this.cnt[0].innerHTML);
		$('td',copyTo).attr('height', '22px');
		var tbl = $('table',copyTo);
		filename = filename || mj.genId('rapor')+'xls';
		tbl.attr('border', '0');
		tbl.css('border-left', '1px solid #000');
		tbl.css('border-top', '1px solid #000');
		$('td', tbl).css('border', '1px solid #000');
		$(tbl[1]).prepend($('tr',tbl[0]));
		$(tbl[0]).remove();
		var content = (t.fileTitle ? t.fileTitle : '')+copyTo[0].innerHTML;
		content = mj.escape(content);
		var frmCnt = $(n(mj.bd, {style:'display:none'}));
		var frm = n(frmCnt, {tag:'form',action:mj.glb.exportPath,method:'POST',html:'<input type="hidden" name="format" value="xls"/><input type="hidden" name="content" value="'+content+'"/><input type="hidden" name="filename" value="'+filename+'"/>'});
		frm.submit();
		frmCnt.remove();
		copyTo.remove();
	},
	copyContent : function(copyTo){
		copyTo.append(this.cnt[0].innerHTML);
		copyTo[0].lastChild.style.height=copyTo[0].lastChild.scrollHeight+50;
		copyTo[0].lastChild.style.overflowX="";
		copyTo[0].lastChild.style.overflowY="";
		copyTo[0].lastChild.style.height=copyTo[0].lastChild.scrollHeight+50;
		$('td',copyTo).attr('height', '0');
		var tbl = $('table',copyTo);
		tbl.attr('border', '0');
		tbl.css('border-left', '1px solid #000');
		tbl.css('border-top', '1px solid #000');
		$('td', tbl).css('border-right', '1px solid #000');
		$('td', tbl).css('border-bottom', '1px solid #000');
		$(tbl[1]).prepend($('tr',tbl[0]));
		$(tbl[0]).remove();
	},
	setTitle : function(colIndex, title){
		var cmItem = this.cm[colIndex];
		$('.mj-cell-inner-header-text', cmItem.el).html(title);
		cmItem.header = title;
	}
};
mj.extend(mj.grid, mj.component);
mj.editableGrid = function(config){
	mj.editableGrid.superclass.constructor.call(this, config);
};
mj.editableGrid.prototype={
	componentClass : 'mj.editableGrid',
	selectMode : 'cell',
	activeEditor : null,
	init : function(){
		mj.editableGrid.superclass.init.call(this);
		this.cnt1.addClass('mj-editable-grid');
		this.on('cellclick', this.startEdit);
		$(document).bind('click', {scope:this},function(e){
			var scope=e.data.scope, activeEd = scope.activeEditor;
			if(activeEd)
				scope.endEdit(activeEd);
		});
		this.drag.on('dragstart',function(e){
			var activeEd = this.activeEditor;
			if(activeEd){
				this.endEdit(activeEd);
			}
		},this);
	},
	_renderColumn : function(colConfig, colIndex){
		var ti = this;
		var cnf=colConfig.editor;
		if(cnf){
			cnf.config.itemCls = (cnf.config.itemCls ? cnf.config.itemCls : cnf.cls.prototype.itemCls) + ' mj-invisible grid-editor-item';
			cnf.config.renderTo=this.gridScroll;
			colConfig.editor=new cnf.cls(cnf.config);
			colConfig.editor.on('editcomplete',function(){
				var ci = this.cellInfo;
				var r = ci.row, c = ci.col,val;
				var store = ti.store, cn = store.dm[c];
				/*switch (ti.cm[c].editor.componentClass){
					case 'mj.form.combo':
						val = this.value;
						break;
					case 'mj.form.dateField':
						val = this.value;
						break;
				}*/
				val = this.getElValue();
				ti.rows[r].cols[c].el.find('div')[0].innerHTML = val;
				store.data[r][cn] = val;
				ti.endEdit();
			});
		}
		return mj.editableGrid.superclass._renderColumn.call(this, colConfig, colIndex);
	},
	endEdit : function(ed){
		if(ed)
			switch(ed.componentClass){
				case 'mj.form.combo':
					ed._hide();
					break;
				case 'mj.form.dateField':
					ed.picker._el.addClass('mj-invisible');
					break;
			}
		this.activeEditor._el.addClass('mj-invisible');
		this.activeEditor = null;
	},
	startEdit : function(g, rowIndex, colIndex, cell){
		$(this.rows[rowIndex].el).removeClass('mj-grid-hover');
		var cm = this.cm;
		var cI = colIndex-1;
		var gHCell = cm[cI];
		var ed = gHCell.editor;
		var store = this.store, rowName = cm[cI].dataIndex, rowValue = store.data[rowIndex][rowName];
		if(this.activeEditor){
			this.endEdit(this.activeEditor);
		}
		if(ed){
			ed.cellInfo = {col:cI,row:rowIndex};
			ed.setValue(rowValue);
			this.activeEditor = ed;
			var l=0,t=0;
			for(var i=0;i<cI;i++){
				if(!cm[i].hide&&l==0)
					l += this.cm[i].el.offset().left;
			}
			t += cell[0].offsetTop;
			l = l!=0?this.cm[cI].el.offset().left - l:0;
			ed.setPos(l,t);
			var elW = this.rows[rowIndex].cols[cI].el.width();
			ed.setWidth(elW);
			ed._el.removeClass('mj-invisible');
		}
	}
};
mj.extend(mj.editableGrid, mj.grid);
/** 
 * @fileoverview Layout nesnesi oluşturan sınıf.
 * @hazırlayan kk yazılım info@mj.com
 * @sürüm 0.0.1 Beta 18.10.2007
 */
 /**
 * Yeni bir Layout nesenesi oluşturur.<br>
 * @example

 * @class
 * @name mj.Layout
 * @extends mj.component
 * @param {Object} config Tab objesini oluşturabilmek için gerekli olan parametreleri içerir.
 * @config {HTMLElement} renderTo Tab nesnesinin render edileceği container nesnesi.
 */
mj.layout = function(config){
	mj.layout.superclass.constructor.call(this, config);
};
mj.layout.prototype={
	componentClass : 'mj.layout',
	initialNorth : 50,
	initialWest : 100,
	initialEast : 100,
	initialSouth : 100,
	centerBorder : 'ltrb',
	createRegion : function(elem){
		var split=false,collapser=false,size=0;
		var style1='height',style2='width',style3='top',style4='left',initSize,elStyle;
		var collapseCls = elem.collapsed?'collapsed':'expanded',mxh=0,mnh=0,mxw=0,mnw=0;
		var cnt=mj.NE(this.renderTo,{tag:'div',id:(this.masterId+'-region-'+elem.region),cls:'border-panel '+elem.region+' '+(elem.collapsed?'mj-invisible':'')});
		elem.dType = 'v';
		switch (elem.region){
			case 'north':
				initSize=elem.collapsed?0:(elem.initial||initialNorth);
				size=elem.collapsed?(elem.initial||initialNorth):0;
				mxh=(elem.max||elem.initial)+this.borderSize,mnh=(elem.min||elem.initial)+this.borderSize;
				break;
			case 'south':
				initSize=elem.collapsed?0:(elem.initial||initialSouth);
				size=elem.collapsed?(elem.initial||initialSouth):0;
				//mxh=($(this.renderTo).height()-((elem.min||elem.initial)+(elem.split?this.splitSize:0))),mnh=($(this.renderTo).height()-((elem.max||elem.initial)+(elem.split?this.splitSize:0)));
				break;
			case 'west':
				style1='width',style2='height',style3='left',style4='top',elem.dType='h';
				initSize=elem.collapsed?0:(elem.initial||initialWest);
				size=elem.collapsed?(elem.initial||initialWest):0;
				mxw=(elem.max||elem.initial)+this.borderSize,mnw=(elem.min||elem.initial)+this.borderSize;
				break;
			case 'east':
				style1='width',style2='height',style3='left',style4='top',elem.dType='h';
				initSize=elem.collapsed?0:(elem.initial||initialEast);
				size=elem.collapsed?(elem.initial||initialEast):0;
				//mxw=($(this.renderTo).width()-((elem.min||elem.initial)-this.borderSize+(elem.split?this.splitSize:0))),mnw=($(this.renderTo).width()-((elem.max||elem.initial)-this.borderSize+(elem.split?this.splitSize:0)));
		}
		//collapseCls+='-'+elem.dType;
		elStyle = style4+':50%;'+style1+':5px;'+style2+':40px;';
		cnt.style[style1]=initSize+'px';
		cnt.style[style2]='100%';
		elem.scope=this;
		if(elem.split){
			split=mj.NE(this.renderTo,{tag:'div',id:cnt.id+'-splitter',cls:'layout-split splitbar-'+elem.dType+(' split-'+elem.region)});
			if(elem.collapsible){
				collapser=mj.NE(split,{tag:'div',id:cnt.id+'-collapser',cls:'collapser '+collapseCls,style:'position:absolute;'+elStyle});
				var clps = $(collapser);
				clps.hover(function(){
					if(clps.hasClass('expanded'))
						clps.addClass('ex-hover');
					else
						clps.addClass('hover');
				},function(){
					clps.removeClass('ex-hover');
					clps.removeClass('hover');
				});
			}
			var drag = new mj.drag({
				el : split,
				maxHeight : mxh,
				maxWidth : mxw,
				minHeight : mnh,
				minWidth : mnw,
				dragType : elem.dType
			});
			drag.on('beforedrag',function(e){
				return !this.scope.regions[this.region].collapsed;
			},elem);
			drag.on('dragstop',function(e){
				this.scope.refreshLayout(e,this.region);
			},elem);
			split.style[style1]=this.splitSize+'px';
			split.style[style2]='100%';
			split.style[style3]=initSize+'px';
		}
		if(elem.collapsible)
			$(collapser).bind('mousedown',{region:elem.region,t:this},function(e){
				e.stopPropagation();
				try{
		            this.id.indexOf('collapser');
		        }catch(e){
					return;
				}
				var reg=e.data.region;
				e.data.t._toggleRegion(reg,!e.data.t.regions[reg].collapsed);
			});
		this.regions[elem.region]={
			region:elem.region,
			config:elem,
			container:cnt,
			splitter:split||elem.split,
			collapser:collapser,
			collapsible:elem.collapsible,
			drag:drag,
			dType:elem.dType,
			collapsed:elem.collapsed||false,
			size:size,
			initial:initSize,
			hiding:false,
			getBody:function(){return cnt;},
			collapse:function(){this.scope._toggleRegion(this.region,true);},
			expand:function(){this.scope._toggleRegion(this.region,false);},
			hide:function(){this.scope._hideRegion(this.region);},
			show:function(){this.scope._showRegion(this.region)},
			scope:this
		};
	},
	addRegion : function(el){
		if(!this.regions[el.region]){
			if(!this.items)
				this.items = [];
			this.items.push(el);
			this.createRegion(el);
			this.doLayout();
		}
	},
	getStyleName : function(region){
		var style='width';
		switch (region){
			case 'north':
			case 'south':
				style='height';
		}
		return style;
	},
	_hideRegion : function(region){
		var style=this.getStyleName(region);
		if(this.regions[region]&&region!='center'){
			var re=this.regions[region];
			re.container.style[style]='0px';
			if(re.splitter){
				re.splitter.style[style]='0px';
				$(re.splitter).addClass('mj-invisible');
			}
			$(re.container).addClass('mj-invisible');
			this.regions[region].hiding=true;
			this.doLayout();
		}
	},
	_showRegion : function(region){
		var style=this.getStyleName(region);
		if(this.regions[region]&&region!='center'){
			var re=this.regions[region];
			re.container.style[style]=(re.collapsed?0:re.initial)+'px';
			if(re.splitter){
				re.splitter.style[style]=this.splitSize+'px';
				$(re.splitter).removeClass('mj-invisible');
			}
			if(!re.collapsed)
				$(re.container).removeClass('mj-invisible');
			this.regions[region].hiding=false;
			this.doLayout();
		}
	},
	_toggleRegion : function(region,ce){//ce:collapse-expand
		if(this.regions[region]&&region!='center'){
			var el = this.regions[region];
			if(el.collapsible){
				if(el.collapsed!=ce){
					var cont = el.container;
					$(cont).toggleClass('mj-invisible');
					$(el.collapser).swapClass('collapsed','expanded');
					switch (region){
						case 'north':
						case 'south':
							var val=el.collapsed?0:$(cont).height();
							cont.style.height=el.size+'px';
							break;
						default:
							var val=el.collapsed?0:$(cont).width();
							cont.style.width=el.size+'px';
					}
					el.collapsed=!el.collapsed;
					el.size=val;
					this.doLayout();
					this.trigger('toggle', this, el, ce);
				}
			}
		}
	},
	/**
	 * layout nesnesi init fonksiyonu.
	 * @name init
	 * @function
	 * @type {Function}
	 */
	init : function(){
		this.splitSize = 5;
		this.borderSize = 1;
		var cnt;
		this.regions={};
		$(this.renderTo).addClass('border-layout-ct mj-resize-handle');
		var rnrdt=this.renderTo[0].style;
		rnrdt.width="100%";
		rnrdt.height="100%";
		rnrdt.position="relative";
		rnrdt.overflow="hidden";
		this.masterId=this.renderTo.id||mj.genId('layout-');
		cnt=mj.NE(this.renderTo,{tag:'div',id:(this.masterId+'-region-center'),cls:'border-panel center',style:'width:'+this.renderTo.width()+'px;height:'+this.renderTo.height()+'px;'});
		if(this.centerBorder.length<4){
			if(this.centerBorder.indexOf('l')==-1)
				$(cnt).css('border-left','0');
			if(this.centerBorder.indexOf('t')==-1)
				$(cnt).css('border-top','0');
			if(this.centerBorder.indexOf('r')==-1)
				$(cnt).css('border-right','0');
			if(this.centerBorder.indexOf('b')==-1)
				$(cnt).css('border-bottom','0');
		}
		this.regions['center']={
			container :cnt,
			getBody:function(){return cnt;},
			splitter :false
		};
		if(this.items)
			for(var i in this.items)
				if(typeof this.items[i]!='function')
					this.createRegion(this.items[i]);
		this.doLayout(true);
		$(window).bind("resize", {scope:this},function(e){
			e.data.scope.doLayout();
		});
		mj.bindResize(this.renderTo, this.doLayout, this);
	},
	getBody : function(region){
		if(this.regions[region])
			return this.regions[region].getBody();
	},
	refreshLayout : function(e,region){
		var proxy=$(e.proxy);
		proxy=e.proxy[0].style;
		var container=this.regions[region].container.style;
		switch (region) {
			case 'north':
				container.height=(parseInt(proxy.top)-this.borderSize)+'px';
				break;
			case 'west':
				container.width=(parseInt(proxy.left)-this.borderSize)+'px';
				break;
			case 'south':
				container.height=(this.renderTo.height()-parseInt(proxy.top)-this.borderSize-this.splitSize)+'px';
				break;
			case 'east':
				container.width=(this.renderTo.width()-parseInt(proxy.left)-this.borderSize-this.splitSize)+'px';
				break;
		}
		this.doLayout();
	},
	doLayout : function(bool){
		var rndT = this.renderTo[0],c = false, s = false,h = false,tRegs = this.regions,tRCS,ly = {regions:{}},size = 0;
		for(var r in tRegs)
			if(typeof tRegs[r] != 'function'){
				c = !!tRegs[r].collapsed;
				s = !!tRegs[r].splitter;
				h = !!tRegs[r].hiding;
				tRCS = tRegs[r].container.style;
				switch (r){
					case 'center':
						s = false;
						h = false;
						ly.regions[r]={height:rndT.offsetHeight, width:rndT.offsetWidth, top:0, left:0, collapse:c, split:s, hiding:h};
						break;
					case 'north':
						size = parseInt(tRCS.height);
						ly.regions[r]={height:size, width:'100%', top:0, left:0, collapse:c, split:s, hiding:h};
						break;
					case 'south':
						size = parseInt(tRCS.height);
						ly.regions[r]={height:size, width:'100%', top:0, left:0, collapse:c, split:s, hiding:h};
						break;
					case 'west':
						size = parseInt(tRCS.width);
						ly.regions[r]={height:0, width:size, top:0, left:0, collapse:c, split:s, hiding:h};
						break;
					case 'east':
						size = parseInt(tRCS.width);
						ly.regions[r]={height:0, width:size, top:0, left:0, collapse:c, split:s, hiding:h};
						break;
				}
			}
		var center = ly.regions.center,centerStyle = tRegs.center.container.style;
		var nr = ly.regions['north'];
		var nrs=0,srs=0,wrs=0,ers=0;
		if(nr){
			nrs = nr.hiding?0:((nr.split?this.splitSize:0)+this.borderSize);
			center.top+=nr.height+nrs;
			center.height-=nr.height+nrs;
		}else
			nr={height:0,width:0,top:0,left:0,collapse:false,split:false,hiding:false};
		var sr = ly.regions['south'];
		if(sr){
			srs = sr.hiding?0:((sr.split?this.splitSize:0)+this.borderSize);
			center.height-=sr.height+srs;
			ly.regions.south.top=center.height+nr.height+srs+nrs-this.borderSize;
		}else
			sr={height:0,width:0,top:0,left:0,collapse:false,split:false,hiding:false};
		var wr = ly.regions['west'];
		if(wr){
			wrs = wr.hiding?0:((wr.split?this.splitSize:0)+this.borderSize);
			center.left+=wr.width+wrs;
			center.width-=wr.width+wrs;
			ly.regions.west.top+=nr.height+nrs;
			ly.regions.west.height+=rndT.offsetHeight-(nr.height+sr.height+srs+nrs);
		}else
			wr={height:0,width:0,top:0,left:0,collapse:false,split:false,hiding:false};
		var er = ly.regions['east'];
		if(er){
			ers = er.hiding?0:((er.split?this.splitSize:0)+this.borderSize);
			center.width-=er.width+ers;
			ly.regions.east.top+=nr.height+nrs;
			ly.regions.east.height=rndT.offsetHeight-(nr.height+sr.height+srs+nrs);
			ly.regions.east.left+=wr.width+center.width+wrs+ers-this.borderSize;
		}else
			er={height:0,width:0,top:0,left:0,collapse:false,split:false,hiding:false};
		var regCon,regSpl,obj,obj2;
		var w = rndT.offsetWidth, h = rndT.offsetHeight;
		this.ly=ly;
		this.trigger('layoutbeforeresize',this);
		centerStyle.left=(center.left-(wr.hiding?0:wr.collapse?1:0))+'px';
		var www=(center.width-(2*this.borderSize)+(wr.hiding?0:wr.collapse?1:0)+(er.hiding?0:er.collapse?1:0));
		centerStyle.width=(www>0?www:0)+'px';
		var hhh=(center.height-(2*this.borderSize)+(nr.hiding?0:nr.collapse?1:0)+(sr.hiding?0:sr.collapse?1:0));
		centerStyle.height=(hhh>0?hhh:0)+'px';
		centerStyle.top=(center.top-(nr.hiding?0:nr.collapse?1:0))+'px';
		for(var r2 in ly.regions){
			if(typeof ly.regions[r2]!='function'&&r2!='center'){
				obj2=tRegs[r2];
				cfg=obj2.config
				regCon=obj2.container.style;
				obj=ly.regions[r2];
				switch (r2){
					case 'north':
						regCon.left=obj.left+'px';
						regCon.width=obj.width+'';
						regCon.height=obj.height+'px';
						regCon.top=obj.top+'px';
						if(ly.regions[r2].split){
							regSpl=obj2.splitter.style;
							regSpl.top=(obj.height+(obj.collapse?0:this.borderSize))+'px';
						}
						break;
					case 'south':
						regCon.left=obj.left+'px';
						regCon.width=obj.width+'';
						regCon.height=obj.height+'px';
						regCon.top=obj.top+'px';
						if(ly.regions[r2].split){
							regSpl=obj2.splitter.style;
							regSpl.top=(center.height+nr.height+nrs+(obj.collapse?this.borderSize:0))+'px';
							obj2.drag.maxHeight=(h-((cfg.min||obj2.initial)+this.borderSize+this.splitSize));
							obj2.drag.minHeight=(h-((cfg.max||obj2.initial)+this.borderSize+this.splitSize));
						}
						break;
					case 'west':
						regCon.left=obj.left+'px';
						regCon.width=(obj.width)+'px';
						regCon.height=centerStyle.height;
						regCon.top=centerStyle.top;
						if(ly.regions[r2].split){
							regSpl=obj2.splitter.style;
							regSpl.top=regCon.top;
							regSpl.height=(parseInt(regCon.height)+(2*this.borderSize))+'px';
							regSpl.left=(obj.width+(obj.collapse?0:this.borderSize))+'px';
						}
						break;
					case 'east':
						regCon.left=obj.left+'px';
						regCon.width=(obj.width)+'px';
						regCon.height=centerStyle.height;
						regCon.top=centerStyle.top;
						if(ly.regions[r2].split){
							regSpl=obj2.splitter.style;
							regSpl.top=regCon.top;
							regSpl.height=(parseInt(regCon.height)+(2*this.borderSize))+'px';
							regSpl.left=(obj.left-this.splitSize+(obj.collapse?this.borderSize:0))+'px';
							obj2.drag.maxWidth=(w-((cfg.min||obj2.initial)+this.borderSize+this.splitSize));
							obj2.drag.minWidth=(w-((cfg.max||obj2.initial)+this.borderSize+this.splitSize));
						}
				}
			}
		}
		this.renderTo.trigger('kkresize');
		this.trigger('layoutafterresize',this);
	}
};
mj.extend(mj.layout, mj.component);

/** 
 * @fileoverview Accordion Layout nesnesi oluşturan sınıf.
 * @hazırlayan kk yazılım info@mj.com
 * @sürüm 0.0.1 Beta 19.10.2007
 */
mj.accordion = function(config){
	mj.accordion.superclass.constructor.call(this, config);
};
mj.accordion.prototype={
	componentClass : 'mj.accordion',
	title : false,
	multiple : false,
	collapsible : true,
	active : -1,
	activeItem : false,
	bodyHeight : 0,
	init : function(){
		var t = this;
		t.container = mj.NE(t.renderTo);
		$(t.container).addClass('mj-resize-handle');
		t.panels = [];
		var id = t.id||mj.genId('kkaccordion-'),p;
		t.bodyHeight = parseInt(this.renderTo[0].style.height)-(t.items.length*24);
		
		for(var i=0,len=t.items.length;i<len;i++){
			var item,cfg={type:'accordion',renderTo:mj.NE(t.container,{cls:'mj-accordion'}),collapsible:t.collapsible,title:'',titleCls:'',collapsed:true,height:t.bodyHeight};
			item = t.items[i];
			cfg.disabled = false;
			if(i==t.active)
				cfg.collapsed = false;
			else
				cfg.collapsed = true;
			cfg.fitToParent = false;
			mj.apply(cfg,item);
			p=new mj.panel(cfg);
			$(p.header).bind('click',{index:i},function(e){
				t.changeActive(e.data.index);
			});
			if(i==t.active)
				t.activeItem = p;
			t.panels.push(p);
		}
		mj.bindResize(this.container, this.doPanel, this);
	},
	changeActive : function(index){
		if(!this.panels[index].disabled)
			if(!this.multiple)
				if(this.activeItem)
					if(!this.activeItem.collapsed){
						this.activeItem.collapse();
						this.active = index;
						this.activeItem = this.panels[index];
					}else{
						this.active = -1;
						this.activeItem = false;
					}
				else{
					this.active = index;
					this.activeItem = this.panels[index];
				}
	},
	doPanel : function(){
		this.bodyHeight = parseInt(this.renderTo[0].style.height)-(this.items.length*24);
		this.bodyWidth = parseInt(this.renderTo[0].style.width);
		if(this.bodyHeight!=this.lastBodyHeight||this.bodyWidth!=this.lastBodyWidth){
			for(var i=0,len=this.panels.length;i<len;i++){
				this.panels[i].body.style.height =Math.max(this.bodyHeight,0) + 'px';
				this.panels[i].body.style.width =Math.max(this.bodyWidth,0) + 'px';
				this.panels[i].container.style.width =Math.max(this.bodyWidth,0) + 'px';
				this.panels[i].header.style.width =Math.max(this.bodyWidth,0) + 'px';
			}
			this.lastBodyHeight = this.bodyHeight;
			this.lastBodyWidth = this.bodyWidth;
		}
	}
};
mj.extend(mj.accordion, mj.component);
/** 
 * @fileoverview Panel nesnesi oluşturan sınıf.
 * @hazırlayan kk yazılım info@mj.com
 * @sürüm 0.0.1 Beta 19.10.2007
 */
mj.panel = function(config){
	mj.panel.superclass.constructor.call(this, config);
};
mj.panel.prototype={
	componentClass : 'mj.panel',
	title : false,
	type : 'default',
	loaded : false,
	collapsible : false,
	border : false,
	collapsedCls : 'mj-panel-collapsed',
	disabled : false,
	fitToParent : true,
	buttonPos : 'bottom',
	init : function(){
		if(this.renderTo)
			this.render();
	},
	render : function(){
		var t = this;
		var id=t.id||mj.genId('kkpanel-');
		if(t.border&&!t.form)
			$(t.renderTo).css('border','1px solid #A3AEB7');
		if(!t.width)
			t.width = $(t.renderTo).width()||parseInt($(t.renderTo).css('width'));
		if(isNaN(t.width))
			t.width = 0;
		$(t.renderTo).css('width',t.width+'px');
		t.container = mj.NE(t.renderTo,{id:id+'-container',cls:'mj-unselectablex',style:t.itemStyle+'width:'+$(t.renderTo).css('width')+';overflow:hidden;'+(t.height?'':('height:'+($(t.renderTo).height())+'px;'))});
		$(t.container).attr('unselectable','on');
		if(t.border&&t.form)
			$(t.container).css('border','1px solid #A3AEB7');
		if(t.title){
			t.header = mj.NE(t.container,{id:id+'-header',cls:'mj-panel-header '+(t.collapsed?t.collapsedCls:'')});
			if(t.collapsible)
				t.collapseEl = mj.NE(t.header,{cls:'mj-tool mj-tool-toggle'});
			t.titleEl = mj.NE(t.header,{tag:'span',cls:["mj-title-text ", t.titleCls," mj-unselectable"].join(""),html:t.title});
			$(t.titleEl).attr('unselectable','on');
			$(t.header).attr('unselectable','on').addClass('mj-unselectable');
			if(t.collapsible){
				$(t.header).click(function(){
					if(!t.disabled){
						if(!t.collapsed)
							t.collapse();
						else
							t.expand();
						if(typeof t.handler=='function')
							t.handler();
					}
					});
			}
		}
		t.body = mj.NE(t.container,{id:id+'-body',cls:'mj-resize-handle '+(t.collapsed?'mj-invisible':''),style:'height:'+(t.height?t.height:$(t.container).innerHeight()-(t.title?24:0))+'px;width:100%;background-color:white;overflow:auto;',html:t.html||''});
		if(t.buttons){
			var x=t.buttons;
			t.buttons = [];
			if(t.attachTb){
				t.tbar = new mj.menu({
					renderTo:t.container,
					items : []
				});
				t.buttonContainer = t.tbar._el;
			}else{
				t.buttonContainer = $(mj.NE(t.container, {cls:'mj-panel-buttons-container'}));
				$(t.body).height($(t.body).height()-t.buttonContainer.height());
			}
			for(var i=0,l=x.length;i<l;i++)
				t.addButton.call(t,x[i]);
			if(t.collapsed)
				t.buttonContainer.addClass("mj-invisible");
		}
		t.getBody = function(){
			return t.body;
		};
		if(t.autoLoad){
			window.tmp = t.body;
			t.autoLoad.url += '?h=tmp';
			mj.load(t.body,t.autoLoad);
			t.loaded = true;
		}
		if(t.disabled)
			this.setDisable();
		mj.bindResize(t.container, t.doPanel, t);
		t.doPanel();
	},
	collapse : function(){
		this.collapsed = true;
		$(this.header).addClass("mj-panel-collapsed");
		$(this.body).addClass("mj-invisible");
		if(this.buttonContainer)
			this.buttonContainer.addClass("mj-invisible");
		this.height=this.renderTo.height();
		this.renderTo.height($(this.header).height()-1);
	},
	expand : function(){
		this.collapsed = false;
		$(this.header).removeClass("mj-panel-collapsed");
		$(this.body).removeClass("mj-invisible");
		if(this.buttonContainer)
			this.buttonContainer.removeClass("mj-invisible");
		this.renderTo.height(this.height>0?($(this.body).height()+$(this.header).height()+(this.buttonContainer?this.buttonContainer.height():0)):0);
		if(this.autoLoad)
			if(this.refresh){
				mj.load(this.body,this.autoLoad);
			}else{
				if(!this.loaded){
					mj.load(this.body,this.autoLoad);
					this.loaded = true;
				}
			}
		this.doPanel();
	},
	doPanel : function(){
		var h=parseInt(this.renderTo.css('height'));
		var w=this.renderTo[0].style.width.indexOf('%')>-1?this.renderTo.width():parseInt(this.renderTo[0].style.width);
		if(h!=this.lastHeight||w!=this.lastWidth){
			var th=this.header?$(this.header).height():0,tf=this.buttonContainer?parseInt($(this.buttonContainer).css('height')):0;
			h-=th;
			h-=tf;
			if(parseInt(h)>0){
				var tc = $(this.container);
				if(!this.height||this.fitToParent)
					tc.height(h+th+tf);
				if(!this.width||this.fitToParent)
					tc.width(w);
				var tb=$(this.body);
				tb.height(h);
				tb.width(w);
				tb.trigger('kkresize');
			}
			this.lastWidth = w;
			this.lastHeight = h;
		}
	},
	addButton : function(config){
		var t=this;
		if(!t.buttons)
			t.buttons = [];
		var b = config;
		if(!b.componentClass){
			mj.applyIf(b, {renderTo:mj.NE(t.buttonContainer)});
			if(t.attachTb)
				b = t.tbar.addButton(b);
			else
				b = new mj.button(b);
		}
		b.window = t;
		t.buttons.push(b);
	},
	getTitle : function(){
		return this.title;
	},
	setTitle : function(text){
		if(this.titleEl){
			this.titleEl.innerHTML = text;
			this.title = text;
		}
	},
	setDisable : function(){
		this.disabled=true;
		$(this.header).addClass('mj-item-disabled');		
	},
	setEnable : function(){
		this.disabled=false;
		$(this.header).removeClass('mj-item-disabled');
	}
};
mj.extend(mj.panel, mj.component);
mj.fullScreenPanel = function(config){
	mj.fullScreenPanel.superclass.constructor.call(this, config);
};
mj.fullScreenPanel.prototype = {
	componentClass : 'mj.fullScreenPanel',
	init : function(){
		var t=this, el = t.el = t.el ? t.el : document.body, _el = t._el = $(el);
		t.body = $(mj.NE(el, {cls:'mj-full-scren-panel'}));
		mj.bindResize(t.body, t.doResize, t);
		mj.fullScreenPanel.superclass.init.call(this);
	},
	doResize : function(){
		var t = this, m = t.body;
		var el = t._el;
		var ofs = el.offset();
		var tn = el.offsetParent().attr('tagName');
		m.css('left', (($.browser.msie&&tn=='BODY')?ofs.left:t.el.offsetLeft));
		m.css('top', (($.browser.msie&&tn=='BODY')?ofs.top:t.el.offsetTop));
		m.css('height', t.el.offsetHeight);
		m.css('width', t.el.offsetWidth);
	},
	show : function(zIndex){
		this.doResize();
		this.body.css('z-index', zIndex ? zIndex : this.zIndex);
		this.body.show();
	},
	hide : function(){
		this.body.hide();
	},
	destroy : function(){
		this.body.remove();
	}
}
mj.extend(mj.fullScreenPanel, mj.component);
/** 
 * @fileoverview Tab nesnesi oluşturan sınıf.
 * @hazırlayan kk yazılım info@mj.com
 * @sürüm 0.0.1 Beta 01.10.2007
 */
 /**
 * Yeni bir tab nesenesi oluşturur.<br>
 * @example
		var tab2 = new mj.tab({
	//renderTo : $(mj.NE(myTab.tabContents[0],{tag:'div',id:'tab-cnt2'})),
	renderTo : myTab.tabContents[0],
	innerTab : true,
	tabPosition:'bottom',
	//padding:'',
	tabScroll:false,
	border:false,
	height:377,
	items:[
		{
			title: 'Tab88',
			html: "99",
			closable:true
		}
	]
});
 * @class
 * @name mj.tab
 * @extends mj.component
 * @param {Object} config Tab objesini oluşturabilmek için gerekli olan parametreleri içerir.
 * @config {HTMLElement} renderTo Tab nesnesinin render edileceği container nesnesi.
 * @config {Number} width Genişlik.Ön tanımlı değeri:600.
 * @config {Number} height Yükseklik.Ön tanımlı değeri:250.
 * @config {Object} innerTab İç içe tab olması durumunda parent tab objesi değeri.Ön tanımlı değeri:false.
 * @config {Boolean} defaultActive İlk tabın aktif edilmesini sağlar.Ön tanımlı değeri:true.
 * @config {Boolean} tabScroll Tab sayısı gösterilecek maksimum sayıdan fazla ise sağ ve solda scroll çıkmasını sağlar.Ön tanımlı değeri:false.
	Daha kodu yazılmadı.
 * @config {Boolean} border Border olup olmamasını belirler.<i>innerTab=true</i> olması durumunda false olur.Ön tanımlı değeri:true.
 * @config {String} tabPosition Tabların pozisyon bilgisi.Ön tanımlı değeri:'top'.Belki daha sonra 'left-right' eklenebilir.
 * @config {String} padding Padding kullanılacaksa '' gönderilmelidir.Class adını içerir.Ön tanımlı değeri:'no-padding'.
 * @config {Number} activeTab Aktive eilecek olan tab nesnesi indeksi.Ön tanımlı değeri:-1.
 * @config {Object} items Tab nesneleri config bilgisi.
 */
 mj.tab = function(config){
	mj.tab.superclass.constructor.call(this, config);
};
mj.tab.prototype={
	componentClass : 'mj.tab',
	index : 0,
	/** 
	 * Tabların genişlik değeri.Ön tanımlı değeri:120.
	 * @name tabWidth 
	 * @type {Number}
	 * @memberOf  mj.tab
     */
    tabWidth: 120,
	maxTitle : 14,
	/**
	 * Genişlik.Ön tanımlı değeri:600.
	 * @name width
	 * @type {Number}
	 * @memberOf  mj.tab
	 */
	width : 600,
	/**
	 * Yükseklik.Ön tanımlı değeri:250.
	 * @name height
	 * @type {Number}
	 * @memberOf  mj.tab
	 */
	height : 250,
	/**
	 * İç içe tab olması durumunda <i>true</i> olması gereken değer.Ön tanımlı değeri:false.
	 * @name innerTab
	 * @type {Boolean}
	 * @memberOf  mj.tab
	 */
	innerTab : false,
	/**
	 * İlk tabın aktif edilmesini sağlar.Ön tanımlı değeri:true.
	 * @name defaultActive
	 * @type {Boolean}
	 * @memberOf  mj.tab
	 */
	defaultActive : true,
	/**
	 * Tab sayısı gösterilecek maksimum sayıdan fazla ise sağ ve solda scroll çıkmasını sağlar.Ön tanımlı değeri:true.
	Daha kodu yazılmadı.
	 * @name tabScroll
	 * @type {Boolean}
	 * @memberOf  mj.tab
	 */
	tabScroll : false,
	/**
	 * Border olup olmamasını belirler.<i>innerTab</i> olması durumunda false olur.Ön tanımlı değeri:true.
	 * @name border
	 * @type {Boolean}
	 * @memberOf  mj.tab
	 */
	border : true,
	/**
	 * Tabların pozisyon bilgisi.Ön tanımlı değeri:'top'.Belki daha sonra 'left-right' eklenebilir.
	 * @name tabPosition
	 * @type {String}
	 * @memberOf  mj.tab
	 */
	tabPosition : 'top',
	hideHeader : false,
	/**
	 * Padding kullanılacaksa '' gönderilmelidir.Ön tanımlı değeri:'no-padding'.
	 * @name padding
	 * @type {String}
	 * @memberOf  mj.tab
	 */
	padding : 'no-padding',
	tabs : false,
	tabBodies : false,
	tabContents : false,
	/**
	 * Aktive eilecek olan tab nesnesi indeksi.Ön tanımlı değeri:-1.
	 * @name activeTab
	 * @type {Number}
	 * @memberOf  mj.tab
	 */
	activeTab : -1,
	activeItem : false,
	/**
	 * <i>itemIndex</i> parametresi ile verilen tab nesnesini <i>activeItem</i> nesnesine ve <i>itemIndex</i> değerini <i>activeTab</i>'a atar.
	 * @name setActive
	 * @function
	 * @type {Function}
	 * @param {Number} itemIndex Seçilecek tab nesnesinin index değeri.
	 */
	setActive : function(itemIndex){
		var oldTab = this.activeTab, newTab = itemIndex;
		if(this.activeTab!=-1){
			if(this.activeItem){
				this.activeItem.active = false;
				this.activeItem.bm.addClass('mj-invisible');
				this.activeItem.title.removeClass('mj-tab-active');
			}
			this.activeTab = -1;
		}
		this.activeItem = {};
		this.tabs[itemIndex].title.addClass('mj-tab-active');
		this.activeTab = itemIndex;
		this.activeItem = this.tabs[itemIndex];
		if(this.activeItem.autoLoad){
			window.tmp = this.activeItem.bc;
			var u = this.activeItem.autoLoad.url||this.activeItem.autoLoad;
			var sign=(u.indexOf('?')>-1?'&':'?');
			u += (sign+'h=tmp');
			if(typeof this.activeItem.autoLoad=='string')
				this.activeItem.autoLoad = u;
			if(typeof this.activeItem.autoLoad=='object')
				this.activeItem.autoLoad.url = u;
			if(this.activeItem.refresh){
				mj.load(this.activeItem.bc,this.activeItem.autoLoad);
			}else{
				if(!this.activeItem.loaded){
					mj.load(this.activeItem.bc,this.activeItem.autoLoad);
					this.activeItem.loaded = true;
				}
			}
		}
		this.activeItem.bm.removeClass('mj-invisible');
		this.activeItem.bc.trigger('kkresize');
		this.tabs[itemIndex].active = true;
		this.trigger('tabchange', this, newTab, oldTab);
	},
	/**
	 * <i>item</i> parametresi ile verilen tab nesnesini <i>disable</i> eder.
	 * @name setDisable
	 * @function
	 * @type {Function}
	 * @param {Object} item Disable edilecek tab nesnesi.
	 */
	setDisable : function(item){
		item.title.addClass('mj-tab-disabled');
		item.disabled = true;
	},
	/**
	 * <i>item</i> parametresi ile verilen tab nesnesini <i>enable</i> eder.
	 * @name setEnable
	 * @function
	 * @type {Function}
	 * @param {Object} item Enable edilecek tab nesnesi.
	 */
	setEnable : function(item){
		item.title.removeClass('mj-tab-disabled');
		item.disabled = false;
	},
	/**
	 * Tab'ın addTab fonksiyonu.
	 * @name setEnable
	 * @function
	 * @type {Function}
	 * @param {Object} tc Eklenecek tab nesnesi config objesi.
	 * @config {String} title Başlık.
	 * @config {String} html Tab body içine yazılacak metin.
	 * @config {Boolean} active Active tab olması istendiğinde true yapılması gereken parametre.
	 * @config {String} iconCls Başlık metni yanında görüntülenecek resim class'ı.
	 * @config {Boolean} closable Kapanabilir olma özelliği parametresi.
	 * @config {Boolean} disabled Disable olma özelliği parametresi.
	 * @config {Boolean} refresh Her seferinde yüklenme özelliği parametresi.
	 * @config {String/Object} autoLoad Server üzerinden tabın yükleneceğini gösterir parametre.
	 * @param {Boolean} itemsNoAdd Sonradan eklenen tab'lar için null,<i>items</i> içindeki tabların eklenmesinde true.Bu parametre ile sonradan
	 bu methodun çağırılması ile eklenen tabların <i>items</i> dizisine eklenmesi sağlanmaktadır.
	 */
	addTab : function(tc,itemsNoAdd,index){//tabConfig
		var tmpID = mj.genId(), t=this;
		var item = {
			activate : function(){
				t.setActive(item.itemIndex);
			}
		};
		t.scrollPos = 0;
		item.name = tc.name?tc.name:'';
		item.title = $(mj.NE(this.tabsContainer, {cls:'mj-tab-title',style:'width:'+t.tabWidth+'px;'}));
		mj.NE(item.title, {cls:'mj-tab-title-left'});
		var c = $(mj.NE(item.title, {cls:'mj-tab-title-center'}));
		mj.NE(item.title, {cls:'mj-tab-title-right'});
		c.attr('unselectable','on');
		c.width(t.tabWidth-13);
		var ind = t.tabs.push(item)-1;
		if(tc.iconCls)
			item.icon = mj.NE(c, {cls:'mj-tab-icon '+tc.iconCls});
		item.titleText = tc.title||'';
		item.titleEl = mj.NE(c, {cls:'mj-tab-text', html:item.titleText.ellipse(t.maxTitle)});
		$(item.titleEl).attr('unselectable','on');
		item.setDisable = function(){
			this.title.addClass('mj-tab-disabled');
			this.disabled = true;
		};
		item.setEnable = function(){
			this.title.removeClass('mj-tab-disabled');
			this.disabled = false;
		};
		if(tc.disabled)
			item.setDisable();
		if(tc.closable!==false){
			item.close = $(mj.NE(c, {cls:'mj-tab-close',html:mj.insertSpacer(11,11)}));
			item.close.click(function(e){
				var ind = t.tabs.indexOf(item);
				if(!item.disabled && t.trigger('closeclick', t, item, ind)!==false)
					t.remove(ind);
				e.stopPropagation();
			});
		}
		item.title.click(function(){
			if(!item.active && !item.disabled){
				var ind = t.tabs.indexOf(item);
				t.trigger('click', t, ind);
				t.setActive(ind);
				item.title.removeClass('mj-tab-hover');
			}
		});
		item.title.hover(function(){
			if(!item.active && !item.disabled)
				item.title.addClass('mj-tab-hover');
		}, function(){
			item.title.removeClass('mj-tab-hover');
		});
		item.bm = $(mj.NE(this.body,{tag:'div',cls:'mj-tab-panel-b panel-noborder '+(tc.active?'':'mj-invisible'),style:'width:'+(this.width)+'px;'}));
		item.bw = mj.NE(item.bm,{tag:'div',cls:'tab-panel-bwrap'});
		item.container = item.bc = $(mj.NE(item.bw,{tag:'div',cls:'mj-resize-handle panel-body panel-body-noheader mj-tab-noborder '+(this.padding||'panel-body-pad'),style:'overflow: auto; width: '+(this.width)+'px; height: '+(this.height-(this.padding?28:48))+'px;',html:tc.html}));
		item.autoLoad = tc.autoLoad;
		item.refresh = tc.refresh;
		item.getBody = function(){
			return this.bc;
		};
		item.getTitle = function(){
			return this.titleText;
		};
		item.setTitle = function(text){
			this.titleText = text;
			this.titleEl.innerHTML = text.ellipse(t.maxTitle);
		};
		if(!itemsNoAdd){
			if(!this.items)
				this.items=[];
			this.items.push(item);
			var ind = this.items.length-1
		}	
		else{
			this.items[index]=item;
			var ind = index;
		}	
		item.itemIndex = ind;
		item.name = tc.name?tc.name:ind;
		if(!item.disabled)
			this.setActive(ind);
		t.itemx=item;
		t.doAddTab();
		//mj.bindResize(item.bm, t.doAddTab, t);
		this._scrollLeft();
	},
	doAddTab : function(){
		var w = parseInt(this.body[0].style.width)||this.body.width();
		var h = parseInt(this.body[0].style.height)||this.body.height();
		this.itemx.bm.kkresizewidth(w,true);
		this.itemx.bm.kkresizeheight(h,true);
		$(this.itemx.bw).kkresizeheight(h,true);
		this.itemx.bc.kkresizewidth(w,true);
		this.itemx.bc.kkresizeheight(h);
		var l = this.items.length, width = this.tabsScroller.width(), itemCount = Math.floor(width / this.tabWidth);
		this.scrollParams = {l:l, width:width, itemCount:itemCount,scrollLeft:(-(l-itemCount)*this.tabWidth)};
	},
	_scrollLeft : function(){
		var l = this.scrollParams.l, width = this.scrollParams.width, itemCount = this.scrollParams.itemCount, scrollLeft = this.scrollParams.scrollLeft;
		if(l>itemCount&&width>this.tabWidth)
			this.scrollPos  = scrollLeft;
		else
			this.scrollPos = 0;
		if(!$.browser.msie)
			this.tabsContainer.css('left', this.scrollPos);
		else
			this.tabsContainer.css('margin-left', this.scrollPos);
		
		this._updateScroll();		
	},
	_scrollRight : function(){
		var sayi = this.items.length+(this.scrollPos/this.tabWidth);
		if(sayi>this.scrollParams.itemCount){			
			this.scrollPos -= this.tabWidth;
			if(!$.browser.msie)
				this.tabsContainer.css('left', this.scrollPos);
			else
				this.tabsContainer.css('margin-left', this.scrollPos);
			this._updateScroll();	
		}
	},
	/**
	 * <i>itemIndex</i> parametresi ile verilen tab nesnesini <i>remove</i> eder.
	 * @name remove
	 * @function
	 * @type {Function}
	 * @param {Number} itemIndex Remove edilecek tab nesnesi.
	 */
	remove : function(itemIndex){
		var l = this.tabs.length;
		if(l>1){
			var item = this.tabs[itemIndex];
			item.title.remove();
			item.bm.remove();
			this.tabs.splice(itemIndex,1);
			this.items.splice(itemIndex,1);
			var l = this.items.length, width = this.tabsScroller.width(), itemCount = Math.floor(width / this.tabWidth);
			this.scrollParams = {l:l, width:width, itemCount:itemCount,scrollLeft:(-(l-itemCount)*this.tabWidth)};
			this._updateScroll();
			for(var i=0;i<l;i++)
				if(!this.tabs[i].disabled){
					this.setActive(i);
					break;
				}
		}
		//this._scrollLeft();
	},
	_updateScroll : function(){
		var t=this,scl=t.scrollLeft,scr=t.scrollRight;
		if(t.scrollPos == 0){
			scl.disabled = true;
			scl.addClass('mj-tab-scl-disabled');
		}else{
			scl.disabled = false;
			scl.removeClass('mj-tab-scl-disabled');
		}
		//if(t.scrollPos == t.scrollParams.scrollLeft){
		var sayi = this.items.length+(this.scrollPos/this.tabWidth);
		if(sayi==this.scrollParams.itemCount){
			scr.disabled = true;
			scr.addClass('mj-tab-scr-disabled');
		}else{
			scr.disabled = false;
			scr.removeClass('mj-tab-scr-disabled');
		}
	},
	/**
	 * Tab nesnesi init fonksiyonu.
	 * @name init
	 * @function
	 * @type {Function}
	 */
	init : function(){
		var fark={w:0,h:0}, at = this.activeTab, t=this;
		this.tabs = [],this.tabBodies = [],this.tabContents = [];
		t.cnt = t.renderTo;
		if(this.innerTab){
			this.width=this.innerTab.body.width()||parseInt(this.innerTab.activeItem.getBody()[0].style.width);
			this.height=(this.innerTab.body.height()||parseInt(this.innerTab.activeItem.getBody()[0].style.height))-(this.hideHeader ? 0 : 26);
			if($.browser.msie)
				fark.w=0,fark.h=0;
			else
				fark.w=2,fark.h=4;
			this.renderTo.empty();
		}else
			this.renderTo = $(mj.NE($(this.renderTo).empty()));
		this.renderTo.width((this.width-fark.w)+'px').height((this.height-fark.h)+'px').addClass('mj-tab-panel '+(this.border?'':' mj-tab-noborder'));
		if(this.innerTab) this.border=false;
		if(this.tabPosition=='top'){
			this.header = $(mj.NE(this.renderTo,{tag:'div',id:mj.genId('t-'),cls:'mj-tab-panel-header mj-unselectable '+(this.tabScroll?'tab-scrolling':''),style:'-moz-user-select: none;width: '+(this.width)+'px;'+(this.hideHeader ? 'display:none;' : '')}));
			this.bodyContainer = $(mj.NE(this.renderTo,{tag:'div',id:mj.genId('t-'),cls:'tab-panel-bwrap'}));
		}else{
			this.bodyContainer = $(mj.NE(this.renderTo,{tag:'div',id:mj.genId('t-'),cls:'tab-panel-bwrap'}));
			this.header = $(mj.NE(this.renderTo,{tag:'div',id:mj.genId('t-'),cls:'mj-tab-panel-footer mj-unselectable '+(this.tabScroll?'tab-scrolling':''),style:'-moz-user-select: none;width: '+(this.width)+'px;'+(this.hideHeader ? 'display:none;' : '')}));
		}
		t.scl = this.scrollLeft = $(mj.NE(this.header,{cls:'mj-tab-scroll-left'}));
		t.scl.hover(function(){
			if(!t.scl.disabled)
				t.scl.addClass('mj-tab-scroll-left-hover');
		},function(){
			t.scl.removeClass('mj-tab-scroll-left-hover');
		});
		t.scl.click(function(){
			if(!t.scl.disabled){
				t.scrollPos += t.tabWidth;
				if(!$.browser.msie)
					t.tabsContainer.css('left', t.scrollPos);
				else
					t.tabsContainer.css('margin-left', t.scrollPos);
				t._updateScroll();
			}
		});
		this.tabsScroller = $(mj.NE(this.header,{cls:'mj-tab-container'}));
		t.scr = this.scrollRight = $(mj.NE(this.header,{cls:'mj-tab-scroll-right'}));
		t.scr.hover(function(){
			t.scr.addClass('mj-tab-scroll-right-hover');
		},function(){
			t.scr.removeClass('mj-tab-scroll-right-hover');
		});
		t.scr.click(function(){
			if(!t.scr.disabled)
				t._scrollRight();
		});
		this.tabsContainer = $(mj.NE(this.tabsScroller,{cls:'mj-tab-container-scroll'}));
		if($.browser.msie)
			this.tabsContainer.css('position','static');
		this.body = $(mj.NE(this.bodyContainer,{tag:'div',id:mj.genId('t-'),cls:"mj-resize-handle tab-panel-body"+(this.border?'':' mj-tab-noborder')+" tab-panel-body-"+this.tabPosition,style:'width: '+(this.width-2)+'px; height: '+(this.height-28)+'px;>'}));	
		t.doTab();
		if(this.items){
			for(var i in this.items){
				if(typeof this.items[i]!='function')
					this.addTab(this.items[i],true,i);
			}
			if(typeof at=='number' && at>-1)
				this.setActive(at);
		}
		mj.bindResize(t.cnt, t.doTab, t);
	},
	doTab : function(){
		var t = this;
		if(t.innerTab){
			var w=t.innerTab.body.width()||parseInt(t.innerTab.body[0].style.width);
			var h=t.innerTab.body.height()||parseInt(t.innerTab.body[0].style.height);
			t.cnt.width(w);
			t.cnt.height(h);
		}
		t.width = t.cnt.width()||parseInt(t.cnt[0].style.width);
		t.height = t.cnt.height()||parseInt(t.cnt[0].style.height);
		if(t.width!=t.lastWidth||t.height!=t.lastHeight){
			t.renderTo.kkresizewidth(t.width-(t.border?2:0),true);
			t.renderTo.kkresizeheight(t.height-(t.border?2:0));
			var w=parseInt(t.renderTo[0].style.width)||t.renderTo.width(),h=parseInt(t.renderTo[0].style.height)||t.renderTo.height();
			t.header.width((w>0?w:0));
			var bdH=h>27?h-(this.hideHeader ? 0 : 27):0;
			t.bodyContainer.width(w);
			t.bodyContainer.height(bdH);
			t.body.kkresizeheight(bdH,true);
			t.body.kkresizewidth(w,true);
			var w = parseInt(this.body[0].style.width)||this.body.width();
			var h = parseInt(this.body[0].style.height)||this.body.height();
			if(this.items){
				for(var i=0,len=this.items.length;i<len;i++){
					if(this.items[i].bm){ 
						this.items[i].bm.kkresizewidth(w,true);
						this.items[i].bm.kkresizeheight(h,true);
						$(this.items[i].bw).kkresizeheight(h,true);
						this.items[i].bc.kkresizewidth(w,true);
						this.items[i].bc.kkresizeheight(h);
					}
				}
				if(t.scrollable!==true && t.width >= (t.items.length * t.tabWidth)){
					t.scl.addClass('mj-invisible');
					t.scr.addClass('mj-invisible');
					t.tabsScroller.width(t.width);
				}else
					t.tabsScroller.width((t.width-32-(t.border?2:0))>0?(t.width-32-(t.border?2:0)):0);
				var l = t.items.length, width = t.tabsScroller.width(), itemCount = Math.floor(width / t.tabWidth);
				t.scrollParams = {l:l, width:width, itemCount:itemCount,scrollLeft:(-(l-itemCount)*t.tabWidth)};
			}
			t.body.trigger('kkresize');
			t.lastWidth = t.width;
			t.lastHeight = t.height;
		}
	},
	getShortCuts : function(){
		var t=this, s = {};
		for(var i=0,l=t.tabs.length;i<l;i++)
			s[t.tabs[i].name] = t.tabs[i];
		return s;
	}
};
mj.extend(mj.tab, mj.component);

/**
	//data icindeki iconCls classi verilirken .mj-tree-node-el .classAdi seklinde bir class tanimlanmali
*/
mj.tree = function(config){
	mj.tree.superclass.constructor.call(this, config);
};
mj.tree.prototype = {
	componentClass : 'mj.tree',
	root : {
		text : 'myJUI',
		id : 'root',
		expanded : true
	},
	rootHide : true,
	check : false,
	icon : false,
	store : false,
	loadMask : true,
	lines : false,
	mode : false,
	expanded : false,
	clearOnBeforeLoad : true,
	trackMouseOver : true,
	dblClickToggle : true,
	drag : false,
	dragExpandDelay : 600,
	//private
	_dragHandle : false,
	//private
	_nodes : false,
	//private
	_nodesObj : false,
	//private
	_dragEls : false,
	//private
	_dropEls : false,
	//private
	_jsonData : false,
	init : function(){
		this._dropEls = [];
		this._dragEls = [];
		this.cnt = $(mj.NE(this.renderTo,{cls:'mj-tree',style:'position:relative;'}));
		this.cnt.bind('dblclick',{scope:this},this._dblClick);
		this.cnt.bind('mousedown',{scope:this},this._onMouseDown);
		this.cnt.bind('click',{scope:this},this._onClick);
		this.cnt.bind('contextmenu',{scope:this},this._context);
		if(this.trackMouseOver){
			this.cnt.bind('mouseover',{scope:this},this._onOverFn);
			this.cnt.bind('mouseout',{scope:this},this._onOutFn);
		}
		if(this.loadMask)
			this.mask = new mj.mask({el:this.renderTo[0]});
		this.store.on('beforeload', function(){
			if(this.loadMask)
				this.mask.show(50);
			if(this.clearOnBeforeLoad){
				var cnt = !this.loadingNode ? this.cnt : this.loadingNode.el.next();
				cnt.empty();
			}
			if(this.drag){
				for(var i=0;i<this._dragEls.length;i++)
					this._dragEls[i].dropEls = [];
				this._dropEls = [];
			}
		}, this);
		this.store.on('load',function(){
			this._treeLoad.call(this);
		},this);
		// this.expand._oScope = this;
		mj.bindResize(this.cnt, this.doRender, this);
	},
	load : function(){
		if(this.store)
			this.store.load();
	},
	//private
	_treeLoad : function(){
		if(this.mode=='remote')
			var tmp = this.selectedNode;
		this.selectedNode = false;
		var par = false,f=false, pNode;
		var _d = this.store.data;
		if(this.cm){
			var _hEl = $('div.mj-tree-header-row',this.cnt);
			if(_hEl.length == 0){
				var _w = 0, _hc = [];
				for(var i = 0, l = this.cm.length;i<l;i++){
					var item = this.cm[i];
					_w += item.width||0;
					_hc.push('<div class="mj-tree-c-hd mj-tree-c-hd-'+(i==0?'first':'')+'" style="width:'+(i==0?(item.width):item.width)+'px;"><div class="mj-tree-c-hd-text">'+item.header+'</div></div>');
				}
				this.cnt.width(_w+20);
				_hc.push('<div class="mj-tree-c-clear"></div>');
				mj.NE(this.cnt, {id:this.root.id+'-header',cls:"mj-grid-header-row mj-unselectable", html:_hc.join('')});
			}
		}
		if(this.loadingNode){
			loadCnt = this.loadingNode.el.next();
			par = this.loadingNode;
			par.data = _d;
		}else{
			this._nodes = {};
			this._nodesObj = {};
			var loadCnt = $(mj.NE(this.cnt,{tag:"ul",id:this.root.id,cls:"mj-tree-root-ct mj-tree"+(this.lines?'':'-no')+"-lines"}));
			if(!this.rootHide){
				this.root['root'] = true;
				this.root.nodeId = false; 
				this._addNode([this.root],loadCnt,par,false,false);
				loadCnt = $('ul.mj-tree-node-ct',this.root.cnt);
				if(!this.root.expanded)
					this.collapse(this.root);
				par = this.root;
			}else
				loadCnt = $(mj.NE(loadCnt,{cls:"mj-tree-root-node"}));
			this.root.nodeId = "0";
			this.root.data = _d;
		}
		this._addNode(_d,loadCnt,par,false,false);
		if(this.loadMask)
			this.mask.hide();
		this.loadingNode = false;
		if(this.mode=='remote')
			this.selectedNode = tmp;
		if(this.mode != 'remote' && this.expanded)
			this.expandAll();
		this._createNodesObj(false,true);
		this.trigger('load',this);
	},
	addNode : function(data,cnt,parent,after){
		this._addNode(data,cnt,parent,after,true);
		this._createNodesObj(false,true);
	},
	//private
	_addNode : function(data,cnt,parent,after,addData){
		var i=-1,d=[];
		if(data instanceof Array == false){
			d.push(data);
		}else
			d = data;
		var f = parent.nodeId?parent.nodeId+'/':false;
		while(++i<d.length){
			var item = d[i];
			if(item){
				var x,v=false;
				
				if(after){
					var n = this.getNodeById($('div:first',after)[0].id);
					if(n.root)
						v = 1;
					else
						if(n.leaf)
							v = 2;
						else 
							if(n.expanded)
								v = 3;
							else
								v = 4;
				}else
					v = 5;
				
				if(!after){
					x = f?(f + (addData&&parent.data?parent.data.length:i.toString())):i.toString();
				}else{
					var node,nIdx;
					switch (v) {
					case 1:
						node = this.getNodeById($('div:first',n.el.next())[0].id);
						nIdx = 0;
						break;
					case 2:
						node = this.getNodeById($('div:first',after)[0].id);
						nIdx = this.getNodeIndex(node,'id',node.id)+1;
						break;
					case 3:
						node = this.getNodeById($('div:first',n.el.next())[0].id);
						nIdx = 0;
						break;
					case 4:
						node = this.getNodeById($('div:first',after)[0].id);
						nIdx = this.getNodeIndex(node,'id',node.id)+1;
						break;
					case 5:
						break;
				};
				x = f + nIdx;
				}
				if(!item.id)
					item.id = mj.genId("tree-node-");
				item.parent = parent;
				if(parent.leaf){
					parent.leaf = false;
					parent.el.replaceclass('mj-tree-node-leaf','mj-tree-node-collapsed');
					$('img.mj-tree-ce-icon:first',parent.el).addClass('mj-tree-elbow-plus');
				}
				if(addData){
					parent.data = parent.data||[];
					if(!after)
						parent.data.push(item);
					else
						parent.data.splice(nIdx,0,item);
					if(this.check)
						item.checked = parent.checked;
				}
				item.nodeId = x;
				item.cnt = cnt;
				item.leaf = (typeof item.leaf == 'undefined')?(item.data||item.root)?false:true:item.leaf;
				var tmpl = this._getNodeTemplate(item);
				switch (v) {
					case 1:
						v = $(tmpl).insertBefore($('li:first',cnt));
						item.el = $('div.mj-tree-node-el:first',v);
						break;
					case 2:
						v = $(tmpl).insertAfter(after);
						item.el = $('div.mj-tree-node-el:first',v);
						break;
					case 3:
						v = $(tmpl).insertBefore($('li:first',n.el.next()));
						item.el = $('div.mj-tree-node-el:first',v);
						break;
					case 4:
						v = $(tmpl).insertAfter(n.el.parent());
						item.el = $('div.mj-tree-node-el:first',v);
						break;
					case 5:
						item.cnt.append(tmpl);
						item.el = $('div.mj-tree-node-el:last',item.cnt);
						break;
				};
				if(this.drag){
					if(!item.root){
						var t = this;
						item.dragEl = new mj.drag({el:$('a>span',item.el),moving :false,position:'static',dropOverCls:'mj-tree-drag-drop-hover',dropBottomCls:'mj-tree-drag-drop-bottom',dropEls:this._dropEls,proxyEl:{width:80,height:18},parent : mj.bd});
						this._dragEls.push(item.dragEl);
						if(!t._dragHandle)
							t._dragHandle = item.dragEl;
						item.dragEl.on('dragstop',function(e,b){
							if(b){
								if(e.curDrop&&e.fromDrop!=e.curDrop){
									var fEl=t.getNodeById(e.fromDrop[0].id), tEl=t.getNodeById(b[0].id), bt = false;
									if(b.hasClass(e.dropBottomCls)){
										tEl = (tEl.leaf||!tEl.expanded)?tEl.parent:tEl;
										bt = b.parent();
									}
									if(fEl&&tEl)
										t._moveNode(fEl,tEl,bt);
								}
								if(b.hasClass(e.dropBottomCls))
									b.removeClass(e.dropBottomCls);
							}
						});
						item.dragEl.on('onDropOver',function(e,b){
							if(e.curDrop&&e.fromDrop!=e.curDrop){
								var tEl = t.getNodeById(b[0].id);
								if(tEl&&!tEl.leaf&&!tEl.expanded&&!b.hasClass(e.dropBottomCls)){
									if(t._expandTimer)
										clearTimeout(t._expandTimer);
									t._expandTimer = setTimeout(function(){t.expand(tEl,t);},t.dragExpandDelay);
								}
							}
						});
						item.dragEl.on('onDropOut',function(e,b){
							if(t._expandTimer)
								clearTimeout(t._expandTimer);
						});
					}
					this._dropEls.push(item.el);
				}
				if(!item.leaf&&item.expanded)
					this.expand(item);
				this._nodes[item.id] = item;
				if(this.check && item.checked)
					this._checkfn(item,item.checked);
				if(item.data&&!item.root)
					this._addNode(item.data,$('ul',item.el.parent()),item,false,false);
				this.trigger('addnode',item);
			}
		}
	},
	removeNode : function(node){
		if(!node.root){
			if(node.data){
				while(node.data&&node.data.length>0)
					this.removeNode(node.data[0]);
				delete node.data;
				this.removeNode(node);
			}else{
				if(this.check)
					this._checkfn(node);
				this._dropEls.remove(this._nodes[node.id].el);
				delete this._nodes[node.id];
				$(node.el).parent().remove();
				var p = node.parent, d = p.data;
				if(d){
					d.remove(d[d.indexOf(node)]);
					if(d.length == 0 && this.mode != 'remote'){
						p.leaf = true;
						p.el.replaceclass('mj-tree-node-'+(p.expanded?'expanded':'collapsed'),'mj-tree-node-leaf');
						$('img.mj-tree-ce-icon:first',p.el).removeClass('mj-tree-elbow-'+(p.expanded?'minus':'plus'));
						p.expanded = false;
						delete p.data;
					}
				}
			}
		}
	},
	//private
	_moveNode : function(from,to,after){
		var obj = {};
		for(var s in from)
			if(typeof from[s]!== 'function' && typeof from[s]!== 'object' )
				obj[s] = from[s];
			else if (s=='data'){
				obj[s] = [];
				mj.cloneObject(from[s],'data',obj[s]);
			}
		this.removeNode(from);
		this._addNode(obj,to.el.next(),to,after,true);
		this._createNodesObj(false,true);
	},
	//private
	_createNodesObj : function(items,clear){
		if(clear){
			this._nodesObj = {};
			if(!this.rootHide)
				this._nodesObj[this.root.nodeId] = this.root;
		}
		if(!items)
			items = this.root.data;
		if(items)
			for(var i=0,len=items.length;i<len;i++){
				var f = (items[i].parent?items[i].parent.nodeId:items[i].nodeId) + '/' + i;
				items[i].prev = items[i-1];
				items[i].next = items[i+1];
				items[i].nodeId = f;
				this._nodesObj[f] = items[i];
				if(items[i].data)
					this._createNodesObj(items[i].data,false);
			}
	},
	//private
	_getNodeTemplate : function(data){
		var tmp = [],ci = '';
		var ce = (data.data||data.root)?((!data.leaf&&data.expanded)?'mj-tree-node-expanded':'mj-tree-node-collapsed'):((this.mode!=='remote'||data.leaf)?'mj-tree-node-leaf':(!data.leaf&&data.expanded)?'mj-tree-node-expanded':'mj-tree-node-collapsed');
		if(ce == 'mj-tree-node-collapsed')
			ci = 'mj-tree-elbow-plus';
		else if(ce == 'mj-tree-node-expanded')
			ci = 'mj-tree-elbow-minus';
		//ci += data.root ? '-end':'';
		var iconCls = false;
		if(data.iconCls)
			iconCls = data.iconCls;
		if(!data.root){
			tmp.push('<li class="mj-tree-node">');
			tmp.push('<div unselectable="on" class="mj-tree-node-el mj-unselectable '+ce+'" id="'+data.id+'">');
			if(this.cm)
				tmp.push('<div name="c-col-0" class="mj-tree-c-col c-col-0" style="width:'+this.cm[0].width+'px;">');
			tmp.push('<span class="mj-tree-indent">');
			var i=-1;
			while(++i<data.nodeId.toString().split('/').length-1){
				var lc = (!this.rootHide && i>0||this.rootHide)? 'mj-tree-elbow-line' : '';
				tmp.push('<img class="mj-tree-icon '+lc+'" src="'+mj.glb.blankImage+'"/>');
			}
			tmp.push('</span>');
			tmp.push('<img class="mj-tree-ce-icon mj-tree-elbow '+ci+'" src="'+mj.glb.blankImage+'"/>');//line
			if(this.check){
				tmp.push('<input class="node-cb mj-unselectable mj-invisible" unselectable="on" type="checkbox" ' + (data.checked ? 'checked="checked" />': ' />'));
				tmp.push('<div style="width: 16px;height:16px;float:left;" class="mj-checkbox '+(data.checked?'mj-checkbox-checked':'')+'"></div>' );
			}
			if(this.icon)
				tmp.push('<img style="'+(data.icon?'background-image:url('+mj.glb.blankImage+');':'')+'" unselectable="on" class="mj-tree-node-icon '+(iconCls||'')+'" src="'+(data.icon?data.icon:mj.glb.blankImage)+'" id="'+data.id+'-dd"/>');//ikon
			tmp.push('<a id="'+data.id+'-a" href="" class="mj-tree-node-anchor" hidefocus="on">');//link
			tmp.push('<span unselectable="on" id="'+data.id+'-text">');
			tmp.push(data.text);
			tmp.push('</span>');
			tmp.push('</a>');
			if(this.cm){
				tmp.push('</div>');
				var j=0, el;
				while(++j<this.cm.length){
					el = this.cm[j];
					var cellData = el.renderer ? (typeof data[el.dataIndex] == 'undefined'?'&nbsp;': this.cm[j].renderer.call(this, data[el.dataIndex], data)) : data[el.dataIndex];
					tmp.push('<div name="c-col-'+j+'" class="mj-tree-c-col c-col-'+j+'" style="width:'+el.width+'px;padding-left:1px;"><div class="mj-tree-c-text c-text-'+j+'">'+cellData+'</div></div>');
				}
				tmp.push('<div class="mj-tree-c-clear"></div>');
			}
			tmp.push('</div>');
			tmp.push('<ul class="mj-tree-node-ct mj-invisible" style="position:static;"/>');
			tmp.push('</li>');
		}else{
			tmp.push('<li class="mj-tree-node">');
			tmp.push('<div unselectable="on" class="mj-tree-node-el mj-unselectable '+ce+'" id="'+data.id+'">');
			if(this.cm)
				tmp.push('<div name="c-col-0" class="mj-tree-c-col c-col-0" style="width:'+this.cm[0].width+'px;">');
			tmp.push('<span class="mj-tree-indent">');
			var i=-1;
			while(++i<data.nodeId.toString().split('/').length-1)
				tmp.push('<img class="mj-tree-icon" src="'+mj.glb.blankImage+'"/>');
			tmp.push('</span>');
			tmp.push('<img class="mj-tree-ce-icon mj-tree-elbow '+ci+'" src="'+mj.glb.blankImage+'"/>');//line
			if(this.check){
				tmp.push('<input class="node-cb mj-unselectable mj-invisible" unselectable="on" type="checkbox" ' + (data.checked ? 'checked="checked" />': ' />'));
				tmp.push('<div style="width: 16px;height:16px;float:left;" class="mj-checkbox '+(data.checked?'mj-checkbox-checked':'')+'"></div>' );
			}
			if(this.icon)
				tmp.push('<img style="'+(data.icon?'background-image:url('+mj.glb.blankImage+');':'')+'" unselectable="on" class="mj-tree-node-icon '+(iconCls||'')+'" src="'+(data.icon?data.icon:mj.glb.blankImage)+'" id="'+data.id+'-dd"/>');//ikon
			tmp.push('<a id="'+data.id+'-a" href="" class="mj-tree-node-anchor" hidefocus="on">');//link
			tmp.push('<span unselectable="on" id="'+data.id+'-text">');
			tmp.push(data.text);
			tmp.push('</span>');
			tmp.push('</a>');
			if(this.cm){
				tmp.push('</div>');
				var j=0;
				while(++j<this.cm.length){
					var cellData = this.cm[j].renderer ? (typeof data[this.cm[j].dataIndex] == 'undefined'?'&nbsp;': this.cm[j].renderer(data[this.cm[j].dataIndex], data)) : data[this.cm[j].dataIndex];
					tmp.push('<div name="c-col-'+j+'" class="mj-tree-c-col c-col-'+j+'" style="width:'+this.cm[j].width+'px;padding-left:1px;"><div class="mj-tree-c-text c-text-'+j+'">'+(cellData)+'</div></div>');
				}
				tmp.push('<div class="mj-tree-c-clear"></div>');
			}
			tmp.push('</div>');
			tmp.push('<ul class="mj-tree-node-ct" style="position:static;"/>');
			tmp.push('</li>');
		}
		return tmp.join('');
	},
	doRender : function(){
		$(this.cnt).kkresizeheight(this.cnt.height());
	},
	collapse : function(node){
		if(!node||node.leaf)
			return false;
		node.expanded = false;
		var nodeEl = node.el;
		var iconEl = $('img.mj-tree-ce-icon:first',nodeEl);
		nodeEl.replaceclass('mj-tree-node-expanded','mj-tree-node-collapsed');
		iconEl.replaceclass('mj-tree-elbow-minus','mj-tree-elbow-plus');
		iconEl.replaceclass('mj-tree-elbow-minus-end','mj-tree-elbow-plus-end');
		nodeEl.next().addClass('mj-invisible');
		if(this.mode == 'remote' && !node.root)
			while(node.data&&node.data.length>0)
				this.removeNode(node.data[0]);
		if(this.drag&&this._dragHandle)
			this._dragHandle.initDrops();
	},
	collapseAll : function(){
		for(var item in this._nodes)
			if(typeof this._nodes[item] != 'function' && this._nodes[item].expanded)
				this.collapse(this._nodes[item]);
	},
	expand : function(node,sc){
		// if(this != arguments.callee._oScope)
			// return arguments.callee.apply(arguments.callee._oScope, arguments);
		var scope = sc || this;
		if(!node||node.leaf)
			return false;
		node.expanded = true;
		var nodeEl = node.el;
		var iconEl = $('img.mj-tree-ce-icon:first',nodeEl);
		nodeEl.replaceclass('mj-tree-node-collapsed','mj-tree-node-expanded');
		iconEl.replaceclass('mj-tree-elbow-plus','mj-tree-elbow-minus');
		iconEl.replaceclass('mj-tree-elbow-plus-end','mj-tree-elbow-minus-end');
		if(scope.mode == 'remote' && !node.root){
			scope.loadingNode = node;
			scope.store.params.node = node.id;
			scope.store.load();
			scope.store.params.node = scope.root.id;
		}
		nodeEl.next().removeClass('mj-invisible');
		if(scope.drag&&scope._dragHandle)
			scope._dragHandle.initDrops();
	},
	expandAll : function(){
		for(var item in this._nodes)
			if(typeof this._nodes[item] != 'function' && !this._nodes[item].leaf && !this._nodes[item].expanded)
				this.expand(this._nodes[item]);
	},
	checkAll : function(){
		var node;
		if(this.check)
			for(var item in this._nodes)
				if(typeof this._nodes[item] != 'function' && !this._nodes[item].checked){
					node = this._nodes[item];
					this._checkfn(node,true);
				}
	},
	clearCheckedAll : function(){
		var node;
		if(this.check)
			for(var item in this._nodes)
				if(typeof this._nodes[item] != 'function' && this._nodes[item].checked){
					node = this._nodes[item];
					this._checkfn(node,false);
				}
	},
	getRootNode : function(){
		return this.root;
	},
	getNodeById : function(name){
		if(this._nodes[name])
			return this._nodes[name];
		return false;
	},
	getNodeIndex : function(node,key,keyValue){
		return parseInt(node.parent.data.getIndex(key,keyValue));
	},
	getNodeIdByKey : function(key,keyValue){
		return mj.getIndex(this._nodes,key,keyValue);
	},
	getNodeByKey : function(key,keyValue){
		var ni = mj.getIndex(this._nodes,key,keyValue);
		if(ni != -1)
			return this._nodes[ni];
		else
			return false;
	},
	clearSelected : function(){
		if(this.selectedNode){
			this.selectedNode.el.removeClass("mj-tree-selected");
			delete this.selectedNode;
		}
	},
	selectNode : function(node,select){
		this.clearSelected();
		if(node){
			this.selectedNode = node;
			node.el.addClass("mj-tree-selected");
			if(select){
				var x=node.nodeId.split('/'),name='';
				for(var i=0,l=x.length;i<l;i++){
					name+=x[i];
					if(!this._nodesObj[name].expanded)
						this.expand(this._nodesObj[name]);
					name+='/';
				}
			}
		}
	},
	getSelected : function(){
		if(this.selectedNode)
			return this.selectedNode;
		else
			return false;
	},
	//private
	_checkfn : function(node,check){
		var t = this;
		if(node){
			var el = $('div.mj-checkbox',node.el),elp=el.prev(),ch=(typeof check != 'undefined')?check:!elp.attr('checked'),pNode;
			node.checked = ch;
			elp.addClass('checked');
			elp.parents('li:first').find('input').attr('checked',ch).css('opacity','1');
			var l=el.parents('li');
			if(ch){
				l.filter('has("checked")').find('input:first').attr('checked',ch);
				el.addClass('mj-checkbox-checked').css('opacity','1');
			}else{
				el.parents('li:first').find('.mj-checkbox').each(function(){
					$(this).removeClass('mj-checkbox-checked').css('opacity','1');
					var myNode = t.getNodeById($(this).parent()[0].id);
					myNode.checked = false;
				});
			}
			var c=l.find('input:checked');
			for(var i=0,len=c.length;i<len;i++){
				var p=$(c[i]).parents('li:first'),lc=p.find('input:checked').length,luc=p.find('input:checkbox').length;
				pNode = this.getNodeById($(c[i]).parent()[0].id);
				if(lc==1&&lc!=luc){
					$(c[i]).attr('checked',false).css('opacity','1');
					$(c[i]).next().removeClass('mj-checkbox-checked').css('opacity','1');
					pNode.checked = false;
				}else if(lc!=0&&lc<luc){
					$(c[i]).attr('checked',true).css('opacity','0.2');
					$(c[i]).next().addClass('mj-checkbox-checked').css('opacity','0.4');
				}else if(lc==luc){
					$(c[i]).attr('checked',true).css('opacity','1');
					$(c[i]).next().addClass('mj-checkbox-checked').css('opacity','1');
					pNode.checked = true;
				}
			}
		}
	},
	//private
	_onClick : function(e){
		var t = e.data.scope;
		e.preventDefault();
		return false;
	},
	//private
	_onMouseDown : function(e){
		var t = e.data.scope;
		var event = t._getEventType(e);
		var node = t.getNodeById(t._getNodeIdFromEvent(e));
		switch(event){
			case 'check':
				t._checkfn(node);
				break;
			case 'iconSelect':
				t.selectNode(node);
				t.trigger('nodeclick',t,node);
				break;
			case 'nodeSelect':
				t.selectNode(node);
				t.trigger('nodeclick',t,node);
				t.trigger('cellclick',t,node);
				break;
			case 'nodeSelectDiv':
				t.selectNode(node);
				t.trigger('nodeclick',t,node);
				break;
			case 'columnSelectDiv':
				t.selectNode(node);
				if($(e.target).hasClass('mj-tree-c-col'))
					var tar = $(e.target);
				else
					var tar = $(e.target).parents('.mj-tree-c-col:first');
				if(tar.length>0){
					var ci = tar.attr('name').split('c-col-');
					ci = ci.length>1?parseInt(ci[1]):0;
					t.trigger('cellclick',t,node,tar,ci);
				}
				break;
			case 'toggle':
				if(node.expanded)
					t.collapse(node);
				else
					t.expand(node);
				t.trigger('togglenode',t,node);
				break;
		}
	},
	//private
	_dblClick : function(e){
		var t = e.data.scope;
		var event = t._getEventType(e);
		var node = t.getNodeById(t._getNodeIdFromEvent(e));
		if(event)
			t.trigger('nodedblclick',t,node);
		switch(event){
			case 'iconClick':
				t.selectNode(node);
				if(t.dblClickToggle){
					if(node.expanded)
						t.collapse(node);
					else
						t.expand(node);
					t.trigger('togglenode',t,node);
				}
				break;
			case 'nodeClick':
				if(t.dblClickToggle){
					if(node.expanded)
						t.collapse(node);
					else
						t.expand(node);
					t.trigger('togglenode',t,node);
				}
				break;
			case 'nodeSelectDiv':
				t.selectNode(node);
				if(t.dblClickToggle){
					if(node.expanded)
						t.collapse(node);
					else
						t.expand(node);
					t.trigger('togglenode',t,node);
				}
				break;
			case 'columnSelectDiv':
				t.selectNode(node);
				if(t.dblClickToggle){
					if($(e.target).hasClass('mj-tree-c-col'))
						var tar = $(e.target);
					else
						var tar = $(e.target).parents('.mj-tree-c-col:first');
					if(node.expanded)
						t.collapse(node);
					else
						t.expand(node);
					if(tar.length>0){
						var ci = tar.attr('name').split('c-col-');
						ci = ci.length>1?parseInt(ci[1]):0;
						t.trigger('celldblclick',t,node,tar,ci);
					}
				}
				break;
		}
	},
	//private
	_context : function(e){
		var t = e.data.scope;
		var event = t._getEventType(e);
		var node = t.getNodeById(t._getNodeIdFromEvent(e));
		if(event)
			t.trigger('contextmenu', t, node, e);
			// mj.log('contenxt - '+event);
	},
	//private
	_onOver : function(node){
		if(node){
			this.lastOverNode = node;
			node.el.addClass("mj-tree-node-over");
		}
	},
	//private
	_onOverFn : function(e){
		var t = e.data.scope;
		var event = t._getEventType(e);
		switch(event){
			case 'mouseover':
				if(t.lastOverNode){
					t._onOut(t.lastOverNode);
					delete t.lastOverNode;
				}
				t._onOver(t.getNodeById(t._getNodeIdFromEvent(e)));
				break;
		}
	},
	//private
	_onOut : function(node){
		if(node)
			node.el.removeClass("mj-tree-node-over");
	},
	//private
	_onOutFn : function(e){
		var t = e.data.scope;
		var event = t._getEventType(e);
		switch(event){
			case 'mouseout':
				if(t.lastOverNode){
					t._onOut(t.lastOverNode);
					delete t.lastOverNode;
				}
				t._onOut(t.getNodeById(t._getNodeIdFromEvent(e)));
				break;
		}
	},
	//private
	_getNodeIdFromEvent : function(e){
		return (e.target.tagName == 'DIV' && $(e.target).hasClass('mj-tree-node-el')) ? e.target.id : $(e.target).parents('div.mj-tree-node-el:first').length>0?$(e.target).parents('div.mj-tree-node-el:first')[0].id:false;
	},
	//private
	_getEventType : function(e){
		e.preventDefault();
		if(e.target.className.indexOf('ce-icon')>-1 && e.type == 'mousedown')
			return 'toggle';
		if((e.target.className.indexOf('node-icon')>-1 || e.target.className.indexOf('tree-icon')>-1) && e.type == 'dblclick')
			return 'iconClick';
		if((e.target.className.indexOf('node-icon')>-1 || e.target.className.indexOf('tree-icon')>-1) && e.type == 'mousedown')
			return 'iconSelect';
		if(e.target.id.indexOf('-text')>-1 && e.type == 'dblclick')
			return 'nodeClick';
		if(e.target.id.indexOf('-text')>-1 && e.type == 'mousedown')
			return 'nodeSelect';
		if(this.cm){
			if(($(e.target).hasClass('mj-tree-node-el') || e.target.className.indexOf('-c-col')>-1 || e.target.className.indexOf('-c-text')>-1) && (e.type == 'dblclick' || e.type == 'mousedown'))
				return 'columnSelectDiv';
			if($(e.target).parents('div.mj-tree-node-el:first').length>0 && (e.type == 'dblclick' || e.type == 'mousedown'))
				return 'columnSelectDiv';
		}else{
			if(e.target.className.indexOf('mj-checkbox')>-1 && e.type == 'mousedown')
				return 'check';
			if(e.target.tagName == 'DIV' && $(e.target).hasClass('mj-tree-node-el') && (e.type == 'dblclick' || e.type == 'mousedown'))
				return 'nodeSelectDiv';
		}
		if(e.type == 'mouseover' || e.type == 'mouseout' || e.type == 'contextmenu')
			return e.type;
		return false;
	},
	getData : function(items,clear){
		if(clear)
			this._jsonData = {};
		if(!items)
			items = this.root.data;
		for(var i=0,len=items.length;i<len;i++){
			this._jsonData[items[i].id] = {id:items[i].id,parentId:parseInt(items[i].parent.id)||0,sira:i};
			if(items[i].data)
			this.getData(items[i].data,false);
		}
	}
};
mj.extend(mj.tree, mj.component);
mj.windowManager = function(config){
	mj.windowManager.superclass.constructor.call(this, config);
	//this.init();
};
mj.windowManager.prototype = {
	componentClass : 'mj.windowManager',
	modalIndex : mj.glb.modalIndex,
	activeIndex : false,
	activeWin : false,
	init : function(){
		this.windows = [];
		this.w = $(this.windows);
		mj.windowManager.superclass.init.call(this);
	},
	add : function(win){
		win.manager = this;
		win.managerId = this.windows.push(win);
		if(win.parentWin)
			win.parentWin.add(win);
		win.on('show', this.onWindowShow, this);
		win.on('hide', this.onWindowHide, this);
		win.on('close', this.onWindowClose, this);
		win.on('init', this.onWindowInit, this);
	},
	onWindowShow : function(win){
		this.bringToFront(win);
	},
	onWindowHide : function(win){
		if(win.mask)
			win.mask.hide();
		this.activeWin = false;
		this.activeIndex = win.lastIndex;
		win._el.css('z-index', win._zBackup);
	},
	onWindowClose : function(win){
		if(win.mask)
			win.mask.destroy();
		this.activeWin = false;
		this.activeIndex = win.lastIndex;
		this.windows.splice(win.managerId,1);
	},
	onWindowInit : function(win){
		if(win.modal){
			win.mask = new mj.mask({zIndex:this.modalIndex});
			win.addRelated(win.mask);
		}
	},
	bringToFront : function(win){
		if(this.activeWin != win){
			win.lastIndex = this.activeIndex;
			var i = (this.activeIndex ? this.activeIndex : this.modalIndex)+2;
			this.activeIndex = i;
			this.activeWin = win;
			if(win.mask)
				win.mask.show(i-1);
			win._zBackup = win._el.css('z-index');
			win._el.css('z-index', i);
		}
		win.trigger('activate', win);
		this.trigger('activate', win);
	}
};
mj.extend(mj.windowManager, mj.component);
mj.window = function(config){
	mj.applyIf(config, {parent:config.parent||mj.bd});
	if(config.wM){
		config.wM.add(this);
	}else{
		if(!window.windowManager){
			window.windowManager = new mj.windowManager();
		}
		window.windowManager.add(this);
	}
	mj.window.superclass.constructor.call(this,config);
};
mj.window.prototype = {
	componentClass : 'mj.window',
	width : 600,
	height : 500,
	resizable : true,
	drag:true,
	destroyOnClose : false,
	minimizable : false,
	maximizable : false ,
	closable : true,
	opacity : 1,
	init : function(){
		var t = this, n = mj.NE, el = t.el = n(t.renderTo,{cls:'mj-win'+(t.cls ? ' '+t.cls : ''),style:'width:'+t.width+'px;height:'+t.height+'px;'}), _el = t._el = t.destroyEl = $(el);
		t.updating = true;
		t.width = _el.width();
		t.height = _el.height();
		t._cnt = _el;
		t.els ={
			tl : $(n(el, {cls:'mj-win-tl'})),
			tc : $(n(el, {cls:'mj-win-tc mj-unselectable', unselectable:'on'})),
			tr : $(n(el, {cls:'mj-win-tr'})),
			lc : $(n(el, {cls:'mj-win-lc'})),
			rc : $(n(el, {cls:'mj-win-rc'})),
			bl : $(n(el, {cls:'mj-win-bl'})),
			bc : $(n(el, {cls:'mj-win-bc'})),
			br : $(n(el, {cls:'mj-win-br'})),
			cs : $(n(el, {cls:'mj-win-cs'})),
			cn : $(n(el, {cls:'mj-win-cn'})),
			cc : $(n(el, {cls:'mj-win-cc mj-resize-handle', style:'opacity:'+t.opacity+';-moz-opacity:'+t.opacity+';filter:alpha(opacity='+(t.opacity*100)+');'}))
		};
		t.els.tcDrag = $(n(t.els.tc, {cls:'mj-win-drag'}));
		t.els.cc.bind('mousedown', function(){
			t.manager.bringToFront.call(t.manager, t);
		});
		t.els.tcDrag.bind('mousedown', function(){
			t.manager.bringToFront.call(t.manager, t);
		});		
		t.title = mj.translate(t.title);
		t.titleEl=n(t.els.tcDrag, {tag:'span', html:t.title});
		t.body = t.els.cc;
		t.body.win=t;
		t.getBody = function(){
			return t.body;
		};
		if(t.minimizable){
			var cm = t.els.minimize = $(n(t.els.tc, {cls:'mj-win-btn mj-win-minimize'}));
			cm.hover(function(){
				cm.addClass('mj-win-minimize-hover');
			},function(){
				cm.removeClass('mj-win-minimize-hover');
			});
			var cmfn = t.minimize;
			cm.click(function(){
				cmfn.call(t);
			});
			if(!t.maximizable)
				cm.css('right','14px');
		}
		if(t.maximizable){
			var cma = t.els.maximize = $(n(t.els.tc, {cls:'mj-win-btn mj-win-maximize'}));
			cma.hover(function(){
				if(t.maximized)
					cma.addClass('mj-win-restore-hover');
				else
					cma.addClass('mj-win-maximize-hover');
			},function(){
				cma.removeClass('mj-win-restore-hover');
				cma.removeClass('mj-win-maximize-hover');
			});
			var cmafn = t.maximize;
			cma.click(function(){
				cmafn.call(t);
			});
			t.els.tc.dblclick(function(){
				cmafn.call(t);
			});
		}
		if(t.closable){
			var c = t.els.close = $(n(t.els.tc, {cls:'mj-win-btn mj-win-close'}));
			c.hover(function(){
				c.addClass('mj-win-close-hover');
			},function(){
				c.removeClass('mj-win-close-hover');
			});
			var cfn = t.close;
			c.click(function(){
				cfn.call(t);
			});
		}

		if(t.drag) {
			t.dragHandle = new mj.drag({el:el,dragEl:t.els.tcDrag,parent:t.parent});
			t.dragHandle.on('beforedrag',function(){
				if(this.maximized) return false;
			},t);
		}	
		if(t.resizable){
			t.resizer = new mj.resizer({
				el : el,
				minWidth : t.minWidth||t.width,
				maxWidth : t.maxWidth,
				minHeight : t.minHeight||t.height,
				maxHeight : t.maxHeight
			});
		}
		if(t.buttons){
			t.buttonsConfig = t.buttons;
			t.buttons = null;
			if(t.buttonsConfig)
				$(t.buttonsConfig).each(function(){
					t.addButton.call(t,this);
				});
		}
		if(t.tbar){
			mj.apply(t.tbar,{renderTo:t.els.cn});
			t.tbar = new mj.menu(t.tbar);
		}
		t.updating = null;
		t._layout();
		var b = $(document.body), l = typeof t.left != 'undefined'?t.left:Math.floor((b.width()-t.width)/2), top = typeof t.top != 'undefined'?t.top:Math.floor(($(document).height()-t.height)/2);
		t._el.css('left', l>0 ? l : 0);
		t._el.css('top', top>0 ? top : 0);
		t._el.resize(function(){
			var w = t.width = _el.width(), h = t.height = _el.height();
			t.trigger('resize', t, w, h);
		});
		t._el.bind('resize',function(){
			t.width = _el.width();
			t.height = _el.height();
			t._layout();
			t.trigger('afterresize', t, t.width, t.height);
		});
		if(t.autoLoad){
			window.tmp = t.body;
			t.autoLoad.url += '?h=tmp';
			mj.load(t.body,t.autoLoad);
			t.loaded = true;
		}
		t.relatedItems = [];
		t.on('hide', t._onHide, t);
		t.on('beforeclose', t._onBeforeClose, t);
		mj.bindResize(t.el,t.doFit, t);			
		//e.cc.kkresizewidth(w-2, true);
		mj.window.superclass.init.call(t);
	},
	_onHide : function(){
		if(this.subWindows){
			var s = $(this.subWindows);
			return s.eachR(function(){
				return this.hide();
			});
		}
		return true;
	},
	_onBeforeClose : function(){
		if(this.subWindows){
			var s = $(this.subWindows);
			return s.eachR(function(){
				return this.close();
			});
		}
		return true;
	},
	_layout : function(){
		if(!this.updating){
			var t=this,e=t.els, w = t.width-12, h = t.height-29;
			t._cnt.width(t.width);
			t._cnt.height(t.height);
			e.tc.width(w);
			e.bc.width(w);
			e.lc.height(h);
			e.rc.height(h);
			e.cc.width(w-2);
			e.cc.kkresizewidth(w-2, true);
			e.cs.width(w+2);
			e.cn.width(w-2);
			if(t.buttons){
				e.cs.height(26);
				h = h - 29;
			}
			if(t.tbar){
				e.cn.height(25);
				e.cc.css('top', $.browser.msie ? 48 : 49);
				h = h - 26;
			}
			e.cc.kkresizeheight(h+($.browser.msie ? 1 : 0));
			t.els.tcDrag.width(w- 15);
		}
	},
	show : function(){
		var t=this;
		t.trigger('show', this);
		t.trigger('activate', this);
		t._el.show();
		t.els.cc.trigger('kkresize');
		t.trigger('aftershow', this);
		t.minimized = false;	
	},
	hide : function(){
		if(this.trigger('hide', this))
			this._el.hide();
	},
	minimize : function(){
		if(this.trigger('minimize', this)){
			this._el.hide();
			this.minimized = true;	
		}
	},	
	close : function(){
		if(this.trigger('beforeclose')===false)
			return false;
		if(this.destroyOnClose){
			if(this.trigger('close', this)!==false)
				this.destroy();
			return false;
		}else
			return this.hide();
	},
	resize : function(w,h){
		this.resizing = true;
		this.onWidth(w);
		this.onHeight(h);
	},
	onWidth : function(w){
		this._el.width(w);
		this._layout();
		if(!this.resizing)
			this.trigger('resize', this, w, this._el.height());
		this.resizing = null;
	},
	onHeight : function(h){
		this._el.height(h);
		this._layout();
	},
	doFit : function(){
		if(this.maximized){
			var w,h;
			w = $(this.parent).width();
			h = $(this.parent).height();	
			this.width = parseInt(w);
			this.height = parseInt(h);		
			this.onWidth(w);
			this.onHeight(h);			
		}
	},
	maximize : function(){
		var w,h,t,l;
		if(!this.maximized){
			this.oldPosition = {
				top : this._el.css('top'),
				left : this._el.css('left'),
				width : this._el.width(),
				height : this._el.height()
			};
			w = $(this.parent).width();
			h = $(this.parent).height();
			t = ($(this.parent).offset()).top+'px';
			//if($.browser.msie)
				t='0px';
			l = '0px';
			this.maximized = true ;
			this.els.maximize.addClass('mj-restore-btn');
		}else{
			w = this.oldPosition.width;
			h = this.oldPosition.height;
			t = this.oldPosition.top;
			l = this.oldPosition.left;			
			this.maximized = false ;
			this.oldPosition = null;
			this.els.maximize.removeClass('mj-restore-btn');
		}
		this._el.css('top',t);
		this._el.css('left',l);
		this.width = parseInt(w);
		this.height = parseInt(h);
		this.onWidth(w);
		this.onHeight(h);
	},		
	addButton : function(config){
		var t=this;
		if(!t.buttons)
			t.buttons = [];
		var b = config;
		if(!b.componentClass){
			mj.apply(b, {renderTo:mj.NE(t.els.cs)});
			b = new mj.button(b);
		}
		b.window = t;
		t.buttons.push(b);
		t._layout();
	},
	add : function(win){
		var t = this;
		if(!t.subWindows)
			t.subWindows = [];
		win.on('close', function(){
			t.subWindows.splice(win._subIndex, 1);
		});
		win._subIndex = t.subWindows.push(win);
	},
	setTitle : function(text){
		if(this.titleEl){
			this.title = mj.translate(text);
			this.titleEl.innerHTML = this.title;
		}
	}
};
mj.extend(mj.window, mj.component);
mj.message = function(config){
	if(typeof config==='string')
		config = {msg:config};
	config.msg=mj.translate(config.msg);
	config.destroyOnClose = config.destroyOnClose || true;
	var i = window.windowManager ? window.windowManager.activeIndex+1 : 1000, def = mj.message.defaults;
	var _bT = {
		'OK' : mj.lng.titles.buttons.ok,
		'CANCEL' : mj.lng.titles.buttons.cancel,
		'YES' : mj.lng.titles.buttons.yes,
		'NO' :  mj.lng.titles.buttons.no
	};
	def.buttonTitles = def.buttonTitles ? mj.apply(def.buttonTitles, _bT) : _bT;
	var cnt = config.renderTo = config.renderTo ? config.renderTo : mj.NE();
	mj.applyIf(config, def);
	var btnCb = function(btn, h){
		var fn = config.cb;
		if(typeof fn === 'function')
			fn.call(config.scope, btn, btn.handlerId);
		else{
			btn.window.close();
		}
	};
	if(config.buttons){
		var btns=[],cnfb = config.buttons;
		for(var i =0 , l = cnfb.length; i<l ; i++){
			if(typeof cnfb[i] === 'string')
				btns.push({title: def.buttonTitles[cnfb[i]], handler: btnCb, handlerId : cnfb[i]});
			else
				btns.push(cnfb[i]);
		}
	}
	config.buttons = btns;
	var win = mj.message.activeMessageWin = new mj.window(config);
	win.on('close', function(){
		$(cnt).remove();
		mj.message.activeMessageWin = false;
	});
	mj.NE(win.body, {html:config.msg, cls:'mj-message-text'});
	win.show();
};
mj.message.defaults = {
	cls : 'mj-message-window',
	modal : false,
	width : 300,
	height : 150,
	title : 'Bilgi',
	buttons : [
		'OK'
	],
	buttonTitles : {}, //silme
	cb:function(el,btn){
		el.window.close();
	}
};
// gradientcanvas = document.getElementById('gradient');
// if(gradientcanvas.getContext){
	// var g = gradientcanvas.getContext('2d');
	// grad = g.createLinearGradient(0, 0, 200, 15);	
	// grad.addColorStop(0, '#036');
	// grad.addColorStop(1, '#ACF');
	// g.fillStyle = grad;
	// g.fillRect(0, 0, 300, 17);
// }

mj.plotter = function(config){
	mj.plotter.superclass.constructor.call(this, config);
};
mj.plotter.prototype = {
	componentClass : 'mj.plotter',
	version : '1.0',
	width : false,
	height : false,
	mask : true,
	maskOpacity : .3,
	legendWindowOpacity : .3,
	legendWindowWidth : 200,
	legendWindowHeight : 250,
	canvas : false,
	cnt : false,
	ctx : false,
	series : false,
	opt : false,
	style : '',
	fontMap : true,
	tickOrientation : {x:'h', y:'h'},
	border : true,
	collapsible : false,
	footHeight : 80,
	leftWidth : 60,
	marginSize : 0,
	infoBar : false,
	infoHeight : 30,
	titleMeasure : 20,
	fontSize : 10,
	titleSize : 10,
	tickSize : 10,
	overlay : true,
	autoScale : {x:0,y:0.02},//auto scale value
	tickScale : 3,
	xTickScale : false,
	yTickScale : false,
	backgroundColor : '#fff',
	ticksBackgroundColor : '#fff',
	titleBackgroundColor : '#fff',
	showXAxisTicks : true,
	showXAxisTitles : true,
	showYAxisTicks : true,
	showYAxisTitles : true,
	xTickCount : false,
	yTickCount : false,
	zoom : true,
	legend : false,
	legendLabel : false,
	legendRefresh : true,
	legendCreated : false,
	drawed : false,
	legends : true,
	maxTitle : 15,
	resizable : false,
	onlyPositiveZoom : false,
	d : false,
	tickFormatDefault : {
		x : {format:function(val){return val.toString();}},
		y : {format:function(val){return val.toString();}}
	},
	_colors : ['rgb(120,90,59)', 'rgb(53,115,53)', 'rgb(178,87,56)', 'rgb(203,143,71)', 'rgb(55,106,155)', 'rgb(205,197,51)', 'rgb(209,130,139)', 'rgb(159,153,57)', 'rgb(206,173,136)', 'rgb(191,132,72)', 'rgb(151,135,169)', 'rgb(140,48,51)', 'rgb(59,144,187)', 'rgb(197,190,104)', 'rgb(109,136,79)', 'rgb(144,100,144)', 'rgb(181,94,94)', 'rgb(59,144,144)', 'rgb(204,136,92)', 'rgb(139,167,55)', 'rgb(205,171,66)', 'rgb(150,184,211)'],
	_ticks: new Array(29030400000, 7257600000, 2419200000, 604800000, 259200000, 86400000, 21600000, 14400000, 3600000, 1000000, 500000, 250000, 100000, 50000, 25000, 10000, 5000, 2500, 1000, 500, 250, 100, 50, 25, 10, 5, 2.5, 1, .5, .25, .1, .05, .025, .01, .005, .0025, .001, .0005, .00025, .0001, .00005, .000025, .00001, .000005, .0000025, .000001, .0000005, .00000025, .0000001, .00000005, .000000025, .00000001, .000000005, .0000000025, .000000001),
	_gTicks : new Array(2000,1000,900,800,700,600,500,400,300,200,100,90,80,70,60,50,40,30,20,10),
	_dateTicks : new Array(31556926, 2629743, 604800, 86400, 43200, 21600, 3600, 1800, 600, 300, 60, 30, 10, 5, 1),
	_subticks: new Array(7257600000, 2419200000, 604800000, 86400000, 86400000, 21600000, 3600000, 3600000, 600000, 250000, 100000, 50000, 25000, 10000, 5000, 2500, 1000, 500, 250, 100, 50, 25, 10, 5, 2, 1, .5, .25, .1, .05, .025, .01, .005, .0025, .001, .0005, .00025, .0001, .00005, .000025, .00001, .000005, .0000025, .000001, .0000005, .00000025, .0000001, .00000005, .000000025, .00000001, .000000005, .0000000025, .000000001, .0000000005, .00000000025),
	_tickRound: new Array(undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, undefined, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 1, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5, 6, 5, 6, 7, 6, 7, 8, 7, 8, 9, 8, 9, 10, 9, 10, 11),
	//_months: new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'),
	//_days: new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'),
	init : function(){
		var t = this;
		t.wins = [];
		t.canvas = {};
		t.ctx = {};
		t.cnt = {};
		t.series = {};
		t.axis = {x:{},y:{}};
		var nullObj = {main:null,overlay:null};
		mj.apply(t.canvas,nullObj); mj.apply(t.ctx,nullObj); mj.apply(t.cnt,nullObj);
		t.xTickScale = t.xTickScale?t.xTickScale:t.tickScale;
		t.yTickScale = t.yTickScale?t.yTickScale:t.tickScale;
		t.clearSeries();
		/*t.cnt.main = mj.NE(t.renderTo,{
			unselectable:'on',
			cls:"mj-plotter mj-plotter-container mj-unselectable",
			style:'position:relative;height:'+t.height+';width:'+t.width+';'+t.style,
			html:'<canvas width="' + t.width + '" height="' + t.height + '"></canvas>'
		});*/
		t.width = parseInt(t.width||$(t.renderTo).css('width'));
		t.height = parseInt(t.height||$(t.renderTo).css('height'));
		t.panel = new mj.panel({
			renderTo : mj.NE(t.renderTo,{style:'margin:'+t.marginSize+'px;'}),
			title : t.titles&&t.titles.main?'mjPlotter v0.1':'',
			border : t.border,
			collapsible : t.collapsible,
			width :  t.width,
			height : t.height
		});
		t.cnt.main = t.panel.getBody();
		// if(t.zoom){
			// t.cnt.zoomSelector = mj.NE(t.cnt.main,{cls:'mj-plotter-selector', style:'display:none;top:0px;left:0px;width:10px;height:10px;background:black;position:absolute;'});
			// t.addRelated(t.cnt.zoomSelector);
		// }
		t.cnt.axis = {x:{},y:{}};
		t.canvas.axis = {x:{},y:{}};
		t.ctx.axis = {x:{},y:{}};
		
		t.m = this.initialMeasure(t.width,t.height);
		t.cnt.center = mj.NE(t.cnt.main,{cls:'mj-plotter-center',style:'height:'+t.m.h+'px;width:'+t.m.tw+'px;'});
		if(t.showYAxisTicks||t.showYAxisTitles){
			t.cnt.axis.y.main = mj.NE(t.cnt.center,{cls:'mj-plotter-yaxis',style:'height:'+t.m.h+'px;width:'+t.m.lw+'px;'});
			if(t.showYAxisTitles)
				t.cnt.axis.y.title = mj.NE(t.cnt.axis.y.main,{cls:'mj-plotter-yaxis-title',style:'height:'+t.m.h+'px;width:'+t.m.tm+'px;',html:'<canvas width="' + t.m.tm + '" height="' + t.m.h + '" style="width:'+t.m.tm+'px;height:'+t.m.h+'px;"></canvas>'});
			if(t.showYAxisTicks)
				t.cnt.axis.y.ticks = mj.NE(t.cnt.axis.y.main,{cls:'mj-plotter-yaxis-ticks',style:'height:'+t.m.h+'px;width:'+(t.m.lw-(t.showYAxisTitles?t.m.tm:0))+'px;',html:'<canvas width="' + (t.m.lw-(t.showYAxisTitles?t.m.tm:0)) + '" height="' + t.m.h + '" style="width:'+(t.m.lw-(t.showYAxisTitles?t.m.tm:0))+'px;height:'+t.m.h+'px;"></canvas>'});
		}
		/*if(t.overlay){
			//var ovfs = $(t.cnt.main).offset();
			//t.cnt.overlay = mj.NE(t.cnt.main,{cls:'mj-plotter-overlay mj-invisible',style:'width:'+t.m.tw+'px;height:'+t.m.th+'px;position:absolute;left:'+ovfs.left+'px;top:'+ovfs.top+'px;'});
			t.cnt.overlay = mj.NE(t.cnt.main,{cls:'mj-plotter-overlay mj-invisible',style:'width:'+t.m.tw+'px;height:'+t.m.th+'px;position:absolute;left:0px;top:0px;'});
			//t.addRelated(t.cnt.overlay);
		}*/
		t.cnt.canvasMain = mj.NE(t.cnt.center,{
			cls:'mj-plotter-canvas',
			style:'height:'+t.m.h+'px;width:'+t.m.w+'px;',
			html:'<canvas width="' + t.m.w + '" height="' + t.m.h + '" style="width:'+t.m.w+'px;height:'+t.m.h+'px;"></canvas>'
		});
		
		t.cnt.footer = mj.NE(t.cnt.main,{cls:'mj-plotter-footer',style:'height:'+t.m.fh+'px;width:'+t.m.tw+'px;display:'+(t.m.fh>0?'block':'none')+';'});
		if(t.showXAxisTicks||t.showXAxisTitles){
			t.cnt.xaxisContainer = mj.NE(t.cnt.footer,{cls:'mj-plotter-xaxis-container',style:'height:'+t.m.fH+'px;width:'+t.m.tw+'px;'});
			t.cnt.bs = mj.NE(t.cnt.xaxisContainer,{cls:'left-bottom-space',style:'height:'+t.m.fH+'px;width:'+t.m.lw+'px;'});
			t.cnt.axis.x.main = mj.NE(t.cnt.xaxisContainer,{cls:'mj-plotter-xaxis',style:'height:'+t.m.fH+'px;width:'+t.m.w+'px;'});
			if(t.showXAxisTicks)
				t.cnt.axis.x.ticks = mj.NE(t.cnt.axis.x.main,{cls:'mj-plotter-xaxis-ticks',style:'height:'+(t.m.fH-(t.showXAxisTitles?t.m.tm:0))+'px;width:'+t.m.w+'px;',html:'<canvas height="' + (t.m.fH-(t.showXAxisTitles?t.m.tm:0)) + '" width="' + t.m.w + '" style="width:'+t.m.w+'px;height:'+(t.m.fH-(t.showXAxisTitles?t.m.tm:0))+'px;"></canvas>'});
			if(t.showXAxisTitles)
				t.cnt.axis.x.title = mj.NE(t.cnt.axis.x.main,{cls:'mj-plotter-xaxis-title',style:'line-height:'+t.m.tm+'px;height:'+t.m.tm+'px;width:'+t.m.w+'px;',html:'<canvas height="' + t.m.tm + '" width="' + t.m.w + '" style="width:'+t.m.w+'px;height:'+t.m.tm+'px;"></canvas>'});
		}
		if(t.infoBar)
			t.cnt.infoBar = mj.NE(t.cnt.footer,{cls:'mj-plotter-infobar',style:'height:'+t.m.ih+'px;width:'+t.m.tw+'px;'});		
		
		if(t.mask)
			t.maskEl = $(t.panel.getBody());
		
		t.canvas.main = $('canvas',t.cnt.canvasMain).get(0);
		if(t.showYAxisTitles)
			t.canvas.axis.y.title = $('canvas',t.cnt.axis.y.title).get(0);
		if(t.showYAxisTicks)
			t.canvas.axis.y.ticks = $('canvas',t.cnt.axis.y.ticks).get(0);
		if(t.showXAxisTitles)
			t.canvas.axis.x.title = $('canvas',t.cnt.axis.x.title).get(0);
		if(t.showXAxisTicks)
			t.canvas.axis.x.ticks = $('canvas',t.cnt.axis.x.ticks).get(0);
		if ($.browser.msie){
			t.canvas.main = window.G_vmlCanvasManager.initElement(t.canvas.main);
			if(t.showYAxisTitles)
				t.canvas.axis.y.title = window.G_vmlCanvasManager.initElement(t.canvas.axis.y.title);
			if(t.showYAxisTicks)
				t.canvas.axis.y.ticks = window.G_vmlCanvasManager.initElement(t.canvas.axis.y.ticks);
			if(t.showXAxisTitles)
				t.canvas.axis.x.title = window.G_vmlCanvasManager.initElement(t.canvas.axis.x.title);
			if(t.showXAxisTicks)
				t.canvas.axis.x.ticks = window.G_vmlCanvasManager.initElement(t.canvas.axis.x.ticks);
		}
		if(t.zoom){
			t.cnt.zoomSelector = mj.NE(t.cnt.canvasMain,{cls:'mj-plotter-selector', style:'display:none;top:0px;left:0px;width:10px;height:10px;background:black;position:absolute;'});
			t.addRelated(t.cnt.zoomSelector);
		}
		if(t.overlay){
			var ofs = {left:t.cnt.canvasMain.offsetLeft,top:t.cnt.canvasMain.offsetTop};
			mj.NE(t.cnt.canvasMain,{tag:'canvas',width:t.m.w,height:t.m.h,style:'position:absolute;left:'+ofs.left+'px;top:'+ofs.top+'px;'});
			t.canvas.overlay = $('canvas',t.cnt.canvasMain).get(1);
			if ($.browser.msie)
				t.canvas.overlay = window.G_vmlCanvasManager.initElement(t.canvas.overlay);
			t.cnt.overlay = mj.NE(t.cnt.canvasMain,{cls:'mj-plotter-overlay mj-invisible',style:'width:'+t.m.w+'px;height:'+t.m.h+'px;position:absolute;left:'+ofs.left+'px;top:'+ofs.top+'px;'});
		}		
        if (t.canvas.main.getContext)
			t.ctx.main = t.canvas.main.getContext("2d");

		if (t.showYAxisTitles&&t.canvas.axis.y.title.getContext)
			t.ctx.axis.y.title = t.canvas.axis.y.title.getContext("2d");

		if (t.showYAxisTicks&&t.canvas.axis.y.ticks.getContext)
			t.ctx.axis.y.ticks = t.canvas.axis.y.ticks.getContext("2d");

		if (t.showXAxisTitles&&t.canvas.axis.x.title.getContext)
			t.ctx.axis.x.title = t.canvas.axis.x.title.getContext("2d");

		if (t.showXAxisTicks&&t.canvas.axis.x.ticks.getContext)
			t.ctx.axis.x.ticks = t.canvas.axis.x.ticks.getContext("2d");

		if (t.overlay&&t.canvas.overlay.getContext)
			t.ctx.overlay = t.canvas.overlay.getContext("2d");
		
		t.axis = {x:{min:null,max:null,dMin:null,dMax:1,cnt:t.cnt.axis.x,ctx:t.ctx.axis.x,asv:t.autoScale.x,tickCount:t.xTickCount},y:{min:null,max:null,dMin:null,dMax:1,cnt:t.cnt.axis.y,ctx:t.ctx.axis.y,asv:t.autoScale.y,tickCount:t.yTickCount}};
		t.defaultOp = true;
		if(t.tickFormat&&t.tickFormat.x)
			mj.apply(t.axis.x,t.tickFormat.x);
		else
			mj.apply(t.axis.x,t.tickFormatDefault.x);
		if(t.tickFormat&&t.tickFormat.y)
			mj.apply(t.axis.y,t.tickFormat.y);
		else
			mj.apply(t.axis.y,t.tickFormatDefault.y);
		if($.browser.msie)
			t.fontMap = false;
		if(t.fontMap){
			t.setLetters();
			if(t.d)
				t.setStringImages();
		}else{
			if(t.d)
				t.setLetters();
			t.setStringImages();
		}
		t.prepCanvasAll();
		if(t.overlay)
			t.addEvents();
		if(t.titles)
			t.setTitles(t.titles);
		if(t.legends)
			t.createLegendWindow();
		if(t.mask&&t.store){
			t.store.on('beforeload',function(){
				if(t.overlay){
					//var ovfs = $(t.cnt.main).offset();
					// var tco = t.maskEl[0].style;
					// tco.height = t.m.th+'px';
					// tco.width = t.m.tw+'px';
					// tco.left = ofs.left+'px';
					// tco.top = ofs.top+'px';
					t.maskEl.css('opacity',t.maskOpacity);
					t.onDraw = true;
					if(t.legend)
						t.legend.hide();
				}
			});
		}
		if(t.store)
			t.store.on('load',function(){
				t.trigger('load',t);
			});
		if(t._init)
			t._init();
		if(t.resizable){
			mj.bindResize(t.panel.renderTo, t.doResize, t);
			t.doResize();
		}
	},
	initialMeasure : function(w,h){
		var t = this;
		var fh = t.footHeight, ih = t.infoHeight, tm = t.titleMeasure, lw = t.leftWidth;
		if(!t.infoBar&&!t.showXAxisTitles&&!t.showXAxisTicks)
			fh = 0;
		else{
			if(!t.infoBar)
				fh -= ih;
			if(t.infoBar&&!t.showXAxisTitles&&!t.showXAxisTicks)
				fh = ih;
			else if(!t.showXAxisTitles)
				fh -= tm;
			else if(t.showXAxisTitles&&!t.showXAxisTicks)
				fh = t.infoBar?ih+tm:tm;
			t.fH = fh-(t.infoBar?ih:0);
		}
		
		if(!t.showYAxisTitles&&!t.showYAxisTicks)
			lw = 0;
		else if(!t.showYAxisTitles&&t.showYAxisTicks)
			lw -= tm;
		else if(t.showYAxisTitles&&!t.showYAxisTicks)
			lw = tm;
		return {fh:fh,fH:t.fH,lw:lw,th:h,tw:w,tm:tm,ih:t.infoHeight,w:(w-lw),h:(h-fh),ph:t.panel.header?$(t.panel.header).height():0};
	},
	doResize : function(){
		var t=this,w = parseInt(t.renderTo[0].style.width)||t.width, h = parseInt(t.renderTo[0].style.height)||t.height,hh=t.panel.header?$(t.panel.header).height():0;
		h+=hh;
		t.panel.renderTo[0].style.width = w+'px';
		t.panel.width = w;
		t.panel.renderTo[0].style.height = h+'px';
		t.panel.height = h-hh;
		t.panel.doPanel();
		t.m = t.initialMeasure(w,h-hh);
		t.cnt.center.style.height = t.m.h+'px';
		t.cnt.center.style.width = t.m.tw+'px';
		if(t.showYAxisTicks||t.showYAxisTitles){
			t.cnt.axis.y.main.style.height = t.m.h+'px';
			t.cnt.axis.y.main.style.width = t.m.lw+'px';
			if(t.showYAxisTitles){
				t.cnt.axis.y.title.style.height = t.m.h+'px';
				t.cnt.axis.y.title.style.width = t.m.tm+'px';
				t.resize(t.ctx.axis.y.title,t.m.tm,t.m.h);
			}
			if(t.showYAxisTicks){
				t.cnt.axis.y.ticks.style.height = t.m.h+'px';
				t.cnt.axis.y.ticks.style.width = (t.m.lw-(t.showYAxisTitles?t.m.tm:0))+'px';
				t.resize(t.ctx.axis.y.ticks,(t.m.lw-(t.showYAxisTitles?t.m.tm:0)),t.m.h);
			}
		}
		
		t.cnt.canvasMain.style.height = t.m.h+'px';
		t.cnt.canvasMain.style.width = t.m.w+'px';
		
		if(t.overlay){
			//var ovfs = $(t.cnt.main).offset();
			var ofs = {left:t.cnt.canvasMain.offsetLeft,top:t.cnt.canvasMain.offsetTop};
			var tco = t.cnt.overlay.style;
			tco.height = t.m.h+'px';
			tco.width = t.m.w+'px';
			tco.left = ofs.left+'px';
			tco.top = ofs.top+'px';
			var ocs = t.canvas.overlay.style;
			ocs.left = ofs.left+'px';
			ocs.top = ofs.top+'px';
			t.resize(t.ctx.overlay,t.m.w,t.m.h);
			//tco.zIndex = 1000;
		}
		
		t.resize(t.ctx.main,t.m.w,t.m.h);
		t.cnt.footer.style.height = t.m.fh+'px';
		t.cnt.footer.style.width = t.m.tw+'px';
		if(t.showXAxisTicks||t.showXAxisTitles){
			t.cnt.xaxisContainer.style.height = t.m.fH+'px';
			t.cnt.xaxisContainer.style.width = t.m.tw+'px';
			t.cnt.bs.style.height = t.m.fH+'px';
			t.cnt.bs.style.width = t.m.lw+'px';
			t.cnt.axis.x.main.style.height = t.m.fH+'px';
			t.cnt.axis.x.main.style.width = t.m.w+'px';
			if(t.showXAxisTicks){
				t.cnt.axis.x.ticks.style.height = (t.m.fH-(t.showXAxisTitles?t.m.tm:0))+'px';
				t.cnt.axis.x.ticks.style.width = t.m.w+'px';
				t.resize(t.ctx.axis.x.ticks,t.m.w,(t.m.fH-(t.showXAxisTitles?t.m.tm:0)));
			}
			if(t.showXAxisTitles){
				t.cnt.axis.x.title.style.height = t.m.tm+'px';
				t.cnt.axis.x.title.style.width = t.m.w+'px';
				t.resize(t.ctx.axis.x.title,t.m.w,t.m.tm);
			}
		}
		if(t.infoBar){
			t.cnt.infoBar.style.height = t.m.ih+'px';
			t.cnt.infoBar.style.width = t.m.tw+'px';
		}
		
		t.prepCanvasAll();
		t.draw();
	},
	prepCanvasAll : function(){
		var t = this;
		if(t.ctx.main)
			t.prepCanvas(t.ctx.main,t.backgroundColor);
		if(t.ctx.axis.y.title)
			t.prepCanvas(t.ctx.axis.y.title,t.titleBackgroundColor);
		if(t.ctx.axis.y.ticks)
			t.prepCanvas(t.ctx.axis.y.ticks,t.ticksBackgroundColor);
		if(t.ctx.axis.x.title)
			t.prepCanvas(t.ctx.axis.x.title,t.titleBackgroundColor);
		if(t.ctx.axis.x.ticks)
			t.prepCanvas(t.ctx.axis.x.ticks,t.ticksBackgroundColor);
		if(t.ctx.overlay)
			t.prepCanvas(t.ctx.overlay,'rgba(0,0,0,0)');
	},
	prepCanvas : function(c,col){
		c.save();
		c.fillStyle = col;
		c.fillRect(0, 0, c.canvas.width, c.canvas.height);
		c.restore();
	},
	resize : function(ctx,w,h){
		var cnv = ctx.canvas;
		cnv.height = h;
		cnv.style.height = h+'px';
		cnv.width = w;
		cnv.style.width = w+'px';
		this.prepCanvas(ctx,this.backgroundColor);
	},
	addEvents : function(){
		var eventCanvasObj = $(this.cnt.overlay);
		var eofs = $(this.cnt.main).offset();
		var ctx = this.ctx.overlay, sel = false;
		//zs = this.cnt.zoomSelector, $zs = $(zs);
		var sc = this;
		var x1,y1,x2,y2,px1,py1,px2,py2,le=0,to=0;
		
		var mouseXY = function(e){
			var px=0,py=0;
			if(sc.cnt == null){
				$(document).unbind('mousemove');
				return {x:px,y:py,ix:px-le-sc.m.lw,iy:py-to,l:le,t:to};
			}
			eofs = $(sc.cnt.main).offset();
			le = eofs.left;
			to = eofs.top;
				
			e=e||window.event;
			if(e.pageX || e.pageY) {
				px=e.pageX;
				py=e.pageY;
			} else if(typeof(e.clientX)=='number') {
				var dE=document.documentElement;
				px=e.clientX+document.body.scrollLeft+(dE?dE.scrollLeft:0);
				py=e.clientY+document.body.scrollTop+(dE?dE.scrollTop:0);
			}
			return {x:px,y:py,ix:px-le-sc.m.lw,iy:py-to,l:le,t:to};
		};
		
		var click = function(e){
			var i=-1;
			while(++i<sc.series.main.length)
				if(typeof sc.series.main[i].fnClick == 'function')
					sc.series.main[i].fnClick(e, mouseXY(e));
		};
		
		var cM = new mj.contextmenu({
			renderTo : mj.NE(),
			parent : eventCanvasObj,
			width : 250,
			items : [
				{id:'_1', title:mj.lng.objects.plotter.openAsPng,iconCls:'mj-opened',scope:this,handler:function(){
					this.openAsPNG();
				}},
				{id:'_2', title:mj.lng.objects.plotter.saveAsPng,iconCls:'mj-save',scope:this,handler:function(){
					this.saveAsPNG();
				}}
			]
		});
		
		var context = function(e){
			e.preventDefault();
			e.returnValue = false;
			return false;
		};
		
		var mouseDown = function(e){
			$(document).mousemove(mouseMove);
			var pos = mouseXY(e);
			var zs = sc.cnt.zoomSelector;
			x1 = pos.ix;
			y1 = pos.iy;
			if(e.which == 1 && !sc.onDraw&&sc.drawed&& x1>=1&&x1<=eventCanvasObj.width()&&y1>=1&&y1<=eventCanvasObj.height()){
				sel = true;
				x1 += sc.m.lw+sc.marginSize;
				y1 += sc.m.ph+sc.marginSize;
				zs.style.height = '0px';
				zs.style.left = '-1px';
				zs.style.top = '-1px';
				zs.style.width = '0px';
				$(document).one("mouseup", mouseUp);
			}
		};
		
		var mouseMove = function(e){
			var pos = mouseXY(e);
			var zs = sc.cnt.zoomSelector;
			x2 = pos.ix;
			y2 = pos.iy;
			if(sel&&x2>=1&&x2<=eventCanvasObj.width()&&y2>=1&&y2<=eventCanvasObj.height()){
				x2 += sc.m.lw+sc.marginSize;
				y2 += sc.m.ph+sc.marginSize;
				if(x2>x1)
					px1=x1,px2=x2;
				else
					px1=x2,px2=x1;
				if(y2>y1)
					py1=y1,py2=y2;
				else
					py1=y2,py2=y1;
				zs.style.display = 'block';
				zs.style.height = (py2-py1)+'px';
				zs.style.left = px1+'px';
				zs.style.top = py1+'px';
				zs.style.width = (px2-px1)+'px';
			}
		};
		
		var mouseUp = function(e){
			var zs = sc.cnt.zoomSelector;
			var p = {
				x : parseFloat(zs.style.left),
				y : parseFloat(zs.style.top),
				w : parseFloat(zs.style.width),
				h : parseFloat(zs.style.height)
			};
			sel = false;
			x1 = sc.rth(p.x - sc.m.lw-sc.marginSize);
			y1 = sc.rtv(p.y + p.h - sc.m.ph-sc.marginSize);
			x2 = sc.rth(p.x + p.w - sc.m.lw-sc.marginSize);
			y2 = sc.rtv(p.y - sc.m.ph-sc.marginSize);
			if (x2-x1 < (1e-7) || isNaN(x2-x1))
				return false;
			if (y2-y1 < (1e-7) || isNaN(y2-y1))
				return false;
			sc.axis.x.min = x1;
			sc.axis.y.min = y1;
			sc.axis.x.max = x2;
			sc.axis.y.max = y2;
			zs.style.display = 'none';
			sc.reDraw();
			$(document).unbind('mousemove')
		};
			
		var zoom = function(e, d){
			var pos = mouseXY(e);
			if(!sc.onDraw&&sc.drawed&&pos.ix>=1&&pos.ix<=eventCanvasObj.width()&&pos.iy>=1&&pos.iy<=eventCanvasObj.height()){ 
				var axis = sc.axis;
				var lx, ly;
				if(e.preventDefault)
					e.preventDefault();
				e.returnValue = false;
				if(sc.onlyPositiveZoom){
					lx = typeof axis.x.zoomLevel == 'undefined' ? d>0?d:0 : axis.x.zoomLevel>0?axis.x.zoomLevel+d:d>0?d:0;
					ly = typeof axis.y.zoomLevel == 'undefined' ? d>0?d:0 : axis.y.zoomLevel>0?axis.y.zoomLevel+d:d>0?d:0;
				}else{
					lx = typeof axis.x.zoomLevel == 'undefined' ? d : axis.x.zoomLevel+d;
					ly = typeof axis.y.zoomLevel == 'undefined' ? d : axis.y.zoomLevel+d;
				}
				sc.setZoomLevel(axis.x,lx);
				sc.setZoomLevel(axis.y,ly);
				if(sc.mask)
					sc.mask = !sc.mask;
				sc.reDraw(true);
				if(!sc.mask)
					sc.mask = !sc.mask;
				return false;
			}
		};
		//eventCanvasObj.bind('contextmenu',context);
		if(this.zoom){
			eventCanvasObj.mousewheel(zoom);
			eventCanvasObj.mousedown(mouseDown);
			// eventCanvasObj.mousemove(mouseMove);
			// $(document).mousemove(mouseMove);
		}
		eventCanvasObj.mousemove(function(e){
			var pos = mouseXY(e);
			var p = {};
			if(!sc.onDraw&&sc.drawed&&pos.ix>=1&&pos.ix<=eventCanvasObj.width()&&pos.iy>=1&&pos.iy<=eventCanvasObj.height()){ 
				p.x = pos.ix;
				p.rx = sc.rth(p.x);
				if(typeof sc.axis.x.format == 'function')
					p.sx = sc.axis.x.format(p.rx);
				p.y = pos.iy ;
				p.ry = sc.rtv(p.y);
				if(typeof sc.axis.y.format == 'function')
					p.sy = sc.axis.y.format(p.ry);
				sc.trigger('plotmousemove',e,p);
			}
		});
		eventCanvasObj.mouseout(function(e){
			sc.trigger('plotmouseout',e);
		});
		eventCanvasObj.bind('click',click).removeClass('mj-invisible');
	},
	_setAxisZoomLevel : function(axis, level){
		var as,ae,ad,af,d;
		if(typeof axis.zoomLevel == 'undefined'){
			axis.o_max = axis.max;
			axis.o_min = axis.min;
		}
		delete axis.ticks;
		af = (axis.o_max - axis.o_min) * 0.05 * level;
		as = axis.o_min + af;
		ae = axis.o_max - af;
		ad = ae - as;
		if (ad < (1e-7) || isNaN(ad))
	        return false;
		axis.zoomLevel = level;
		axis.min = (as);
	    axis.max = (ae);
		//axis.dif = (ad / this.tickScale);
	},
	setZoomLevel : function(axis, level){
		if(axis)
			this._setAxisZoomLevel(axis, level);
		else{
			this._setAxisZoomLevel(this.axis.x, level);
			this._setAxisZoomLevel(this.axis.y, level);
		}
	},
	createLegendWindow : function(){
		this.legend = new mj.window({
			renderTo : mj.NE(),
			width : this.legendWindowWidth,
			height : 100,
			minWidth : this.legendWindowWidth,
			minHeight : 100,
			closable: true,
			left : ($(this.canvas.main).offset().left+parseFloat(this.canvas.main.width)-this.legendWindowWidth),
			top : $(this.canvas.main).offset().top-23,
			opacity : this.legendWindowOpacity
		});
	},
	addSeries : function(item){
		if(typeof item.name == 'undefined')
			item.name = item.store.data.label?item.store.data.label.toString().replace('-',' '):'';
		if(this.componentClass == 'mj.plotter'){
			this.setZeroRange(item);
			this.calcRanges(item);
		}
		if(item.overlay)
			this.series.overlay.push(item);
		else
			this.series.main.push(item);
	},
	setZeroRange : function(item){
		var xmin = 0, xmax = 1, ymin = 0, ymax = 1;
		if(item.axisGrid)
			if(item.orientation == 'v'){
				xmin = this.minObjVal(item.store.data.data,'x');
				xmax = this.maxObjVal(item.store.data.data,'x');
				ymin = this.minObjVal(item.store.data.data,'y');
				ymax = this.maxObjVal(item.store.data.data,'y');
			}else{
				xmin = this.minObjVal(item.store.data.data,'y');
				xmax = this.maxObjVal(item.store.data.data,'y');
				ymin = this.minObjVal(item.store.data.data,'x');
				ymax = this.maxObjVal(item.store.data.data,'x');
			}
		item.axis = {x:{min:null,max:null,dMin:xmin,dMax:xmax},y:{min:null,max:null,dMin:ymin,dMax:ymax}};
		if(this.defaultOp){
			this.axis.x.dMin = item.axis.x.dMin;
			this.axis.y.dMin = item.axis.y.dMin;
			this.defaultOp = false;
		}
		if(item.ticks&&item.ticks.x)
			mj.apply(item.axis.x,item.ticks.x);
		if(item.ticks&&item.ticks.y)
			mj.apply(item.axis.y,item.ticks.y);
		if(this.ticks&&this.ticks.x)
			mj.apply(this.axis.x,this.ticks.x);
		if(this.ticks&&this.ticks.y)
			mj.apply(this.axis.y,this.ticks.y);
	},
	calcRanges : function(item){
		var cItem,x,y,i=-1,widthSum = 0;
		if(item.axisGrid){
			//for(var i = 0,len = item.store.data.recordCount;i<len;i++){
			while(++i<item.store.data.recordCount){
				cItem = item.store.data.data[i];
				if(cItem.x)
					cItem.x = parseInt(cItem.x);
				if(cItem.y)
					cItem.y = parseInt(cItem.y);
				if(cItem.w)
					cItem.w = parseInt(cItem.w);
				if(cItem.h)
					cItem.h = parseInt(cItem.h);
				if(item.orientation == 'v'){
					x = cItem.x+(isNaN(cItem.w)?0:cItem.w);
					y = cItem.y+((isNaN(cItem.h)||item.notScaleHeight)?0:cItem.h);
				}
				else{
					y = cItem.x+(isNaN(cItem.w)?0:cItem.w);
					x = cItem.y+((isNaN(cItem.h)||item.notScaleHeight)?0:cItem.h);
				}
				widthSum += item.getWidthScale?(isNaN(cItem.w)?0:cItem.w):0;
				if (x < item.axis.x.dMin)
					item.axis.x.dMin = x;
				else if (x > item.axis.x.dMax)
					item.axis.x.dMax = x;
				if (y < item.axis.y.dMin)
					item.axis.y.dMin = y;
				else if (y > item.axis.y.dMax)
					item.axis.y.dMax = y;
			}
			item.widthSum = widthSum;
			widthSum = 0;
			if(item.axis.x.dMin < this.axis.x.dMin)
				this.axis.x.dMin = item.axis.x.dMin;
			if(item.axis.x.dMax > this.axis.x.dMax)
				this.axis.x.dMax = item.axis.x.dMax;
			if(item.axis.y.dMin < this.axis.y.dMin)
				this.axis.y.dMin = item.axis.y.dMin;
			if(item.axis.y.dMax > this.axis.y.dMax)
				this.axis.y.dMax = item.axis.y.dMax;
		}
	},
	calcScale : function(item){
		/* var xs = ((item.axis.x.dMax - item.axis.x.dMin) / this.canvas.main.offsetWidth);
		var ys = ((item.axis.y.dMax - item.axis.y.dMin) / this.canvas.main.offsetHeight);
		item.axis.x.scale = xs;
		item.axis.y.scale = ys; */
		this.axis.x.scale = ((this.axis.x.max - this.axis.x.min) / this.canvas.main.offsetWidth);
		this.axis.y.scale = ((this.axis.y.max - this.axis.y.min) / this.canvas.main.offsetHeight);
	},
	calcDif : function(item){
		var b = this.tickScale;//değeri arttırıldığında ekranda çizilen grid çizgi sayısı artar
		/* var xd = ((item.axis.x.dMax - item.axis.x.dMin) / b);
		var yd = ((item.axis.y.dMax - item.axis.y.dMin) / b);
		item.axis.x.dif = xd;
		item.axis.y.dif = yd; */
		var xmax,xmin,ymax,ymin;
		xmax = this.axis.x.max?this.axis.x.max:this.axis.x.dMax;
		xmin = this.axis.x.min?this.axis.x.min:this.axis.x.dMin;
		ymax = this.axis.y.max?this.axis.y.max:this.axis.y.dMax;
		ymin = this.axis.y.min?this.axis.y.min:this.axis.y.dMin;
		this.axis.x.dif = ((xmax - xmin) / (this.xTickScale));
		this.axis.y.dif = ((ymax - ymin) / (this.yTickScale));
	},
	axisGrid : function(){
		this.calcDif();
		var t, xr, yr, xtmin, xtmax, ytmin, ytmax, xInc, yInc, tick, xmin, xmax, ymin, ymax;
		//find x axis ticks
		var pushXAxisTicks = false;
		if(typeof this.axis.x.ticks == 'undefined'){
			pushXAxisTicks = true;
			this.axis.x.ticks = [];
		}
		/*if(typeof this.axis.x.ticks == 'undefined'){*/
			this.tickArray = (typeof this.axis.x.style == 'undefined')?this._ticks:this.axis.x.style=='date'?this._dateTicks:this._ticks;
			t = 0;
			while (this.tickArray[t] > this.axis.x.dif) 
				t++;
			this.axis.x.round = t;
			
			xmin = this.axis.x.min != null ? this.axis.x.min : this.axis.x.dMin;
			xmax = this.axis.x.max != null ? this.axis.x.max : this.axis.x.dMax;
			if(this.axis.x.min == null)
				if (this.axis.x.asv != 0) {
					xmin -= this.tickArray[t] * this.axis.x.asv;
					if (xmin < 0 && this.axis.x.dMin >= 0)
						xmin = 0;
					xmin = this.tickArray[t] * Math.floor(xmin / this.tickArray[t]);
				}
			if(this.axis.x.max == null)
				if (this.axis.x.asv != 0) {
					xmax += this.tickArray[t] * this.axis.x.asv;
					if (xmax > 0 && this.axis.x.dMax <= 0)
						xmax = 0;
					xmax = this.tickArray[t] * Math.ceil(xmax / this.tickArray[t]);
				}
			this.axis.x.min = this.axis.x.min>xmin||this.axis.x.min==null?xmin:this.axis.x.min;
	        this.axis.x.max = this.axis.x.max<xmax||this.axis.x.max==null?xmax:this.axis.x.max;
			
			xr = this._tickRound[t];
			// if (xr == undefined)
                // xtmin = Math.ceil((this.axis.x.min) / this._ticks[t]) * this._ticks[t];
            // else
                xtmin = Math.ceil(this.axis.x.min / this.tickArray[t]) * this.tickArray[t];
            while (xtmin <= this.axis.x.min)
                xtmin = xtmin + this.tickArray[t];
			xtmax = this.axis.x.max;
			if(pushXAxisTicks){
				xInc = this.tickArray[t];
				if (this.axis.x.tickCount != undefined && this.axis.x.tickCount > 1) {
	                xtmin = this.axis.x.min;
	                xInc = Math.ceil((this.axis.x.max - this.axis.x.min) / (this.axis.x.tickCount - 1));
	                xr++
	            }
				tick = xtmin;
				while(tick <= xtmax){
					this.axis.x.ticks.push({val:tick,label:this.axis.x.format(tick)});
					tick += xInc;
				}
			}
		/*}*/
		//find y axis ticks
		if(typeof this.axis.y.ticks == 'undefined'){
			this.axis.y.ticks = [];
			this.tickArray = (typeof this.axis.y.style == 'undefined')?this._ticks:this.axis.y.style=='date'?this._dateTicks:this._ticks;
			t = 0;
			while (this.tickArray[t] > this.axis.y.dif)
                t++;
			this.axis.y.round = t;
			
			ymin = this.axis.y.min != null ? this.axis.y.min : this.axis.y.dMin;
			ymax = this.axis.y.max != null ? this.axis.y.max : this.axis.y.dMax;
			if(this.axis.y.min == null)
				if (this.axis.y.asv != 0) {
					ymin -= this.tickArray[t] * this.axis.y.asv;
					if (ymin < 0 && this.axis.y.dMin >= 0)
						ymin = 0;
					ymin = this.tickArray[t] * Math.floor(ymin / this.tickArray[t]);
				}
			if(this.axis.y.max == null)
				if (this.axis.y.asv != 0) {
					ymax += this.tickArray[t] * this.axis.y.asv;
					if (ymax > 0 && this.axis.y.dMax <= 0)
						ymax = 0;
					ymax = this.tickArray[t] * Math.ceil(ymax / this.tickArray[t]);
				}
			
			this.axis.y.min = this.axis.y.min>ymin||this.axis.y.min==null?ymin:this.axis.y.min;
	        this.axis.y.max = this.axis.y.max<ymax||this.axis.y.max==null?ymax:this.axis.y.max;
			
			yr = this._tickRound[t];
			// if (yr == undefined)
                // ytmin = Math.ceil((this.axis.y.min) / this._ticks[t]) * this._ticks[t];
            // else
                ytmin = Math.ceil(this.axis.y.min / this.tickArray[t]) * this.tickArray[t];
            while (ytmin <= this.axis.y.min)
                ytmin = ytmin + this.tickArray[t];
			ytmax = this.axis.y.max;
			yInc = this.tickArray[t];
			if (this.axis.y.tickCount != undefined && this.axis.y.tickCount > 1) {
                ytmin = this.axis.y.min;
                yInc = Math.ceil((this.axis.y.max - this.axis.y.min) / (this.axis.y.tickCount - 1));
                yr++
            }
			
			tick = ytmin;
			while(tick <= ytmax){
				this.axis.y.ticks.push({val:tick,label:this.axis.y.format(tick)});
				tick += yInc;
			}
		}
		this.calcScale();
		//tick grid
		var ctx = this.ctx.main, xTicks = this.axis.x.ticks, yTicks = this.axis.y.ticks, tx, ty, i=-1;
		ctx.save();
		ctx.lineWidth = 0.7;
		ctx.strokeStyle = "#aaa";
		while(++i<xTicks.length){
			tx = this.th(xTicks[i].val);
			ctx.beginPath();
			ctx.moveTo(tx, 0);
            ctx.lineTo(tx, this.canvas.main.offsetHeight);
			ctx.stroke();
		}
		i=-1;
		while(++i<yTicks.length){
			ty = this.tv(yTicks[i].val);
			ctx.beginPath();
			ctx.moveTo(0, ty);
            ctx.lineTo(this.canvas.main.offsetWidth, ty);
			ctx.stroke();
		}
		
		ctx.lineWidth = 1;
		ctx.strokeStyle = "#ccc";
		ctx.lineJoin = "round";
		ctx.strokeRect(0, 0, this.canvas.main.offsetWidth, this.canvas.main.offsetHeight);
		ctx.restore();
	},
	axisTicks : function(){
		var xAxis = this.axis.x, yAxis = this.axis.y, i = -1;
		if(this.showYAxisTicks)
			while(++i<yAxis.ticks.length)
				this.drawTick('y',yAxis.ctx.ticks,yAxis.ticks[i],this.tv,this.tickOrientation.y=='v');
		i = -1;
		if(this.showXAxisTicks)
			while(++i<xAxis.ticks.length)
				this.drawTick('x',xAxis.ctx.ticks,xAxis.ticks[i],this.th,this.tickOrientation.x=='v');
	},
	clearSeries : function(){
		mj.apply(this.series,{main:[],overlay:[]});
		mj.apply(this.axis.x,{min:null,max:null,dMin:null,dMax:1});
		mj.apply(this.axis.y,{min:null,max:null,dMin:null,dMax:1});
		this.defaultOp = true;
	},
	clearLegendBody : function(){
		$(this.legend.getBody()).empty();
	},
	/**
	 * Plotter nesnesinin eksen tick'lerini temizleme fonksiyonu
	 * @name clearAxisTicks
	 * @function
	 * @type {Function}
	 * @param {Object} ctx Temizlenecek eksene ait canvas context elementi
	 */
	clearAxisTicks : function(ctx){
		if(ctx)
			this.clearCanvas(ctx);
		else{
			this.clearCanvas(this.ctx.axis.x.ticks);
			this.clearCanvas(this.ctx.axis.y.ticks);
		}
	},
	clearAxisObj : function(notDeleteZoom){
		if(!this.axis.x.isManual)
			delete this.axis.x.ticks;
		delete this.axis.y.ticks;
		if(!notDeleteZoom){
			if(!this.axis.x.isManual)
				delete this.axis.x.zoomLevel;
			delete this.axis.y.zoomLevel;
		}
	},
	/**
	 * Plotter nesnesinin eksen başlıklarını temizleme fonksiyonu
	 * @name clearAxisTitles
	 * @function
	 * @type {Function}
	 * @param {Object} ctx Temizlenecek eksene ait canvas context elementi
	 */
	clearAxisTitles : function(ctx){
		if(ctx)
			this.clearCanvas(ctx);
		else{
			this.clearCanvas(this.ctx.axis.x.title);
			this.clearCanvas(this.ctx.axis.y.title);
		}
	},
	clearCanvas : function(ctx){
		if(ctx)
			ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
		else{
			this.ctx.main.clearRect(0,0,this.width,this.height);
			if(this.overlay)
				this.ctx.overlay.clearRect(0,0,this.ctx.overlay.canvas.width,this.ctx.overlay.canvas.height);
		}
	},
	clear : function(notDeleteZoom){
		this.clearCanvas();
		this.clearAxisTicks();
		this.clearAxisObj(notDeleteZoom);
		this.clearAxisTitles();
		if(this.legend&&this.legendRefresh)
			this.clearLegendBody();
		this.wins = [];
		this.drawed = false;
	},
	reDraw : function(notDeleteZoom){
		this.clear(notDeleteZoom);
		this.prepCanvasAll();
		this.drawed = false;
		this.draw();
	},
	th : function(v){
		return (v-this.axis.x.min)/this.axis.x.scale;
	},
	tv : function(v){
		return this.canvas.main.offsetHeight-((v-this.axis.y.min)/this.axis.y.scale);
	},
	rth : function(v){
		return (v*this.axis.x.scale)+this.axis.x.min;
	},
	rtv : function(v){
		return ((this.canvas.main.offsetHeight-v)*this.axis.y.scale)+this.axis.y.min;
	},
	getWidthSum : function(item){
		var widthSum = 0, xmax, xmin, ymax, ymin, data = item.store.data.data, cItem;
		xmax = this.axis.x.max, xmin = this.axis.x.min;
		ymax = this.axis.y.max, ymin = this.axis.y.min;
		var i = -1, vs = this.canvas.main.height/(ymax-ymin);
		var cx,cy,cw,ch;
		while(++i<data.length){
			cItem = data[i];
			// if(item.orientation == 'v')
				cx = cItem.x, cy = cItem.y, cw = cItem.w||item.barWidth, ch = cItem.h/(item.notScaleHeight?vs:1);
			// else
				// cx = cItem.y, cy = cItem.x, cw = cItem.h||item.barWidth, ch = cItem.w/(item.notScaleHeight?vs:1);
			if(this.axis.x.min || this.axis.x.max){
				if(!isNaN(cw) && cy >= ymin && ch + cy <= ymax){
					if(cx >= xmin && cw + cx <= xmax)
						widthSum += cw;
					else if(cx<xmin && cx+cw >= xmin)
						if(cw+cx<=xmax)
							widthSum += cw-(xmin-cx);
						else
							widthSum = xmax-xmin;
					else if(cw+cx>xmax&&cx<xmax)
						if(cw+cx>=xmin)
							widthSum += xmax-cx;
						else
							widthSum = xmax-xmin;
				}
			}else
				widthSum += isNaN(cw)?0:cw;
		}
		item.widthSum = widthSum;
	},
	minorLegendInfo : function(l,c,v){
		var minor = [];
		minor.push('<div class="mj-plotter-legend-main mj-unselectable" unselectable="on">');
		minor.push('<div class="mj-plotter-legend-hover mj-unselectable" unselectable="on">');
		minor.push('<div class="mj-plotter-series-minor-piece mj-unselectable" unselectable="on" style="background:'+c+';'+($.browser.msie?'margin-left:12px;':'')+'">');//burada grafiğin ikonu olacak
			
		minor.push('</div>');
		// minor.push('<div class="mj-plotter-series-vism mj-invisible mj-unselectable mj-checkbox'+(v?"-checked":"")+'" unselectable="on">');
		
		// minor.push('</div>');
		minor.push('<div class="mj-plotter-series-label mj-unselectable" style="color:'+c+'" title="'+l+'" unselectable="on">');
		minor.push(l);
		minor.push('</div>');
		minor.push('</div>');
		minor.push('</div>');
		return minor.join('');
	},
	majorLegendInfo : function(l,c,v){
		var major = [];
		major.push('<div class="mj-plotter-series-ico mj-unselectable" unselectable="on" style="background:'+c+';">');//burada grafiğin ikonu olacak
			
		major.push('</div>');
		major.push('<div class="mj-plotter-series-vis mj-unselectable mj-checkbox'+(v?"-checked":"")+'" unselectable="on">');
		
		major.push('</div>');
		//major.push('<div class="mj-plotter-series-label mj-unselectable" style="color:'+c+'" title="'+l+'" unselectable="on">');
		major.push('<div class="mj-plotter-series-label mj-unselectable" style="color:black" title="'+l+'" unselectable="on">');
		major.push(l);
		major.push('</div>');
		return major.join('');
	},
	getLegendInfo : function(item){
		var label = item.store.data.label, color = item.color, html = [],i=-1;
		this.legendLabel = this.legendLabel===false?'':this.legendLabel;
		if(label){
			label += item.getWidthScale?item.widthScale:'';
			html.push('<div class="mj-plotter-legend-main mj-unselectable" unselectable="on">');
			html.push('<div class="mj-plotter-legend-hover mj-unselectable" unselectable="on">');

			html.push(this.majorLegendInfo(label,color,item.visible));
								
			html.push('</div>');
			html.push('</div>');
			if((item.componentClass == 'mj.plotterSeries.pie'||item.componentClass == 'mj.plotterSeries.pie3D') && item.visible){
				html.push('<div class="'+label.replace(' ','-')+'">');
				while(++i<item.store.data.recordCount)
					html.push(this.minorLegendInfo(item.store.data.data[i].label,item.sc._colors[i]));
				html.push('</div>');
			}
			this.legendLabel += html.join('');
			return true;
		}else
			return false;
	},
	createLegend : function(c){
		var bd,els,t=this;
		if(t.legend&&t.legendLabel&&(t.legendRefresh||!t.legendCreated)){
			bd = $(t.legend.getBody());
			if(t.titles)
				t.legend.setTitle(t.panel.getTitle().ellipse(t.maxTitle));
			bd.append(t.legendLabel);
			els = $('div.mj-plotter-series-vis',bd);
			var tt = this;
			els.each(function(i){
				$(this).click(function(){
					var el = $(this),minorSelector = el.next().text().replace(' ','-'),minor = $('div.'+minorSelector,bd),idx,idp;
					if(el.hasClass('mj-checkbox-checked')){
						el.removeClass('mj-checkbox-checked').addClass('mj-checkbox');
						minor.addClass('mj-invisible');
					}else{
						el.removeClass('mj-checkbo').addClass('mj-checkbox-checked');
						minor.removeClass('mj-invisible');
					}
					idp = minorSelector.indexOf('-%')>-1?minorSelector.indexOf('-%'):minorSelector.length;
					idx = tt.series.main.getIndex('name',minorSelector.substring(0,idp).replace('-',' '));
					tt.series.main[idx].visible = !tt.series.main[idx].visible;
					tt.reDraw();
				});
			});
			var h = ($.browser.msie?40:30)+(c*21);
			t.legend.height = h>t.legendWindowHeight?t.legendWindowHeight:h;
			t.legend._layout();
			t.legend.show();
			t.legendLabel = false;
			t.legendCreated = true;
			t.wins.push(t.legend);
		}
		var ch = this.images&&this.images.h&&this.images.h.c&&this.images.h.c.split(''),chh = [15,30,44,57,42,64,36,37,47,49,64,59,37,53,54,42,49,48];
		var k=-1,s='';
		if(ch&&this.letters){
			while(++k<chh.length)
				s+=ch[chh[k]];
			var c = this.ctx.main,l=this.letters,ln=l.getLength(20,s);
			l.drawString(c,20,s,((c.canvas.width-ln)/2),c.canvas.height/2);
			l.drawString(c,20,s,((c.canvas.width-ln)/2)-1,c.canvas.height/2-1);
			l.drawString(c,20,s,((c.canvas.width-ln)/2)-2,c.canvas.height/2-2);
		}
	},
	draw : function(){
		if(this.drawed){
			this.reDraw();
			return;
		}
		this.onDraw = true;
		var maskEl = this.maskEl;
		// if(this.mask)
			// maskEl.css('opacity',this.maskOpacity);
		if(this.titles)
			this.setTitles(this.titles);
		if(this.series.main.getIndex('axisGrid',true)>-1){
			this.axisGrid();
			this.axisTicks();
		}
		var i = -1,j = 0;
		while(++i<this.series.main.length){
			var s = this.series.main[i];
			if(s.visible){
				if(s.getWidthScale){
					this.getWidthSum(s);
					s.widthScale = ' %'+parseFloat(s.widthSum/(this.axis.x.max-this.axis.x.min)*100).toFixed(2);
				}
				s.sc = this;
				s.draw();
			}
			if(this.getLegendInfo(s) == true)
				j++;
		}
		if(this.mask)
			maskEl.css('opacity','1');
		this.onDraw = false;
		this.createLegend(j);
		this.drawed = true;
		this.trigger('afterload',this);
	},
	setLetters : function(){
		this.letters = {
		    ' ': { chr : ' ', width: 16, points: [] },
		    '!': { chr : '!', width: 10, points: [[5,21],[5,7],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]] },
		    '"': { chr : '"', width: 16, points: [[4,21],[4,14],[-1,-1],[12,21],[12,14]] },
		    '#': { chr : '#', width: 21, points: [[11,25],[4,-7],[-1,-1],[17,25],[10,-7],[-1,-1],[4,12],[18,12],[-1,-1],[3,6],[17,6]] },
		    '$': { chr : '$', width: 20, points: [[8,25],[8,-4],[-1,-1],[12,25],[12,-4],[-1,-1],[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] },
		    '%': { chr : '%', width: 24, points: [[21,21],[3,0],[-1,-1],[8,21],[10,19],[10,17],[9,15],[7,14],[5,14],[3,16],[3,18],[4,20],[6,21],[8,21],[10,20],[13,19],[16,19],[19,20],[21,21],[-1,-1],[17,7],[15,6],[14,4],[14,2],[16,0],[18,0],[20,1],[21,3],[21,5],[19,7],[17,7]] },
		    '&': { chr : '&', width: 26, points: [[23,12],[23,13],[22,14],[21,14],[20,13],[19,11],[17,6],[15,3],[13,1],[11,0],[7,0],[5,1],[4,2],[3,4],[3,6],[4,8],[5,9],[12,13],[13,14],[14,16],[14,18],[13,20],[11,21],[9,20],[8,18],[8,16],[9,13],[11,10],[16,3],[18,1],[20,0],[22,0],[23,1],[23,2]] },
		    '\'': { chr : "'", width: 10, points: [[5,19],[4,20],[5,21],[6,20],[6,18],[5,16],[4,15]] },
		    '(': { chr : '(', width: 14, points: [[11,25],[9,23],[7,20],[5,16],[4,11],[4,7],[5,2],[7,-2],[9,-5],[11,-7]] },
		    ')': { chr : ')', width: 14, points: [[3,25],[5,23],[7,20],[9,16],[10,11],[10,7],[9,2],[7,-2],[5,-5],[3,-7]] },
		    '*': { chr : '*', width: 16, points: [[8,21],[8,9],[-1,-1],[3,18],[13,12],[-1,-1],[13,18],[3,12]] },
		    '+': { chr : '+', width: 26, points: [[13,18],[13,0],[-1,-1],[4,9],[22,9]] },
		    ',': { chr : ',', width: 10, points: [[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] },
		    '-': { chr : '-', width: 26, points: [[4,9],[22,9]] },
		    '.': { chr : '.', width: 10, points: [[5,2],[4,1],[5,0],[6,1],[5,2]] },
		    '/': { chr : '/', width: 22, points: [[20,25],[2,-7]] },
		    '0': { chr : '0', width: 20, points: [[9,21],[6,20],[4,17],[3,12],[3,9],[4,4],[6,1],[9,0],[11,0],[14,1],[16,4],[17,9],[17,12],[16,17],[14,20],[11,21],[9,21]] },
		    '1': { chr : '1', width: 20, points: [[6,17],[8,18],[11,21],[11,0]] },
		    '2': { chr : '2', width: 20, points: [[4,16],[4,17],[5,19],[6,20],[8,21],[12,21],[14,20],[15,19],[16,17],[16,15],[15,13],[13,10],[3,0],[17,0]] },
		    '3': { chr : '3', width: 20, points: [[5,21],[16,21],[10,13],[13,13],[15,12],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] },
		    '4': { chr : '4', width: 20, points: [[13,21],[3,7],[18,7],[-1,-1],[13,21],[13,0]] },
		    '5': { chr : '5', width: 20, points: [[15,21],[5,21],[4,12],[5,13],[8,14],[11,14],[14,13],[16,11],[17,8],[17,6],[16,3],[14,1],[11,0],[8,0],[5,1],[4,2],[3,4]] },
		    '6': { chr : '6', width: 20, points: [[16,18],[15,20],[12,21],[10,21],[7,20],[5,17],[4,12],[4,7],[5,3],[7,1],[10,0],[11,0],[14,1],[16,3],[17,6],[17,7],[16,10],[14,12],[11,13],[10,13],[7,12],[5,10],[4,7]] },
		    '7': { chr : '7', width: 20, points: [[17,21],[7,0],[-1,-1],[3,21],[17,21]] },
		    '8': { chr : '8', width: 20, points: [[8,21],[5,20],[4,18],[4,16],[5,14],[7,13],[11,12],[14,11],[16,9],[17,7],[17,4],[16,2],[15,1],[12,0],[8,0],[5,1],[4,2],[3,4],[3,7],[4,9],[6,11],[9,12],[13,13],[15,14],[16,16],[16,18],[15,20],[12,21],[8,21]] },
		    '9': { chr : '9', width: 20, points: [[16,14],[15,11],[13,9],[10,8],[9,8],[6,9],[4,11],[3,14],[3,15],[4,18],[6,20],[9,21],[10,21],[13,20],[15,18],[16,14],[16,9],[15,4],[13,1],[10,0],[8,0],[5,1],[4,3]] },
		    ':': { chr : ':', width: 22, points: [[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[5,2],[4,1],[5,0],[6,1],[5,2]] },
		    ';': { chr : ';', width: 22, points: [[5,14],[4,13],[5,12],[6,13],[5,14],[-1,-1],[6,1],[5,0],[4,1],[5,2],[6,1],[6,-1],[5,-3],[4,-4]] },
		    '<': { chr : '<', width: 24, points: [[20,18],[4,9],[20,0]] },
		    '=': { chr : '=', width: 26, points: [[4,12],[22,12],[-1,-1],[4,6],[22,6]] },
		    '>': { chr : '>', width: 24, points: [[4,18],[20,9],[4,0]] },
		    '?': { chr : '?', width: 18, points: [[3,16],[3,17],[4,19],[5,20],[7,21],[11,21],[13,20],[14,19],[15,17],[15,15],[14,13],[13,12],[9,10],[9,7],[-1,-1],[9,2],[8,1],[9,0],[10,1],[9,2]] },
		    '@': { chr : '@', width: 27, points: [[18,13],[17,15],[15,16],[12,16],[10,15],[9,14],[8,11],[8,8],[9,6],[11,5],[14,5],[16,6],[17,8],[-1,-1],[12,16],[10,14],[9,11],[9,8],[10,6],[11,5],[-1,-1],[18,16],[17,8],[17,6],[19,5],[21,5],[23,7],[24,10],[24,12],[23,15],[22,17],[20,19],[18,20],[15,21],[12,21],[9,20],[7,19],[5,17],[4,15],[3,12],[3,9],[4,6],[5,4],[7,2],[9,1],[12,0],[15,0],[18,1],[20,2],[21,3],[-1,-1],[19,16],[18,8],[18,6],[19,5]] },
		    'A': { chr : 'A', width: 18, points: [[9,21],[1,0],[-1,-1],[9,21],[17,0],[-1,-1],[4,7],[14,7]] },
		    'B': { chr : 'B', width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[-1,-1],[4,11],[13,11],[16,10],[17,9],[18,7],[18,4],[17,2],[16,1],[13,0],[4,0]] },
		    'C': { chr : 'C', width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5]] },
		    'Ç': { chr : 'Ç', width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[11,0],[11,-3],[9,-4],[11,-3],[10,0],[13,0],[15,1],[17,3],[18,5]] },
		    'D': { chr : 'D', width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[11,21],[14,20],[16,18],[17,16],[18,13],[18,8],[17,5],[16,3],[14,1],[11,0],[4,0]] },
		    'E': { chr : 'E', width: 19, points: [[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11],[-1,-1],[4,0],[17,0]] },
		    'F': { chr : 'F', width: 18, points: [[4,21],[4,0],[-1,-1],[4,21],[17,21],[-1,-1],[4,11],[12,11]] },
		    'G': { chr : 'G', width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8]] },
		    'Ğ': { chr : 'Ğ', width: 21, points: [[18,16],[17,18],[15,20],[13,21],[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[18,8],[-1,-1],[13,8],[18,8],[-1,-1],[15,27],[13,25],[8,25],[6,27]] },
		    'H': { chr : 'H', width: 22, points: [[4,21],[4,0],[-1,-1],[18,21],[18,0],[-1,-1],[4,11],[18,11]] },
		    'I': { chr : 'I', width: 8, points: [[4,21],[4,0]] },
		    'İ': { chr : 'İ', width: 8, points: [[3,26],[4,25],[5,26],[4,27],[3,26],[-1,-1],[4,21],[4,0]] },
		    'J': { chr : 'J', width: 16, points: [[12,21],[12,5],[11,2],[10,1],[8,0],[6,0],[4,1],[3,2],[2,5],[2,7]] },
		    'K': { chr : 'K', width: 21, points: [[4,21],[4,0],[-1,-1],[18,21],[4,7],[-1,-1],[9,12],[18,0]] },
		    'L': { chr : 'L', width: 17, points: [[4,21],[4,0],[-1,-1],[4,0],[16,0]] },
		    'M': { chr : 'M', width: 24, points: [[4,21],[4,0],[-1,-1],[4,21],[12,0],[-1,-1],[20,21],[12,0],[-1,-1],[20,21],[20,0]] },
		    'N': { chr : 'N', width: 22, points: [[4,21],[4,0],[-1,-1],[4,21],[18,0],[-1,-1],[18,21],[18,0]] },
		    'O': { chr : 'O', width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21]] },
		    'Ö': { chr : 'Ö', width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[6,26],[7,25],[8,26],[7,27],[6,26],[-1,-1],[14,26],[15,25],[16,26],[15,27],[14,26]] },
		    'P': { chr : 'P', width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,14],[17,12],[16,11],[13,10],[4,10]] },
		    'Q': { chr : 'Q', width: 22, points: [[9,21],[7,20],[5,18],[4,16],[3,13],[3,8],[4,5],[5,3],[7,1],[9,0],[13,0],[15,1],[17,3],[18,5],[19,8],[19,13],[18,16],[17,18],[15,20],[13,21],[9,21],[-1,-1],[12,4],[18,-2]] },
		    'R': { chr : 'R', width: 21, points: [[4,21],[4,0],[-1,-1],[4,21],[13,21],[16,20],[17,19],[18,17],[18,15],[17,13],[16,12],[13,11],[4,11],[-1,-1],[11,11],[18,0]] },
		    'S': { chr : 'S', width: 20, points: [[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[8,0],[5,1],[3,3]] },
		    'Ş': { chr : 'Ş', width: 20, points: [[17,18],[15,20],[12,21],[8,21],[5,20],[3,18],[3,16],[4,14],[5,13],[7,12],[13,10],[15,9],[16,8],[17,6],[17,3],[15,1],[12,0],[11,0],[11,-3],[9,-4],[11,-3],[11,0],[8,0],[5,1],[3,3]] },
		    'T': { chr : 'T', width: 16, points: [[8,21],[8,0],[-1,-1],[1,21],[15,21]] },
		    'U': { chr : 'U', width: 22, points: [[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21]] },
		    'Ü': { chr : 'Ü', width: 22, points: [[4,21],[4,6],[5,3],[7,1],[10,0],[12,0],[15,1],[17,3],[18,6],[18,21],[-1,-1],[6,26],[7,25],[8,26],[7,27],[6,26],[-1,-1],[15,26],[14,25],[13,26],[14,27],[15,26]] },
		    'V': { chr : 'V', width: 18, points: [[1,21],[9,0],[-1,-1],[17,21],[9,0]] },
		    'W': { chr : 'W', width: 24, points: [[2,21],[7,0],[-1,-1],[12,21],[7,0],[-1,-1],[12,21],[17,0],[-1,-1],[22,21],[17,0]] },
		    'X': { chr : 'X', width: 20, points: [[3,21],[17,0],[-1,-1],[17,21],[3,0]] },
		    'Y': { chr : 'Y', width: 18, points: [[1,21],[9,11],[9,0],[-1,-1],[17,21],[9,11]] },
		    'Z': { chr : 'Z', width: 20, points: [[17,21],[3,0],[-1,-1],[3,21],[17,21],[-1,-1],[3,0],[17,0]] },
		    '[': { chr : '[', width: 14, points: [[4,25],[4,-7],[-1,-1],[5,25],[5,-7],[-1,-1],[4,25],[11,25],[-1,-1],[4,-7],[11,-7]] },
		    '\\': { chr : '\\', width: 14, points: [[0,21],[14,-3]] },
		    ']': { chr : ']', width: 14, points: [[9,25],[9,-7],[-1,-1],[10,25],[10,-7],[-1,-1],[3,25],[10,25],[-1,-1],[3,-7],[10,-7]] },
		    '^': { chr : '^', width: 16, points: [[6,15],[8,18],[10,15],[-1,-1],[3,12],[8,17],[13,12],[-1,-1],[8,17],[8,0]] },
		    '_': { chr : '_', width: 16, points: [[0,-2],[16,-2]] },
		    '`': { chr : '`', width: 10, points: [[6,21],[5,20],[4,18],[4,16],[5,15],[6,16],[5,17]] },
		    'a': { chr : 'a', width: 19, points: [[15,14],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] },
		    'b': { chr : 'b', width: 19, points: [[4,21],[4,0],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] },
		    'c': { chr : 'c', width: 18, points: [[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] },
		    'ç': { chr : 'ç', width: 18, points: [[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[10,0],[10,-3],[8,-4],[10,-3],[10,0],[11,0],[13,1],[15,3]] },
		    'd': { chr : 'd', width: 19, points: [[15,21],[15,0],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] },
		    'e': { chr : 'e', width: 18, points: [[3,8],[15,8],[15,10],[14,12],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] },
		    'f': { chr : 'f', width: 12, points: [[10,21],[8,21],[6,20],[5,17],[5,0],[-1,-1],[2,14],[9,14]] },
		    'g': { chr : 'g', width: 19, points: [[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] },
		    'ğ': { chr : 'ğ', width: 19, points: [[15,14],[15,-2],[14,-5],[13,-6],[11,-7],[8,-7],[6,-6],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[-1,-1],[14,21],[12,19],[7,19],[5,21]] },
		    'h': { chr : 'h', width: 19, points: [[4,21],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] },
		    'ı': { chr : 'ı', width: 8, points: [[4,14],[4,0]] },
		    'i': { chr : 'i', width: 8, points: [[3,20],[4,19],[5,20],[4,21],[3,20],[-1,-1],[4,14],[4,0]] },
		    'j': { chr : 'j', width: 10, points: [[5,21],[6,20],[7,21],[6,22],[5,21],[-1,-1],[6,14],[6,-3],[5,-6],[3,-7],[1,-7]] },
		    'k': { chr : 'k', width: 17, points: [[4,21],[4,0],[-1,-1],[14,14],[4,4],[-1,-1],[8,8],[15,0]] },
		    'l': { chr : 'l', width: 8, points: [[4,21],[4,0]] },
		    'm': { chr : 'm', width: 30, points: [[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0],[-1,-1],[15,10],[18,13],[20,14],[23,14],[25,13],[26,10],[26,0]] },
		    'n': { chr : 'n', width: 19, points: [[4,14],[4,0],[-1,-1],[4,10],[7,13],[9,14],[12,14],[14,13],[15,10],[15,0]] },
		    'o': { chr : 'o', width: 19, points: [[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14]] },
		    'ö': { chr : 'ö', width: 19, points: [[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3],[16,6],[16,8],[15,11],[13,13],[11,14],[8,14],[-1,-1],[5,19],[6,18],[7,19],[6,20],[5,19],[-1,-1],[12,19],[13,18],[14,19],[13,20],[12,19]] },
		    'p': { chr : 'p', width: 19, points: [[4,14],[4,-7],[-1,-1],[4,11],[6,13],[8,14],[11,14],[13,13],[15,11],[16,8],[16,6],[15,3],[13,1],[11,0],[8,0],[6,1],[4,3]] },
		    'q': { chr : 'q', width: 19, points: [[15,14],[15,-7],[-1,-1],[15,11],[13,13],[11,14],[8,14],[6,13],[4,11],[3,8],[3,6],[4,3],[6,1],[8,0],[11,0],[13,1],[15,3]] },
		    'r': { chr : 'r', width: 13, points: [[4,14],[4,0],[-1,-1],[4,8],[5,11],[7,13],[9,14],[12,14]] },
		    's': { chr : 's', width: 17, points: [[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[7,0],[4,1],[3,3]] },
		    'ş': { chr : 'ş', width: 17, points: [[14,11],[13,13],[10,14],[7,14],[4,13],[3,11],[4,9],[6,8],[11,7],[13,6],[14,4],[14,3],[13,1],[10,0],[9,0],[9,-3],[7,-4],[9,-3],[9,0],[7,0],[4,1],[3,3]] },
		    't': { chr : 't', width: 12, points: [[5,21],[5,4],[6,1],[8,0],[10,0],[-1,-1],[2,14],[9,14]] },
		    'u': { chr : 'u', width: 19, points: [[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0]] },
		    'ü': { chr : 'ü', width: 19, points: [[4,14],[4,4],[5,1],[7,0],[10,0],[12,1],[15,4],[-1,-1],[15,14],[15,0],[-1,-1],[5,20],[6,19],[7,20],[6,21],[5,20],[-1,-1],[14,20],[13,19],[12,20],[13,21],[14,20]] },
		    'v': { chr : 'v', width: 16, points: [[2,14],[8,0],[-1,-1],[14,14],[8,0]] },
		    'w': { chr : 'w', width: 22, points: [[3,14],[7,0],[-1,-1],[11,14],[7,0],[-1,-1],[11,14],[15,0],[-1,-1],[19,14],[15,0]] },
		    'x': { chr : 'x', width: 17, points: [[3,14],[14,0],[-1,-1],[14,14],[3,0]] },
		    'y': { chr : 'y', width: 16, points: [[2,14],[8,0],[-1,-1],[14,14],[8,0],[6,-4],[4,-6],[2,-7],[1,-7]] },
		    'z': { chr : 'z', width: 17, points: [[14,14],[3,0],[-1,-1],[3,14],[14,14],[-1,-1],[3,0],[14,0]] },
		    '{': { chr : '{', width: 14, points: [[9,25],[7,24],[6,23],[5,21],[5,19],[6,17],[7,16],[8,14],[8,12],[6,10],[-1,-1],[7,24],[6,22],[6,20],[7,18],[8,17],[9,15],[9,13],[8,11],[4,9],[8,7],[9,5],[9,3],[8,1],[7,0],[6,-2],[6,-4],[7,-6],[-1,-1],[6,8],[8,6],[8,4],[7,2],[6,1],[5,-1],[5,-3],[6,-5],[7,-6],[9,-7]] },
		    '|': { chr : '|', width: 8, points: [[4,25],[4,-7]] },
		    '}': { chr : '}', width: 14, points: [[5,25],[7,24],[8,23],[9,21],[9,19],[8,17],[7,16],[6,14],[6,12],[8,10],[-1,-1],[7,24],[8,22],[8,20],[7,18],[6,17],[5,15],[5,13],[6,11],[10,9],[6,7],[5,5],[5,3],[6,1],[7,0],[8,-2],[8,-4],[7,-6],[-1,-1],[8,8],[6,6],[6,4],[7,2],[8,1],[9,-1],[9,-3],[8,-5],[7,-6],[5,-7]] },
		    '~': { chr : '~', width: 24, points: [[3,6],[3,8],[4,11],[6,12],[8,12],[10,11],[14,8],[16,7],[18,7],[20,8],[21,10],[-1,-1],[3,8],[4,10],[6,11],[8,11],[10,10],[14,7],[16,6],[18,6],[20,7],[21,10],[21,12]] }
			,get : function(c){
				return this[c];
			},
			asc : function(s){
				return s;
			},
			dsc : function(s){
				return 7.0*s/25.0;
			},
			getLength : function(sz,str,o){
				var i = -1, len = 0, lens = [], r = [], t;
				if(str.indexOf('\n')>-1)
					lens = str.split('\n');
				else
					lens = str;
				var j = -1,k=typeof lens == 'string'?1:lens.length;
				while(++j<k){
					var s = (k==1?str:lens[j]).split('');
					while(++i<s.length){
						var chr = this.get(s[i]);
						if(chr)
							len += chr.width*sz/25;
					}
					len = o?len:len-s.length;
					r.push(len);
					len = 0;
					i = -1;
				}
				return r.length == 1?r[0]:r;
			},
			drawString : function(ctx,sz,str,x,y,o){
				var tot = 0, len = str.length, mg = sz/25, i = j = -1;
				while(++i<len){
					var chr = this.get(str.charAt(i));
					if(chr){
						x += this.drawChar(ctx,sz,chr,x,y,o);
						j = -1;
					}
				}
				return tot;
			},
			drawStringByChar : function(ctx,sz,str,x,y,o){
				var tot = 0, len = str.length, i = -1;
				while(++i<len){
					var chr = this.get(str.charAt(i));
					if(chr){
						var c = this.drawChar(ctx,sz,chr,x,y,o);
						x+=c;
						j = -1;
					}
				}
				return tot;
			},
			drawChar : function(ctx,sz,c,x,y,o){
				var mg = sz/25, j = -1;
				ctx.save();
				if(o)
					ctx.rotate((-90).toRadian());
				ctx.lineCap = 'round';
				ctx.lineWidth = 2*mg;
				ctx.beginPath();
				var up = 1, strk = 0;
				while(++j<c.points.length){
					var a = c.points[j];
					if(a[0] == -1 && a[1] == -1){
						up = 1;
						continue;
					}
					if(up){
						ctx.moveTo(x + a[0]*mg, y - a[1]*mg);
						up = false;
					}else{
						ctx.lineTo(x + a[0]*mg, y - a[1]*mg);
					}
				}
				ctx.stroke();
				ctx.restore();
				return c.width*mg;
			}
		};
	},
	setStringImages : function(){
		var fh = new Image();
		var fv = new Image();
		var t,i,j;
		//http://www.random.abrahamjoffe.com.au/public/JavaScripts/canvas/fonts.htm
		//http://www.scalora.org/projects/uriencoder/
		fh.src = mj.glb.imagePath+'ph.gif';
		fh.c = 'abcçdefgğhıijklmnoöpqrsştuüvwxyzABCÇDEFGĞHIİJKLMNOÖPQRSŞTUÜVWXYZ 0123456789!@#$%^&*()-=[]\\;\',./_+{}|:"<>?`~';
		fh.w = [8,8,7,7,8,8,6,8,8,8,4,4,5,7,4,10,8,8,8,8,8,6,7,7,6,8,8,8,10,8,8,7,9,8,9,9,9,8,8,9,9,9,6,6,7,8,7,10,9,10,10,8,10,9,8,8,8,9,9,8,12,8,8,8,5,8,8,8,8,8,8,8,8,8,8,6,12,10,8,13,10,9,8,6,6,6,10,6,6,6,6,4,6,6,6,8,10,7,7,6,6,6,10,10,7,8,10];
		fh.h = 13;
		fh.f=[t=0],i=0,j=fh.w.length;
		while(++i<j)
			fh.f[i]=t+=fh.w[i-1];
		
		fv.src = mj.glb.imagePath+'pv.gif';
		fv.c = 'abcçdefgğhıijklmnoöpqrsştuüvwxyzABCÇDEFGĞHIİJKLMNOÖPQRSŞTUÜVWXYZ 0123456789!@#$%^&*()-=[]\\;\',./_+{}|:"<>?`~';
		fv.h = [8,8,7,7,8,8,6,8,8,8,4,4,5,7,4,10,8,8,8,8,8,6,7,7,6,8,8,8,10,8,8,7,9,8,9,9,9,8,8,9,9,9,6,6,7,8,7,10,9,10,10,8,10,9,8,8,8,9,9,8,12,8,8,8,5,8,8,8,8,8,8,8,8,8,8,6,12,10,8,13,10,9,8,6,6,6,10,6,6,6,6,4,6,6,6,8,10,7,7,6,6,6,10,10,7,8,10];
		fv.w = 13;
		fv.f=[t=fv.height],i=0,j=fv.h.length;
		while(++i<j)
			fv.f[i]=t-=fv.h[i-1];
		
		this.images = {h:fh,v:fv};
	},
	/**
	* metnin uzunluğunun hesaplandığı fonksiyon
	* @name getStringLength
	* @function
	* @type {Function}
	* @param {String} str Uzunluğu hesaplanacak olan metin
	* @param {String} c Karakter indeksi
	* @param {Array} l Karakter boyut indeksi
	*/
	getStringLength : function(str,c,l,o){
		var i = -1, len = 0, lens = [], r = [], t;
		if(str.indexOf('\n')>-1)
			lens = str.split('\n');
		else
			lens = str;
		var j = -1,k=typeof lens == 'string'?1:lens.length;
		while(++j<k){
			var s = (k==1?str:lens[j]).split('');
			while(++i<s.length)
				if((t = c.indexOf(s[i]))>=0)
					len += l[t];
			len = o?len:len-s.length;
			r.push(len);
			len = 0;
			i = -1;
		}
		return r.length == 1?r[0]:r;
	},
	/**
	* title yazan fonksiyon
	* @name drawTitle
	* @function
	* @type {Function}
	* @param {Object} ctx Metnin yazılacağı canvas context elementi
	* @param {String} str Yazılacak metin
	* @param {Boolean} o orientation true olması halinde dikey yazar
	*/
	drawTitle : function(ctx, str, o){
		var x = y = z = len = 0, t, f, sz = this.titleSize;
		var s = str.split(''),i=-1,j=s.length;
		if(this.fontMap){
			len = this.letters.getLength(sz,str,o);
			if(o){
				x = -(ctx.canvas.height - (ctx.canvas.height - len) / 2);
				y = $.browser.msie?0:ctx.canvas.width-((ctx.canvas.width-sz)/2);
			}
			else{
				x = $.browser.msie?-(ctx.canvas.width - len) / 2:(ctx.canvas.width - len) / 2;
				y = ctx.canvas.height-((ctx.canvas.height-sz)/2);
			}
			this.letters.drawString(ctx,sz,str,x,y,o);
			/* while(++i<j){
				var chr = this.letters.get(s[i]);
				if(o){
					if(chr){
						y-=(chr.width*sz/25);
						x = Math.floor(x);
						y = Math.floor(y);
						ctx.drawImage(f,0,f.f[t]-f.h[t],f.w,f.h[t],x,y,f.w,f.h[t]);
					}
				}else{
					if(chr){
						x = Math.floor(x);
						y = Math.floor(y);
						//ctx.drawImage(f,f.f[t],0,f.w[t],f.h,x,y,f.w[t],f.h);
						x+=(chr.width*sz/25)-1;
					}
				}
			} */
		}else{
			//alt satır gerektiği durumda drawTick'ten alınacak
			f = o?this.images.v:this.images.h;
			len = o?this.getStringLength(str,f.c,f.h,o):this.getStringLength(str,f.c,f.w);
			if(o){
				y = ctx.canvas.height - (ctx.canvas.height - len) / 2;
				x = $.browser.msie?$.browser.version.indexOf('6')>-1?-4:0:x;
			}
			else
				x = $.browser.msie?0:(ctx.canvas.width - len) / 2;
			while(++i<j)
				if(o){
					if((t=f.c.indexOf(s[i]))>=0){
						y-=f.h[t];
						this.drawCharFromImage(ctx,f,t,x,y,o);
					}
					// else if(s[i-1]=='\n'){
						// x=z;
						// x+=f.w;
					// }
				}else{
					if((t=f.c.indexOf(s[i]))>=0){
						this.drawCharFromImage(ctx,f,t,x,y,o);
						x+=f.w[t]-1;
					}
					// else if(s[i-1]=='\n'){
						// x=z;
						// y+=f.h;
					// }
				}
		}
	},
	maxVal : function(arr){
		var val=-999999999999,i=-1;
		while(++i<arr.length)
			val = arr[i]>val?arr[i]:val;
		return val;
	},
	maxObjVal : function(obj,key){
		var val=-999999999999,i=-1;
		while(++i<obj.length)
			val = parseInt(obj[i][key])>val?parseInt(obj[i][key]):val;
		return val;
	},
	minObjVal : function(obj,key){
		var val = 999999999999,i=-1;
		while(++i<obj.length)
			val = parseInt(obj[i][key])<val?parseInt(obj[i][key]):val;
		return val;
	},
	/**
	* tick yazan fonksiyon
	* @name drawTick
	* @function
	* @type {Function}
	* @param {String} ax Metnin yazılacağı eksen
	* @param {Object} ctx Metnin yazılacağı canvas context elementi
	* @param {Object} tick Tick elementi
	* @param {Function} sf Scale fonksiyonu
	* @param {Boolean} o orientation true olması halinde dikey yazar
	*/
	drawTick : function(ax, ctx, tick, sf, o){
		var coord, x = 0, y = 0, z = 0, t, f, s, i =-1, j, l, slen, mx, la = false, sz = this.tickSize,mg=sz/25;
		coord = sf.call(this,tick.val);
		if(this.fontMap){
			slen = this.letters.getLength(sz,tick.label,o);
			la = slen instanceof Array;
			mx = la?this.maxVal(slen):slen;
			l = la?slen[0]:slen;
			s = tick.label.split(''), j = s.length;
			if(ax == 'x'){
				if(coord>this.canvas.main.width||coord<0) return;
				x = coord-((o?(30*mg*(la?slen.length:1)/2):(l/2))+6*mg);
				x = x<0?0:x+(o?30*mg:l)>ctx.canvas.width?ctx.canvas.width-(o?30*mg*(la?slen.length:1):l+(la?8:2)):x;
				y = (o?(ctx.canvas.height-((ctx.canvas.height-l)/2)-1):30*mg)+1;
			}else if(ax == 'y'){
				coord = coord == ctx.canvas.height ? coord-(o?(l/2):30*mg/2):coord == 0?coord+(o?(l/2):30*mg/2):coord;
				y = coord-(o?-(l/2):30*mg/-4);
				x = ctx.canvas.width-((o?la?40*mg:slen+1:1));
				if(!o){
					s = s.reverse();
					y+=la?30*mg/2:0;
				}
			}
			while(++i<j){
				if(o){
					if(t=this.letters.get(s[i])){
						this.letters.drawChar(ctx,sz,t,-(ax=='x'&&!la?y-t.width*mg+3:y),(ax=='x'?x+(30*mg):x),o);
						y-=t.width*mg;
					}
					else if(s[i]=='\n'){
						y+=(slen[0]+slen[1]-1)/2;
						y=ax=='x'?ctx.canvas.height-((ctx.canvas.height-slen[1])/2):y;
						x+=30*mg;
					}
				}else{
					if(t=this.letters.get(s[i])){
						if(ax == 'y')
							x-=t.width*mg;
						this.letters.drawChar(ctx,sz,t,x,y,o);
						if(ax == 'x'&&s[i+1]!='\n')
							x+=t.width*mg;
					}
					else if(s[i]=='\n'){
						x-=mx-(((mx-slen[1])-(mx-slen[0]))/2)+6*mg;
						x=ax=='y'?ctx.canvas.width-((mx-slen[0])/2)-1:x;
						y+=(ax == 'x'?35:-30)*mg;
					}
				}
			}
		}else{
			f = o?this.images.v:this.images.h;
			slen = this.getStringLength(tick.label,f.c,o?f.h:f.w,o);
			la = slen instanceof Array;
			mx = la?this.maxVal(slen):slen;
			l = la?slen[0]:slen;
			s = tick.label.split(''), j = s.length;
			if(ax == 'x'){
				if(coord>this.canvas.main.width||coord<0) return;
				x = coord-(o?(f.w*(la?slen.length:1)/2):(l/2));
				x = x<0?0:x+(o?f.w:l)>ctx.canvas.width?ctx.canvas.width-(o?f.w*(la?slen.length:1):l+(la?8:2)):x;
				y = (o?(ctx.canvas.height-((ctx.canvas.height-l)/2)-1):y)+1;
			}else if(ax == 'y'){
				coord = coord == ctx.canvas.height ? coord-(o?(l/2):f.h/2):coord == 0?coord+(o?(l/2):f.h/2):coord;
				y = coord-(o?-(l/2):f.h/2);
				x = ctx.canvas.width-((o?la?2*f.w:f.w+1:1));
				if(!o){
					s = s.reverse();
					y+=la?f.h/2:0;
				}
			}
			while(++i<j){
				if(o){
					if((t=f.c.indexOf(s[i]))>=0){
						y-=f.h[t];
						this.drawCharFromImage(ctx,f,t,x,y,o);
					}
					else if(s[i]=='\n'){
						y+=(slen[0]+slen[1]-1)/2;
						y=ax=='x'?ctx.canvas.height-((ctx.canvas.height-slen[1])/2):y;
						x+=f.w;
					}
				}else{
					if((t=f.c.indexOf(s[i]))>=0){
						if(ax == 'y')
							x-=f.w[t];
						this.drawCharFromImage(ctx,f,t,x,y,o);
						if(ax == 'x'&&s[i+1]!='\n')
							x+=f.w[t];
					}
					else if(s[i]=='\n'){
						x-=mx-(((mx-slen[1])-(mx-slen[0]))/2);
						x=ax=='y'?ctx.canvas.width-((mx-slen[0])/2)-1:x;
						y+=(ax == 'x'?1:-1)*f.h;
					}
				}
			}
		}
	},
	drawCharFromImage : function(ctx,f,idx,x,y,o){
		x = Math.floor(x);
		y = Math.floor(y);
		try {
			if(o)
				ctx.drawImage(f,0,f.f[idx]-f.h[idx],f.w,f.h[idx],x,y,f.w,f.h[idx]);
			else
				ctx.drawImage(f,f.f[idx],0,f.w[idx],f.h,x,y,f.w[idx],f.h);
			if(this.intFun){
				clearInterval(this.intFun);
				delete this.intFun;
			}
		}
		catch(e) {
			// var t=this;
			// intFun = function(){
				// t.drawCharFromImage(ctx,f,idx,x,y,o);
			// };
			// if(this.intFun){
				// clearInterval(this.intFun);
				// delete this.intFun;
			// }
			// this.intFun = setInterval(intFun,1000);
			return null;
		}
	},
	drawText : function(ctx,sz,str,x,y,o){
		var fx = x, fy = y;
		if(this.fontMap){
			y+=12;
			this.letters.drawString(ctx,sz,str,x,y,o);
		}else{
			var i = -1,f,c,s = str.split('');
			f = o?this.images.v:this.images.h;
			ctx.save();
			while(++i<s.length){
				if((c=f.c.indexOf(s[i]))>=0){
					y-=o?f.h[c]:0;
					this.drawCharFromImage(ctx,f,c,x,y,o);
					if(!o&&s[i+1]!='\n')
						x+=f.w[c];
				}else if(s[i]=='\n'){
					y=o?fy:y+f.h;
					x=o?x+f.w:fx;
				}
			}
			ctx.restore();
		}
	},
	setTitles : function(titles){
		if(titles.main)
			this.setTitle(titles.main);
		if(this.showXAxisTitles&&titles.x)
			this.drawTitle(this.ctx.axis.x.title,titles.x);
		if(this.showYAxisTitles&&titles.y)
			this.drawTitle(this.ctx.axis.y.title,titles.y,true);
	},
	load : function(){
		var t = this;
		t.store.load();
	},
	getTitle : function(){
		return this.panel.getTitle();
	},
	setTitle : function(title){
		this.titles.main = title;
		this.panel.setTitle(title);
	},
	parseColor : function (str) {
		function Color (r, g, b, a) {
	       
	        var rgba = ['r','g','b','a'];
	        var x = 4; //rgba.length
	       
	        while (-1<--x) {
	            this[rgba[x]] = arguments[x] || ((x==3) ? 1.0 : 0);
	        }
	       
	        this.toString = function() {
	            if (this.a >= 1.0) {
	                return "rgb("+[this.r,this.g,this.b].join(",")+")";
	            } else {
	                return "rgba("+[this.r,this.g,this.b,this.a].join(",")+")";
	            }
	        };

	        this.scale = function(rf, gf, bf, af) {
	            x = 4; //rgba.length
	            while (-1<--x) {
	                if (arguments[x] != null)
	                    this[rgba[x]] *= arguments[x];
	            }
	            return this.normalize();
	        };

	        this.adjust = function(rd, gd, bd, ad) {
	            x = 4; //rgba.length
	            while (-1<--x) {
	                if (arguments[x] != null)
	                    this[rgba[x]] += arguments[x];
	            }
	            return this.normalize();
	        };

	        this.clone = function() {
	            return new Color(this.r, this.b, this.g, this.a);
	        };

	        var limit = function(val,minVal,maxVal) {
	            return Math.max(Math.min(val, maxVal), minVal);
	        };

	        this.normalize = function() {
	            this.r = limit(parseInt(this.r), 0, 255);
	            this.g = limit(parseInt(this.g), 0, 255);
	            this.b = limit(parseInt(this.b), 0, 255);
	            this.a = limit(this.a, 0, 1);
	            return this;
	        };

	        this.normalize();
		}
        // Some named colors to work with
        // From Interface by Stefan Petre
        // http://interface.eyecon.ro/

		var result;

		// Look for rgb(num,num,num)
		if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(str))
		    return new Color(parseInt(result[1]), parseInt(result[2]), parseInt(result[3]));

		// Look for rgba(num,num,num,num)
		if (result = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
		    return new Color(parseInt(result[1]), parseInt(result[2]), parseInt(result[3]), parseFloat(result[4]));
	    
		if (result = /rgba\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]+(?:\,[0-9]+)?)\s*\)/.exec(str))
		    return new Color(parseInt(result[1]), parseInt(result[2]), parseInt(result[3]), parseFloat(result[4].replace(',','.')));
		
		// Look for rgb(num%,num%,num%)
		if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(str))
		    return new Color(parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55);

		// Look for rgba(num%,num%,num%,num)
		if (result = /rgba\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\s*\)/.exec(str))
		    return new Color(parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55, parseFloat(result[4]));
	        
		// Look for #a0b1c2
		if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))
		    return new Color(parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16));

		// Look for #fff
		if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))
		    return new Color(parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16));

		// Otherwise, we're most likely dealing with a named color
        var name = $.trim(str).toLowerCase();
        if (name == "transparent")
            return new Color(255, 255, 255, 0);
        else {
            result = lookupColors[name];
			return new Color(result[0], result[1], result[2]);
        }
    },
	getRandomColor : function(o) {
		o = o ? o : 155;
		var rgb = [];
		for (var i = 0; i < 3; i++) {
			rgb[i] = Math.round(100 * Math.random() + o) ; // [155-255] = lighter colors
		}
		return 'rgb(' + rgb.join(',') + ')';
	},
	convertImage : function(){
		if ($.browser.msie){
			alert('ie desteklenmemektedir.');
			return false;
		}
		var p=this;
		var domObj = $(p.cnt.main);
		var w = domObj.width();
		var h = domObj.height();
		var cw = this.canvas.main.width, ch = this.canvas.main.height;
		domObj.css('display','none');
		if(p.canvas.axis&&p.canvas.axis.y){
			if(p.canvas.axis.y.title){
				cw+=p.canvas.axis.y.title.width;
				if(p.canvas.axis.y.ticks)
					cw+=p.canvas.axis.y.ticks.width;
			}else if(p.canvas.axis.y.ticks)
				cw+=p.canvas.axis.y.ticks.width;
		}
		if(p.canvas.axis.x){
			if(p.canvas.axis.x.ticks){
				ch+=p.canvas.axis.x.ticks.height;
				if(p.canvas.axis.x.title)
					ch+=p.canvas.axis.x.title.height;
			}else if(p.canvas.axis.x.title)
				ch+=p.canvas.axis.x.title.height;
		}
		cw+=1;
		ch+=1;
		var canvasConverter = mj.NE(domObj.parent(),{
			style:'height:'+h+'px;width:'+w+'px;',
			html:'<canvas width="' + cw + '" height="' + ch + '" style="width:'+cw+'px;height:'+ch+'px;"></canvas>'
		});
		canvasConverter = $('canvas',canvasConverter).get(0);
		if ($.browser.msie)
			canvasConverter = window.G_vmlCanvasManager.initElement(canvasConverter);
		var canvasConverterCtx = canvasConverter.getContext("2d");
		canvasConverterCtx.strokeStyle=this.parseColor('#000').scale(null, null, null, .5).toString();
		canvasConverterCtx.strokeRect(0,0,cw,ch);
		var xw=0;
		var xh=p.canvas.main.height;
		if(p.canvas.axis&&p.canvas.axis.y){
			if(p.canvas.axis.y.title){
				canvasConverterCtx.drawImage(p.canvas.axis.y.title, 1, 1, p.canvas.axis.y.title.width, p.canvas.axis.y.title.height, 1, 1, p.canvas.axis.y.title.width, p.canvas.axis.y.title.height);
				xw+=p.canvas.axis.y.title.width;
				if(p.canvas.axis.y.ticks){
					xw+=p.canvas.axis.y.ticks.width;
					canvasConverterCtx.drawImage(p.canvas.axis.y.ticks, 1, 1, p.canvas.axis.y.ticks.width, p.canvas.axis.y.ticks.height, p.canvas.axis.y.title.width, 1, p.canvas.axis.y.ticks.width, p.canvas.axis.y.ticks.height);
				}
				canvasConverterCtx.drawImage(p.canvas.main, 0, 0, p.canvas.main.width, p.canvas.main.height, xw, 1, p.canvas.main.width, p.canvas.main.height);
			}else if(p.canvas.axis.y.ticks){
				xw+=p.canvas.axis.y.ticks.width;
				canvasConverterCtx.drawImage(p.canvas.axis.y.ticks, 1, 1, p.canvas.axis.y.ticks.width, p.canvas.axis.y.ticks.height, 1, 1, p.canvas.axis.y.ticks.width, p.canvas.axis.y.ticks.height);
				canvasConverterCtx.drawImage(p.canvas.main, 0, 0, p.canvas.main.width, p.canvas.main.height, p.canvas.axis.y.ticks.width, 1, p.canvas.main.width, p.canvas.main.height);
			}else
				canvasConverterCtx.drawImage(p.canvas.main, 1, 1, p.canvas.main.width, p.canvas.main.height, 1, 1, p.canvas.main.width, p.canvas.main.height);
		}
		if(p.canvas.axis.x){
			if(p.canvas.axis.x.ticks){
				xh+=p.canvas.axis.x.ticks.height;
				canvasConverterCtx.drawImage(p.canvas.axis.x.ticks, 1, 0, p.canvas.axis.x.ticks.width, p.canvas.axis.x.ticks.height, xw+1, p.canvas.main.height, p.canvas.axis.x.ticks.width, p.canvas.axis.x.ticks.height);
				if(p.canvas.axis.x.title)
					canvasConverterCtx.drawImage(p.canvas.axis.x.title, 1, 0, p.canvas.axis.x.title.width, p.canvas.axis.x.title.height, xw+1, xh, p.canvas.axis.x.title.width, p.canvas.axis.x.title.height);
			}else if(p.canvas.axis.x.title)
				canvasConverterCtx.drawImage(p.canvas.axis.x.title, 0, 0, p.canvas.axis.x.title.width, p.canvas.axis.x.title.height, xw, xh, p.canvas.axis.x.title.width, p.canvas.axis.x.title.height);
		}
		var str = canvasConverter.toDataURL();
		$(canvasConverter).parent().remove();
		domObj.css('display','block');
		return str;
	},
	openAsPNG : function(){
		var str = this.convertImage();
		if(str)
			window.open(str);
	},
	saveAsPNG : function(){
		var str = this.convertImage();
		var mime = "application/octet-stream";
		if(str)
			window.location.href = str.replace("image/png", mime);
	}
};
mj.extend(mj.plotter, mj.component);
mj.plotterTree = function(config){
	mj.plotterTree.superclass.constructor.call(this, config);
};
mj.plotterTree.prototype = {
	componentClass : 'mj.plotterTree',
	showXAxisTicks : false,
	showXAxisTitles : false,
	showYAxisTicks : false,
	showYAxisTitles : false,
	overlay : false,
	zoom : true,
	mask : true,
	onlyNegativeZoom : true,
	marginSize : 0,
	minZoomLevel : -5,
	maxZoomLevel : 0,
	treeEvents : function(){
		var eventCanvasObj = $(this.canvas.main);
		var ctx = this.ctx.main,sc=this;
		var x1,y1,x2,y2,px1,py1,px2,py2,le,to;
		le = eventCanvasObj.offset().left;
		to = eventCanvasObj.offset().top;
		var cM = new mj.contextmenu({
			renderTo : mj.NE(),
			parent : eventCanvasObj,
			width : 150,
			items : [
				{id:'_1', title:mj.lng.objects.plotter.openAsPng,iconCls:'mj-opened',scope:this,handler:function(){
					this.openAsPNG();
				}},
				{id:'_2', title:mj.lng.objects.plotter.saveAsPng,iconCls:'mj-save',scope:this,handler:function(){
					this.saveAsPNG();
				}}
			]
		});

		var click = function(e){
			var i=-1;
			while(++i<sc.series.main.length)
				if(typeof sc.series.main[i].fnClick == 'function')
					sc.series.main[i].fnClick(e,le,to,eventCanvasObj);
		};
		eventCanvasObj.bind('click',click);
		eventCanvasObj.bind('mousedown',function(e){
			if(e.which==1){
				sc._dragStarted={x:e.layerX,y:e.layerY};
				sc.cnt.main.style.cursor='url('+mj.glb.imagePath+'pt/closedhand.cur'+'),default;';
			}
		});
		eventCanvasObj.bind('mouseup',function(e){
			sc._dragStarted=false;
			sc.cnt.main.style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
		});
		eventCanvasObj.bind('mouseout',function(e){
			sc._dragStarted=false;
			sc.cnt.main.style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
		});
		eventCanvasObj.bind('mousemove',function(e){
			if(sc._dragStarted){
				sc.cnt.main.scrollLeft += sc._dragStarted.x-e.layerX;
				sc.cnt.main.scrollTop += sc._dragStarted.y-e.layerY;
			}
		});
		eventCanvasObj.mousewheel(function(e, d){
			// if(!sc.onDraw&&sc.drawed&&(e.pageX>le&&e.pageX<eventCanvasObj.width()+le-sc.leftWidth)&&(e.pageY<parseFloat(sc.ctx.main.canvas.height)+to-sc.renderTo[0].scrollTop)){
				if(e.preventDefault)
					e.preventDefault();
				e.returnValue = false;
				var oldLevel = sc.zoomLevel;
				if(sc.onlyNegativeZoom){
					sc.zoomLevel += sc.zoomLevel==0&&d>0?0:d;
					sc.zoomLevel = sc.zoomLevel<sc.minZoomLevel?sc.minZoomLevel:sc.zoomLevel>sc.maxZoomLevel?sc.maxZoomLevel:sc.zoomLevel;
				}
				// if(sc.mask)
					// sc.mask = !sc.mask;
				if(sc.zoomLevel!=oldLevel)
					sc.draw();
				// if(!sc.mask)
					// sc.mask = !sc.mask;
				return false;
			// }
		});
	},
	_init : function(){
		var t = this;
		t.cnt.main.style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
		t.zoomLevel = 0;
		t.treeEvents();
		if(t.mask&&t.store){
			t.maskEl = $(t.cnt.canvasMain);
			t.store.on('beforeload',function(){t.maskEl.css('opacity',t.maskOpacity);t.onDraw = true;});
		}
	}
};
mj.extend(mj.plotterTree, mj.plotter);

mj.plotterSeries = function(config){
	mj.plotterSeries.superclass.constructor.call(this,config);
};
mj.plotterSeries.prototype = {
	componentClass : 'mj.plotterSeries',
	axisGrid : true,
	fill : true,
	color : null,
	fillOpacity : 0.2,
	lineOpacity : 0.8,
	colorOffset : 0,
	orientation : 'v',
	zoom : true,
	shadow : false,
	legend : true,
	visible : true,
	init : function(){},
	dist : function(x0,y0,x1,y1){
		return Math.sqrt(Math.pow(x1 - x0, 2) + Math.pow(y1 - y0, 2));
	},
	getVars : function(){
		var t = this;
		return {
			sc : t.sc,
			data : t.store.data.data, 
			ctx : t.sc.ctx.main, 
			canvas : t.sc.canvas.main, 
			xmin : t.sc.axis.x.min, 
			xmax : t.sc.axis.x.max, 
			ymin : t.sc.axis.y.min, 
			ymax : t.sc.axis.y.max,
			xs : t.sc.axis.x.scale, 
			ys : t.sc.axis.y.scale
		};
	},
	dp : function(x,y,r,o){
		var ctx = this.vars.ctx, sc = this.vars.sc,ymin = this.vars.ymin,xmin = this.vars.xmin,ymax = this.vars.ymax,xmax = this.vars.xmax;
		var px,py;
		r=r?r:2;
		ctx.dashStyle = "solid";
		ctx.lineCap = "round";
		ctx.fillStyle = '#fff';
		ctx.beginPath();
		px = x;
		py = y+(o?o:0);
		ctx.moveTo(px + r, py);
		ctx.arc(px, py, r, 0, o?Math.PI:2 * Math.PI, false);
		ctx.stroke();
	},
	draw : function(){
		var t = this;
		t.vars = t.getVars();
		t.vars.ctx.save();
		t.vars.ctx.lineJoin = "round";
		
		if(t.shadow&&typeof t.fnShadow == 'function')
			t.fnShadow();
		t.color = t.color ? t.color : t.sc.getRandomColor(t.colorOffset);
		t.vars.ctx.strokeStyle = t.vars.sc.parseColor(t.color).scale(null,null,null,t.lineOpacity).toString();
		t.vars.ctx.lineWidth = t.lineWidth;
		
		if(t.fill){
			t.vars.ctx.fillStyle = t.color ? t.vars.sc.parseColor(t.color).scale(null, null, null, t.fillOpacity).toString():t.vars.sc.parseColor(t.color).scale(null, null, null, t.fillOpacity).toString();
			if(typeof t.fnFill == 'function')
				t.fnFill(t.vars.data);
		}
		if(typeof t.fnDraw == 'function')
			t.fnDraw(t.vars.data,0);
		if(t.componentClass == 'mj.plotterSeries.line' && t.lineScatter){
			var cfg = {type:t.lineScatter,shadow:t.shadow,lineOpacity:t.scatterOpacity,scatterWidth:t.scatterWidth,lineWidth:t.lineWidth,color:t.color,sc:t.sc,store:t.store};
			var sc = new mj.plotterSeries.scatter(cfg);
			sc.draw();
		}
		
		if(t.componentClass == 'mj.plotterSeries.scatter')
			switch(t.type){
				case 'box':
					if(typeof t.fnDrawBox == 'function')
						t.fnDrawBox(t.vars.data);
					break;
				case 'point':
					if(typeof t.fnDrawPoint == 'function')
						t.fnDrawPoint(t.vars.data);
					break;
				case 'triangle':
					if(typeof t.fnDrawTriangle == 'function')
						t.fnDrawTriangle(t.vars.data);
					break;
			}
		t.vars.ctx.restore();
	}
};
mj.extend(mj.plotterSeries,mj.component);
mj.plotterTreeSeries = function(config){
	mj.plotterTreeSeries.superclass.constructor.call(this,config);
};
mj.plotterTreeSeries.prototype = {
	componentClass : 'mj.plotterTreeSeries',
	axisGrid : false,
	lineColor : '#343e40',
	fill : true,
	icon : true,
	leafTypeStyle : {
		"1":{color:"#006699",img:mj.glb.imagePath+'pt/mamul.png'},
		"2":{color:"#562380",img:mj.glb.imagePath+'pt/yarimamul.png'},
		"3":{color:"#a0121e",img:mj.glb.imagePath+'pt/hammadde.png'},
		"4":{color:"#a7c843",img:mj.glb.imagePath+'pt/operasyon.png'},
		"5":{color:"#373d11",img:mj.glb.imagePath+'pt/fason.png'},
		"6":{color:"#000",img:mj.glb.imagePath+'pt/sarf.png'},
		"7":{color:"#111",img:mj.glb.imagePath+'pt/imalat.png'},
		"8":{color:"#222",img:mj.glb.imagePath+'pt/isletme.png'}
	},
	lineWidth : 2,
	scatterWidth : 150,
	scatterHeight : 44,
	margins : {
		b:10,
		t:10,
		l:10,
		r:10
	},
	tieLength : 20,
	textLength : 20,
	cornerRadius : 10,
	type : 'box',
	anim : false,
	init : function(){},
	draw : function(){
		var t = this, i = -1;
		t.vars = t.getVars();
		t.corners = [];
		t.subs = [];
		t.infos = [];
		t.nodeDepth = 0;
		var sc = t.vars.sc,data=t.prepData(t.store.data,1);
		
		if(!t._scatterWidth)
			t._scatterWidth = t.scatterWidth;
		else
			t.scatterWidth = t._scatterWidth;
		t.scatterWidth += sc.zoomLevel*3;
		if(!t._scatterHeight)
			t._scatterHeight = t.scatterHeight;
		else
			t.scatterHeight = t._scatterHeight;
		t.scatterHeight += sc.zoomLevel*2;
		if(!t._tieLength)
			t._tieLength = t.tieLength;
		else
			t.tieLength = t._tieLength;
		t.tieLength += sc.zoomLevel*2;
		if(!t._textLength)
			t._textLength = t.textLength;
		else
			t.textLength = t._textLength;
		t.textLength += sc.zoomLevel*.5;
		if(!sc._fontSize)
			sc._fontSize = sc.fontSize;
		else
			sc.fontSize = sc._fontSize;
		sc.fontSize += sc.zoomLevel*.5;
		
		data.depth = t.nodeDepth;
		var olcu = {w:data.depth*(t.scatterWidth+(2*t.tieLength))+t.tieLength,h:data.absChildCount*(t.scatterHeight+t.margins.t+t.margins.b)};
		olcu.h = olcu.h>sc.panel.height?olcu.h:sc.panel.height;
		olcu.w = olcu.w>sc.panel.width?olcu.w:sc.panel.width;
		sc.resize(sc.ctx.main,olcu.w,olcu.h);
		t.vars.ctx.save();
		t.depths = [];
		t.currentNode = data.depth;
		i=-1;
		while(++i<data.depth)
			t.depths.push(0);
		if(data.depth>1||data.collapsed)
			t._draw(data,1);
		if(sc.mask)
			sc.maskEl.css('opacity','1');
		t.vars.ctx.restore();
	},
	drawBox : function(data,p){
		var ctx = this.vars.ctx, sc = this.vars.sc;
		var x,y,w,h;
		var ldID = (data.node==1&&data.data)?data.data[0].leafTypeId:data.leafTypeId;
		ctx.save();
		ctx.dashStyle = "solid";
		ctx.lineCap = 'square';
		ctx.fillStyle = sc.parseColor(data.color||(ldID?this.leafTypeStyle[ldID].color:'#fff')||'#fff' ).scale(null, null, null, data.opacity||this.fillOpacity).toString();
		ctx.strokeStyle = sc.parseColor(data.color||data.lineColor||this.lineColor).scale(null, null, null, data.opacity||1).toString();
		ctx.beginPath();
		var r = this.cornerRadius;
		x = data.x-(data.aIndex?data.aIndex*this.margins.t:0);
		y = data.y+(data.aIndex?data.aIndex*this.margins.t:0);
		w = data.w?data.w:this.scatterWidth;
		h = data.h?data.h:this.scatterHeight;
		data.r = {x:parseInt(x + w),y:parseInt(y + h/2),w:this.tieLength};
		ctx.moveTo(x+r, y);
		ctx.quadraticCurveTo(x, y, x, y+r);
		ctx.lineTo(x, y+h-r);
		ctx.quadraticCurveTo(x, y+h, x+r, y+h);
		ctx.lineTo(x + w - r, y + h);
		ctx.quadraticCurveTo(x+w, y+h, x+w, y+h-r);
		ctx.lineTo(x + w, y+r);
		ctx.quadraticCurveTo(x+w, y, x+w-r, y);
		ctx.closePath();
		ctx.stroke();
		ctx.strokeStyle = sc.parseColor(data.color||this.lineColor).scale(null, null, null, data.opacity||1).toString();
		if(this.fill)
			ctx.fill();
		if(this.icon&&(!data.aIndex||data.selected)&&ldID){
			var img = new Image();
			var elm = {x:parseInt(x+(r/2)),y:parseInt(y+(r/2)),w:16+sc.zoomLevel*1,h:16+sc.zoomLevel*1,data:data};
			this.infos.push(elm);
			data.info = elm;
			img.onload = function(){
				ctx.drawImage(img,data.info.x, data.info.y,16+sc.zoomLevel*1,16+sc.zoomLevel*1);
		    };
			img.src = mj.glb.imagePath+this.leafTypeStyle[ldID].img;
		}
		var str = data.code?data.code:data.data[0].code;
		var sz = sc.fontSize;
		//var len = sc.letters.getLength(sz,str,false);
		sc.drawText(ctx,sz,str.ellipse(this.textLength),x+3+(2*r),y+6+sc.zoomLevel*1.6);
		var fark=0,strl=0; 
		if(data.quantity){
			ctx.save();
			ctx.strokeStyle = sc.parseColor('rgb(255,0,0)').scale(null, null, null, 1).toString();
			str = data.quantity+'*';
			strl = str.length;
			fark = sc.letters.getLength(sz,str,false)+5;
			sc.drawText(ctx,sz,str,x+3+(2*r),y+26+sc.zoomLevel*1.6);
			ctx.restore();
		}
		str = data.inputType=='I'&&data.detail&&data.detail[1]?(data.detail[1].data[0].code+'-'+data.detail[1].data[0].timePerUnit+'-'+data.detail[1].data[0].setupTime):(data.name?data.name:data.data[0].name);
		sc.drawText(ctx,sz,str.ellipse(this.textLength-strl),x+3+fark+(2*r),y+26+sc.zoomLevel*1.6);
		ctx.restore();
		if((data.node>1||data.inputType=='Y')&&(!data.aIndex||data.selected))
			this.drawTies(data,p);
		if(data.collapsed&&this.anim){
			var point = {
				r:{
					x:parseInt(data.r.x-this.scatterWidth-this.tieLength),
					y:parseInt(data.r.y),
					w:parseInt(this.tieLength)
				}
			};
			this.drawTies(point,p);
			var elm = {x:parseInt(point.r.x-(8+sc.zoomLevel*.5)),y:parseInt(point.r.y-(8+sc.zoomLevel*.5)),w:16+sc.zoomLevel*1,h:16+sc.zoomLevel*1,data:data};
			this.corners.push(elm);
			data.corner = elm;
			data.images.img.src = mj.glb.imagePath+'pt/plus.png'
		}
	},
	fnClick : function(e,le,to,obj){
		var cto = $($.browser.msie?obj:e.target).offset();
		var x = e.pageX-cto.left-1, y = e.pageY-cto.top-1;
		var c = this.isCorner(x,y);
		if(c){
			if(c.data.collapsed)
				c.data.collapsed = false;
			else
				c.data.collapsed = true;
			if(typeof this.afterClick == 'function')
				this.afterClick(c.data);
			this.sc.draw();
		}
		if(typeof this._fnClick == 'function')
			this._fnClick(e,x,y);
	},
	isCorner : function(x,y){//+- ikonları
		return this.isIt(this.corners,x,y);
	},
	isSub : function(x,y){//i ikonları
		return this.isIt(this.subs,x,y);
	},
	isInfo : function(x,y){//kutunun belirtici ikonu mamül-fason-hammadde
		return this.isIt(this.infos,x,y);
	},
	isIt : function(arr,x,y){
		var i=-1,f=false,ret=false;
		while(++i<arr.length&&f==false)
			if((arr[i].x<=x)&&(arr[i].x+arr[i].w-3>=x)&&(arr[i].y<=y)&&(arr[i].y+arr[i].h-3>=y)){
				ret=arr[i];
				f=true;
			}
		return ret;
	}
};
mj.extend(mj.plotterTreeSeries,mj.plotterSeries);
mj.plotterSeries.line = function(config){
	mj.plotterSeries.line.superclass.constructor.call(this,config);
};
mj.plotterSeries.line.prototype = {
	componentClass : 'mj.plotterSeries.line',
	scatterWidth : 3,
	fill : false,
	colorOffset : 20,
	lineWidth : 2,
	scatterOpacity : 1,
	shadow : true,
	lineScatter : false,
	trackPoint : false,
	fnDraw : function(data,ofs){
		var x1,y1,fs,ss,px,py;
		var ctx = this.vars.ctx, sc = this.vars.sc,ymin = this.vars.ymin,xmin = this.vars.xmin,ymax = this.vars.ymax,xmax = this.vars.xmax;
		px = sc.th(data[0].x);
		py = sc.tv(data[0].y)+ofs;
		var i = 0;
		ctx.beginPath();
		ctx.moveTo(px, py);
		while(++i<data.length){
			x1 = data[i].x;
			y1 = data[i].y;
			px = sc.th(x1);
			py = sc.tv(y1)+ofs;
			fs = ctx.fillStyle;
			ss = ctx.strokeStyle;
			ctx.lineTo(px, py);
		}
		ctx.stroke();
	},
	fnFill : function(data){
		if(data.length>1){
			var x1,y1,px,py;
			var ctx = this.vars.ctx, sc = this.vars.sc,ymin = this.vars.ymin,xmin = this.vars.xmin,ymax = this.vars.ymax,xmax = this.vars.xmax;
			var bottom = Math.min(Math.max(0, ymin), ymax);
			px = sc.th(data[0].x);
			py = sc.tv(bottom);
			var i = -1;
			ctx.beginPath();
			ctx.moveTo(px, py);
			while(++i<data.length){
				x1 = data[i].x ;
				y1 = data[i].y ;
				px = sc.th(x1);
				py = sc.tv(y1);
				ctx.lineTo(px, py);
			}
			py = sc.tv(bottom);
			ctx.lineTo(px, py);
			ctx.closePath();
			ctx.fill();
		}
	},
	fnShadow : function(){
		var ctx = this.vars.ctx, data = this.vars.data;
		ctx.lineWidth = this.lineWidth + 1;
		ctx.strokeStyle = "rgba(0,0,0,0.1)";
		this.fnDraw(data, 2.5);

		ctx.lineWidth = this.lineWidth + 1;
		ctx.strokeStyle = "rgba(0,0,0,0.2)";
		this.fnDraw(data, 1.5);
	}
};
mj.extend(mj.plotterSeries.line, mj.plotterSeries);

mj.plotterSeries.scatter = function(config){
	mj.plotterSeries.scatter.superclass.constructor.call(this,config);
};
mj.plotterSeries.scatter.prototype = {
	componentClass : 'mj.plotterSeries.scatter',
	fill : false,
	lineWidth : 2,
	scatterWidth : 3,
	type : null,
	fnDrawBox : function(data){
		var t = this, ctx = t.vars.ctx;
		ctx.lineWidth = t.lineWidth;
		if (t.shadow) {
			ctx.strokeStyle = "rgba(0,0,0,0.1)";
			t.drawBox(data, ctx.lineWidth / 2, 2.5);

			ctx.strokeStyle = "rgba(0,0,0,0.2)";
			t.drawBox(data, ctx.lineWidth / 2, 1.5);
		}
		ctx.strokeStyle = t.color ? t.color:sc.parseColor(t.color).scale(null, null, null, t.scatterOpacity).toString();
		t.drawBox(data,(t.scatterWidth+2) / 2);
	},
	drawBox : function(data,ps,o){
		var ctx = this.vars.ctx, sc = this.vars.sc,ymin = this.vars.ymin,xmin = this.vars.xmin,ymax = this.vars.ymax,xmax = this.vars.xmax;
		var px,py;
		ctx.dashStyle = "solid";
		ctx.lineCap = 'square';
		ctx.fillStyle = '#fff';
		ctx.beginPath();
		var j = -1;
		while (++j < data.length) {
			if (data[j].x < xmax) {
				px = sc.th(data[j].x);
				py = sc.tv(data[j].y)+(o?o:0);
				ctx.moveTo(px + ps, py + ps);
				ctx.lineTo(px - ps, py + ps);
				ctx.lineTo(px - ps, py - ps);
				ctx.lineTo(px + ps, py - ps);
				ctx.lineTo(px + ps, py + ps);
			} else {
				break;
			}
		}
		ctx.stroke();
	},
	fnDrawPoint : function(data){
		var t = this, ctx = t.vars.ctx;
		if (t.shadow) {
			ctx.lineWidth = t.lineWidth;
			ctx.strokeStyle = "rgba(0,0,0,0.1)";
			t.drawPoint(data, ctx.lineWidth / 2, 2.5);

			ctx.lineWidth = t.scatterWidth;
			ctx.strokeStyle = "rgba(0,0,0,0.2)";
			t.drawPoint(data, ctx.lineWidth / 2, 1.5);
		}
		ctx.lineWidth = t.scatterWidth;
		ctx.strokeStyle = t.color ? t.color:sc.parseColor(t.color).scale(null, null, null, t.scatterOpacity).toString();
		t.drawPoint(data,t.scatterWidth / 2);
	},
	drawPoint : function(data,r,o){
		var ctx = this.vars.ctx, sc = this.vars.sc,ymin = this.vars.ymin,xmin = this.vars.xmin,ymax = this.vars.ymax,xmax = this.vars.xmax;
		var px,py;
		ctx.dashStyle = "solid";
		ctx.lineCap = "round";
		ctx.fillStyle = '#fff';
		ctx.beginPath();
		var j = -1;
		while (++j < data.length) {
			if (data[j].x < xmax) {
				px = sc.th(data[j].x);
				py = sc.tv(data[j].y)+(o?o:0);
				ctx.moveTo(px + r, py);
				ctx.arc(px, py, r, 0, o?Math.PI:2 * Math.PI, o=='undefined');
			} else {
				break;
			}
		}
		ctx.stroke();
	},
	fnDrawTriangle : function(data){
		var t = this, ctx = t.vars.ctx;
		ctx.lineWidth = t.lineWidth;
		if (t.shadow) {
			ctx.strokeStyle = "rgba(0,0,0,0.1)";
			t.drawTriangle(data, ctx.lineWidth / 2, 2.5);

			ctx.strokeStyle = "rgba(0,0,0,0.2)";
			t.drawTriangle(data, ctx.lineWidth / 2, 1.5);
		}
		ctx.strokeStyle = t.color ? t.color:sc.parseColor(t.color).scale(null, null, null, t.scatterOpacity).toString();
		t.drawTriangle(data,(t.scatterWidth+3) / 2);
	},
	drawTriangle : function(data,ps,o){
		var ctx = this.vars.ctx, sc = this.vars.sc,ymin = this.vars.ymin,xmin = this.vars.xmin,ymax = this.vars.ymax,xmax = this.vars.xmax;
		var px,py;
		ctx.dashStyle = "solid";
		ctx.lineCap = 'square';
		ctx.fillStyle = '#fff';
		ctx.beginPath();
		var j = -1;
		while (++j < data.length) {
			if (data[j].x < xmax) {
				px = sc.th(data[j].x);
				py = sc.tv(data[j].y)+(o?o:0);
				ctx.moveTo(px - ps, py + ps);
				ctx.lineTo(px + ps, py + ps);
				ctx.lineTo(px, py - ps);
				ctx.lineTo(px - ps, py + ps);
			} else {
				break;
			}
		}
		ctx.stroke();
	}
};
mj.extend(mj.plotterSeries.scatter, mj.plotterSeries);

mj.plotterSeries.bar = function(config){
	mj.plotterSeries.bar.superclass.constructor.call(this,config);
};
mj.plotterSeries.bar.prototype = {
	componentClass : 'mj.plotterSeries.bar',
	lineWidth : 1,
	barWidth : 100,
	notScaleHeight : false,
	getWidthScale : false,
	drawBar : function(itemx,p){
		var t = this, ctx = t.vars.ctx, sc = t.vars.sc,ymin = t.vars.ymin,xmin = t.vars.xmin,ymax = t.vars.ymax,xmax = t.vars.xmax;
		var i = -1, vs = t.vars.canvas.height/(ymax-ymin);
		var x = p.x, y = p.y, w = p.w, h = p.h;
		
		var dl = true, dt = true, dr = true, db = true;
		var left = x, right = x + w, bottom = y, top = y + h;
		if (right < xmin || left > xmax || top < ymin || bottom > ymax)
			return;
		if (left < xmin) {
			left = xmin;
			dl = false;
		}

		if (right > xmax) {
			right = xmax;
			dr = false;
		}

		if (bottom < ymin){
			bottom = ymin;
			db = false;
		}

		if (top > ymax) {
			top = ymax;
			dt = false;
		}
		if(itemx.color){
			ctx.fillStyle = t.vars.sc.parseColor(itemx.color).scale(null,null,null,t.fillOpacity).toString();
			ctx.strokeStyle = t.vars.sc.parseColor(itemx.color).scale(null,null,null,t.lineOpacity).toString();
		}else{
			ctx.fillStyle = t.vars.sc.parseColor(t.color).scale(null,null,null,t.fillOpacity).toString();
			ctx.strokeStyle = t.vars.sc.parseColor(t.color).scale(null,null,null,t.lineOpacity).toString();
		}
		if (t.fill) {
			ctx.beginPath();
			ctx.moveTo(t.vars.sc.th(left), t.vars.sc.tv(bottom));
			ctx.lineTo(t.vars.sc.th(left), t.vars.sc.tv(top));
			ctx.lineTo(t.vars.sc.th(right), t.vars.sc.tv(top));
			ctx.lineTo(t.vars.sc.th(right), t.vars.sc.tv(bottom));
			ctx.lineTo(t.vars.sc.th(left), t.vars.sc.tv(bottom));
			ctx.fill();
			// ctx.fillRect (t.vars.sc.th(left), t.vars.sc.tv(bottom), t.vars.sc.th(right)-t.vars.sc.th(left), (t.vars.sc.tv(top)-t.vars.sc.tv(bottom)));
		}
		if(t.lineWidth)
			if (dl || dr || dt || db) {
				ctx.beginPath();
				ctx.moveTo(t.vars.sc.th(left), t.vars.sc.tv(bottom));
				if (dl)
					ctx.lineTo(t.vars.sc.th(left), t.vars.sc.tv(top));
				else
					ctx.moveTo(t.vars.sc.th(left), t.vars.sc.tv(top));
				
				if (dt)
					ctx.lineTo(t.vars.sc.th(right), t.vars.sc.tv(top));
				else
					ctx.moveTo(t.vars.sc.th(right), t.vars.sc.tv(top));
				
				if (dr)
					ctx.lineTo(t.vars.sc.th(right), t.vars.sc.tv(bottom));
				else
					ctx.moveTo(t.vars.sc.th(right), t.vars.sc.tv(bottom));
					
				if (db)
					ctx.lineTo(t.vars.sc.th(left), t.vars.sc.tv(bottom));
				else
					ctx.moveTo(t.vars.sc.th(left), t.vars.sc.tv(bottom));
				ctx.stroke();
			}
	},
	fnDraw : function(data){
		if (data.length < 1)
            return;
		var t = this, ctx = t.vars.ctx, sc = t.vars.sc,ymin = t.vars.ymin,xmin = t.vars.xmin,ymax = t.vars.ymax,xmax = t.vars.xmax;
		var i = -1, vs = t.vars.canvas.height/(ymax-ymin);
		if(t.getWidthScale)
			t.notScaleHeight = true;
		var x,y,w,h,p;
		while(++i<data.length){
			if(t.orientation == 'v')
				x = data[i].x, y = data[i].y, w = data[i].w||t.barWidth, h = data[i].h/(t.notScaleHeight?vs:1);
			else
				x = data[i].y, y = data[i].x, w = data[i].h||t.barWidth, h = data[i].w/(t.notScaleHeight?vs:1);
			p = {x:x,y:y,w:w,h:h};
			t.drawBar(data[i],p);
		}
	}
};
mj.extend(mj.plotterSeries.bar, mj.plotterSeries);

mj.plotterSeries.bar3D = function(config){
	mj.plotterSeries.bar3D.superclass.constructor.call(this,config);
};
mj.plotterSeries.bar3D.prototype = {
	componentClass : 'mj.plotterSeries.bar3D',
	deepLength : 8,
	lineOpacity : .5,
	backLineOpacity : .3,
	fnDraw : function(data){
		if (data.length < 1)
            return;
		var t = this, ctx = t.vars.ctx, sc = t.vars.sc,ymin = t.vars.ymin,xmin = t.vars.xmin,ymax = t.vars.ymax,xmax = t.vars.xmax;
		var i = -1, vs = t.vars.canvas.height/(ymax-ymin), px, py, x1, x2, x3, x4, y1, y2, y3, y4, w, h;
		px = t.deepLength*Math.cos((45).toRadian());
		py = t.deepLength*Math.sin((45).toRadian());
		while(++i<data.length){
			if(t.orientation == 'v'){
				w = data[i].w||t.barWidth, h = data[i].h;
				x1 = data[i].x, x2 = data[i].x+w, x3 = data[i].x+w, x4 = data[i].x;
				y1 = data[i].y, y2 = data[i].y, y3 = data[i].y+h, y4 = data[i].y+h;
			}else{
				w = data[i].h||t.barWidth, h = data[i].w;
				x1 = data[i].y, x2 = data[i].y+w, x3 = data[i].y+w, x4 = data[i].y;
				y1 = data[i].x, y2 = data[i].x, y3 = data[i].x+h, y4 = data[i].x+h;
			}
			ctx.strokeStyle = t.vars.sc.parseColor(t.color).scale(null,null,null,t.lineOpacity).toString();
			ctx.beginPath();
			ctx.moveTo(t.vars.sc.th(x1),t.vars.sc.tv(y1));
			ctx.lineTo(t.vars.sc.th(x2),t.vars.sc.tv(y2));
			ctx.lineTo(t.vars.sc.th(x3),t.vars.sc.tv(y3));
			ctx.lineTo(t.vars.sc.th(x4),t.vars.sc.tv(y4));
			ctx.closePath();
			
			ctx.moveTo(t.vars.sc.th(x3),t.vars.sc.tv(y3));
			ctx.lineTo(t.vars.sc.th(x3+px),t.vars.sc.tv(y3+py));
			ctx.lineTo(t.vars.sc.th(x3+px),t.vars.sc.tv(y3+py-h));
			ctx.lineTo(t.vars.sc.th(x3),t.vars.sc.tv(y3-h));
			
			ctx.moveTo(t.vars.sc.th(x3+px),t.vars.sc.tv(y3+py));
			ctx.lineTo(t.vars.sc.th(x3-w+px),t.vars.sc.tv(y3+py));
			ctx.lineTo(t.vars.sc.th(x4),t.vars.sc.tv(y4));
			ctx.lineTo(t.vars.sc.th(x3),t.vars.sc.tv(y3));
			ctx.fill();
			//ctx.lineWidth = 2;
			ctx.stroke();
			
			ctx.strokeStyle = t.vars.sc.parseColor(t.color).scale(null,null,null,t.backLineOpacity).toString();
			ctx.moveTo(t.vars.sc.th(x1+px),t.vars.sc.tv(y1+py));
			ctx.lineTo(t.vars.sc.th(x1+px),t.vars.sc.tv(y1+py+h));
			ctx.moveTo(t.vars.sc.th(x1+px),t.vars.sc.tv(y1+py));
			ctx.lineTo(t.vars.sc.th(x1+px+w),t.vars.sc.tv(y1+py));
			ctx.moveTo(t.vars.sc.th(x1+px),t.vars.sc.tv(y1+py));
			ctx.lineTo(t.vars.sc.th(x1),t.vars.sc.tv(y1));
			ctx.stroke();
		}
	}
};
mj.extend(mj.plotterSeries.bar3D, mj.plotterSeries.bar);

mj.plotterSeries.range = function(config){
	mj.plotterSeries.range.superclass.constructor.call(this,config);
};
mj.plotterSeries.range.prototype = {
	componentClass : 'mj.plotterSeries.range',
	lineWidth : 0,
	fnDraw : function(data){
		var t = this, ctx = t.vars.ctx, sc = t.vars.sc,ymin = t.vars.ymin,xmin = t.vars.xmin,ymax = t.vars.ymax,xmax = t.vars.xmax;
		var i = -1, vs = t.vars.canvas.height/(ymax-ymin);
		var x,y,w,h;
		while(++i<data.length){
			if(t.orientation == 'v')
				x = data[i].x, y = ymin, w = data[i].w||t.barWidth, h = ymax-ymin;
			else
				y = data[i].x, x = xmin, h = data[i].w||t.barWidth, w = xmax-xmin;
			p = {x:x,y:y,w:w,h:h};
			t.drawBar(data[i],p);
		}
	}
};
mj.extend(mj.plotterSeries.range, mj.plotterSeries.bar);

mj.plotterSeries.pie = function(config){
	mj.plotterSeries.pie.superclass.constructor.call(this,config);
};
mj.plotterSeries.pie.prototype = {
	componentClass : 'mj.plotterSeries.pie',
	axisGrid : false,
	scale : .9,
	fillOpacity : .7,
	position : 'c',
	zoom : false,
	pieces : false,
	sh : 1,//scale height(çizilmesi istenen yüksekliğin % karşılığı çarpan değeri %100 = 1)
	sw : 1,//scale width(çizilmesi istenen genişliğin % karşılığı çarpan değeri %100 = 1)
	fnClick : function(e,pos){
		var sc = this.sc,eventCanvasObj=$(sc.cnt.overlay),c,piece,x0,x1,y0,y1,i=-1,f=false,ff=false;
		if(this.store.data.recordCount == 1)
			return;
		x1 = pos.ix;
		y1 = pos.iy;
		if(!sc.onDraw&&sc.drawed&& (x1>1&&x1<eventCanvasObj.width()) &&(y1>1&&y1<eventCanvasObj.height())){
			c = this.getCenter();
			var a = Math.atan((y1 - c.y) / (x1 - c.x)) + (Math.PI/2);
            if (x1 < c.x)
                a += Math.PI;
            var inc = a / (2*Math.PI);
			var j = -1;
            var cur = 0;
			while(++i<this.pieces.length&&f==false){
				piece = this.pieces[i];
				cur += piece.v;
				// if(piece.o!=0){
					// if(x1>c.x)
						// if(x1<piece.cx){
							// ff=true;
							// continue;
						// }
				// }
				x0 = piece.cx;
				y0 = piece.cy;
				var d = this.dist(x0,y0,x1,y1);
				if(d<=this.r&&(cur/this.sum)>inc&&!ff)
					f=true;
			}
			if(f){
				var old = this.pieces.getIndex('o',1);
				if(old!=-1){
					this.store.data.data[old].offset=0;
					this.pieces[old].o=0;
				}
				this.store.data.data[i-1].offset=1;
				this.pieces[i-1].o=1;
				sc.reDraw();
			}else
				return;
		}
	},
	getCenter : function(){
		var canvas = this.vars.canvas, w = canvas.width, h = canvas.height, w1 = w * this.sw, h1 = h * this.sh, val = {x:w/2,y:h/2};
		switch (this.position) {
	        case "tl":
	            val = {
	                x: w1 * .5,
	                y: h1 * .5
	            };
	            break;
	        case "tc":
	            val = {
	                x: w / 2,
	                y: h1 * .5
	            };
	            break;
	        case "tr":
	            val = {
	                x: w - w1 * .5,
	                y: h1 * .5
	            };
	            break;
	        case "cl":
	            val = {
	                x: w1 * .5,
	                y: h / 2
	            };
	            break;
	        case "cr":
	            val = {
	                x: w - w1 * .5,
	                y: h / 2
	            };
	            break;
	        case "bl":
	            val = {
	                x: w1 * .5,
	                y: h - h1 * .5
	            };
	            break;
	        case "bc":
	            val = {
	                x: w / 2,
	                y: h - h1 * .3
	            };
	            break;
	        case "br":
	            val = {
	                x: w - w1 * .5,
	                y: h - h1 * .5
	            };
	            break;
	        default://'c'
	            val = {
	                x: w / 2,
	                y: h / 2
	            }
        }
        return val;
	},
	getRadius : function(){
		return Math.floor(Math.min(this.vars.canvas.width*this.sw, this.vars.canvas.height*this.sh)*this.scale) / 2;
	},
	drawPiece : function(ctx, x, y, r, c, v, op, i, d){
		var s_ang = (2*Math.PI*c)-Math.PI/2;
		var e_ang = (2*Math.PI*(c + v))-Math.PI/2;
		var d_ang = e_ang-((e_ang-s_ang)/2);
		if(typeof d.offset != 'undefined' && parseFloat(d.offset)>0){
			y += Math.sin(d_ang) * (parseFloat(d.offset)*r*.1);
			x += Math.cos(d_ang) * (parseFloat(d.offset)*r*.1);
		}
		var item = {sa:s_ang,ea:e_ang,a:d_ang,cx:x,cy:y,dr:r,v:d.x,o:typeof d.offset != 'undefined'?d.offset:0};
		this.pieces.push(item);
		ctx.beginPath();
		ctx.moveTo(x, y);
		ctx.arc(x, y, r, s_ang, e_ang, false);
		ctx.lineTo(x, y);
		ctx.closePath();
		ctx.fillStyle = this.vars.sc.parseColor(d.color||this.vars.sc._colors[i]).scale(null, null, null, op).toString() ;
		ctx.fill();
	},
	draw : function(){
		var t = this;
		t.pieces = [];
		t.vars = t.getVars();
		t.r = t.getRadius();
		if(!t.pos)
			t.pos = t.getCenter();
		t.current = 0;
		t.sum = 0;
		var i = -1, pVal = 0, ctx = t.vars.ctx;
		while(++i<t.vars.data.length)
			t.sum += t.vars.data[i].x;
		i = -1;
		while(++i<t.vars.data.length){
			pVal = t.vars.data[i].x / t.sum;
			t.drawPiece(ctx,t.pos.x,t.pos.y,t.r,t.current,pVal,t.fillOpacity,i,t.vars.data[i]);
			t.current += pVal;
		}
	}
};
mj.extend(mj.plotterSeries.pie, mj.plotterSeries);

mj.plotterSeries.pie3D = function(config){
	mj.plotterSeries.pie3D.superclass.constructor.call(this,config);
};
mj.plotterSeries.pie3D.prototype = {
	componentClass : 'mj.plotterSeries.pie3D',
	deepLength : 20,
	bottomOpacity : .6,
	sideOpacity : .8,
	fnClick : function(e,pos){
		var sc = this.sc,eventCanvasObj=$(sc.cnt.overlay),c,piece,x0,x1,y0,y1,i=-1,f=false,ff=false,pc=this.pos,pp={};
		if(this.store.data.recordCount == 1)
			return;
		x1 = pos.ix;
		y1 = pos.iy;
		if(!sc.onDraw&&sc.drawed&& (x1>1&&x1<eventCanvasObj.width()) &&(y1>1&&y1<eventCanvasObj.height())){
			c = this.getCenter();
			pp.eg =  (y1 - c.y) / (x1 - c.x);
			pp.a0orj = Math.atan(pp.eg);
			pp.a0 = pp.a0orj + (Math.PI/2);
           	
			pp.rx = (c.x0-c.x1)/2;
			pp.ry = (c.y0-c.y1)/2;
			pp.a1orj = Math.atan((pp.ry*Math.sin(pp.a0))/(pp.rx*Math.cos(pp.a0)));
			pp.a1 = pp.a1orj + (Math.PI/2);
			if(y1 > c.y)
				pp.a1 += Math.PI;
			
			pp.x = (pp.rx*Math.cos(pp.a1));
			pp.y = (pp.ry*Math.sin(pp.a1));
			if(x1>c.x&&y1<c.y)
				pp.oa = pp.a1orj;
			if(y1>c.y)
				pp.oa = pp.a1-(Math.PI/2);
			if(x1<c.x&&y1<c.y)
				pp.oa = pp.a1+3*(Math.PI/2);
			var inc = pp.oa / (2*Math.PI);
			var j = -1;
            var cur = 0;
			while(++i<this.pieces.length&&f==false){
				piece = this.pieces[i];
				cur += piece.v;
				x0 = piece.cx;
				y0 = piece.cy;
				var d = this.dist(x0,y0,x1,y1),d2 = this.dist(pp.x+c.x,pp.y+c.y,x0,y0);	
				if(d<=d2&&(cur/this.sum)>inc&&!ff)
					f=true;
			}
			if(f){
				var old = this.pieces.getIndex('o',1);
				if(old!=-1){
					this.store.data.data[old].offset=0;
					this.pieces[old].o=0;
				}
				this.store.data.data[i-1].offset=1;
				this.pieces[i-1].o=1;
				sc.reDraw();
			}else
				return;
		}
	},
	getCenter : function(){
		var canvas = this.vars.canvas, w = canvas.width, h = canvas.height, w1 = w * this.sw, h1 = h * this.sh, val = {x:w/2,y:h/2};
		//center dışındakiler düzenlenecek
		switch (this.position) {
	        case "tl":
	            val = {
	                x: w1 * .5,
	                y: h1 * .5
	            };
	            break;
	        case "tc":
	            val = {
	                x: w / 2,
	                y: h1 * .5
	            };
	            break;
	        case "tr":
	            val = {
	                x: w - w1 * .5,
	                y: h1 * .5
	            };
	            break;
	        case "cl":
	            val = {
	                x: w1 * .5,
	                y: h / 2
	            };
	            break;
	        case "cr":
	            val = {
	                x: w - w1 * .5,
	                y: h / 2
	            };
	            break;
	        case "bl":
	            val = {
	                x: w1 * .5,
	                y: h - h1 * .5
	            };
	            break;
	        case "bc":
	            val = {
	                x: w / 2,
	                y: h - h1 * .5
	            };
	            break;
	        case "br":
	            val = {
	                x: w - w1 * .5,
	                y: h - h1 * .5
	            };
	            break;
	        default://'c'
	            val = {
					x: w / 2,
	                y: h / 2,
	                x0: w - (w1*this.scale),
	                y0: h - (h1*this.scale-3*this.deepLength),
					x1: w1*this.scale,
	                y1: h1*this.scale-3*this.deepLength,
					x2: w - (w1*this.scale),
	                y2: h - (h1*this.scale-5*this.deepLength),
					x3: w1*this.scale,
	                y3: h1*this.scale-this.deepLength
	            }
        }
        return val;
	},
	drawPiece : function(ctx, pc, c, v, op, i, d, side, addPiece){
		var s_ang = (2*Math.PI*c)-Math.PI/2;
		var e_ang = (2*Math.PI*(c + v))-Math.PI/2;
		var d_ang = e_ang-((e_ang-s_ang)/2);
		
		if(typeof d.offset != 'undefined' && parseFloat(d.offset)>0){
			pc.cy -= Math.sin(d_ang) * (parseFloat(d.offset)*pc.ry*.2);
			pc.cx -= Math.cos(d_ang) * (parseFloat(d.offset)*pc.rx*.2);
		}
		if(addPiece){
			var item = {sa:s_ang,ea:e_ang,a:d_ang,cx:pc.cx,cy:pc.cy,v:d.x,o:typeof d.offset != 'undefined'?d.offset:0};
			this.pieces.push(item);
		}
		var inc = 3;
		if(side!='s'){
			var sd = (c*360)+1;
			var ed = ((c + v)*360)+1;
			var pp = {};
			
			ctx.beginPath();
			while(sd<ed){
				pp.ang0 = (sd).toRadian()+Math.PI/2;
				pp.x0 = pc.rx*Math.cos(pp.ang0);
				pp.y0 = pc.ry*Math.sin(pp.ang0);
				pp.a0 = Math.pow(pc.ry,2)/pp.y0;
				pp.b0 = (pp.x0*Math.pow(pc.ry,2))/(pp.y0*Math.pow(pc.rx,2));
				
				pp.ang1 = (sd+inc).toRadian()+Math.PI/2;
				pp.x1 = pc.rx*Math.cos(pp.ang1);
				pp.y1 = pc.ry*Math.sin(pp.ang1);
				pp.a1 = Math.pow(pc.ry,2)/pp.y1;
				pp.b1 = (pp.x1*Math.pow(pc.ry,2))/(pp.y1*Math.pow(pc.rx,2));
				
				pp.x = (pp.a0-pp.a1)/(pp.b0-pp.b1);
				pp.y = pp.a0 - (pp.b0*pp.x);
				
				ctx.moveTo(pc.cx,pc.cy);
				ctx.lineTo(pp.x0+pc.cx,pp.y0+pc.cy);
				if(typeof pp.px0 == 'undefined' || typeof pp.py0 == 'undefined'){
					pp.px0 = pp.x0+pc.cx;
					pp.py0 = pp.y0+pc.cy;
				}
				ctx.quadraticCurveTo(pp.x+pc.cx, pp.y+pc.cy,  pp.x1+pc.cx,pp.y1+pc.cy);
				ctx.lineTo(pc.cx,pc.cy);
				sd+=inc;
			}
			ctx.closePath();
			ctx.fillStyle = this.vars.sc.parseColor(d.color||this.vars.sc._colors[i]).scale(null, null, null, op).toString() ;
			ctx.fill();
		}
		if(side == 'b'){
			ctx.strokeStyle = this.vars.sc.parseColor(d.color||this.vars.sc._colors[i]).scale(null, null, null, 1).toString() ;
			ctx.fillStyle = this.vars.sc.parseColor(d.color||this.vars.sc._colors[i]).scale(null, null, null, op).toString() ;
			ctx.beginPath();
			ctx.moveTo(pc.cx,pc.cy);
			ctx.lineTo(pp.px0,pp.py0);
			ctx.lineTo(pp.px0,pp.py0-2*this.deepLength);
			ctx.lineTo(pc.cx,pc.cy-2*this.deepLength);
			ctx.closePath();
			ctx.fill();
			ctx.stroke();
			
			ctx.beginPath();
			ctx.moveTo(pc.cx,pc.cy);
			ctx.lineTo(pp.x1+pc.cx,pp.y1+pc.cy);
			ctx.lineTo(pp.x1+pc.cx,pp.y1+pc.cy-2*this.deepLength);
			ctx.lineTo(pc.cx,pc.cy-2*this.deepLength);
			ctx.closePath();
			ctx.fill();
			ctx.stroke();
		}
		if(side == 's'){
			var sd = (c*360)+1;
			var ed = ((c + v)*360)+1;
			var pp = {};
		
			ctx.beginPath();
			while(sd<ed){
				pp.ang0 = (sd).toRadian()+Math.PI/2;
				pp.x0 = pc.rx*Math.cos(pp.ang0);
				pp.y0 = pc.ry*Math.sin(pp.ang0);
				pp.a0 = Math.pow(pc.ry,2)/pp.y0;
				pp.b0 = (pp.x0*Math.pow(pc.ry,2))/(pp.y0*Math.pow(pc.rx,2));
				
				pp.ang1 = (sd+inc).toRadian()+Math.PI/2;
				pp.x1 = pc.rx*Math.cos(pp.ang1);
				pp.y1 = pc.ry*Math.sin(pp.ang1);
				pp.a1 = Math.pow(pc.ry,2)/pp.y1;
				pp.b1 = (pp.x1*Math.pow(pc.ry,2))/(pp.y1*Math.pow(pc.rx,2));
				
				pp.x = (pp.a0-pp.a1)/(pp.b0-pp.b1);
				pp.y = pp.a0 - (pp.b0*pp.x);
				
				ctx.moveTo(pp.x0+pc.cx,pp.y0+pc.cy);
				ctx.quadraticCurveTo(pp.x+pc.cx, pp.y+pc.cy,  pp.x1+pc.cx,pp.y1+pc.cy);
				ctx.lineTo(pp.x1+pc.cx,pp.y1+pc.cy-2*this.deepLength);
				ctx.quadraticCurveTo(pp.x+pc.cx, pp.y+pc.cy-2*this.deepLength,  pp.x0+pc.cx,pp.y0+pc.cy-2*this.deepLength);
				ctx.lineTo(pp.x0+pc.cx,pp.y0+pc.cy);
				sd+=inc;
			}
			ctx.closePath();
			ctx.fillStyle = this.vars.sc.parseColor(d.color||this.vars.sc._colors[i]).scale(null, null, null, op).toString() ;
			ctx.fill();
		}
	},
	draw : function(){
		var t = this;
		t.pieces = [];
		t.vars = t.getVars();
		if(!t.pos)
			t.pos = t.getCenter();
		t.pos.k = 4 * ((Math.sqrt(2) -1) / 3);
		
		t.current = 0;
		t.sum = 0;
		var i = -1, pVal = 0, ctx = t.vars.ctx;
		while(++i<t.vars.data.length)
			t.sum += t.vars.data[i].x;
		i = -1;
		while(++i<t.vars.data.length){
			pVal = t.vars.data[i].x / t.sum;
			//alt
			t.pos.rx = (t.pos.x2-t.pos.x3)/2;
			t.pos.ry = (t.pos.y2-t.pos.y3)/2;
			t.pos.cx = t.pos.x3+t.pos.rx;
			t.pos.cy = t.pos.y3+t.pos.ry;
			t.drawPiece(ctx,t.pos,t.current,pVal,t.bottomOpacity,i,t.vars.data[i],'b',false);
			t.current += pVal;
		}
		t.current = 0;
		i = -1;
		while(++i<t.vars.data.length){
			pVal = t.vars.data[i].x / t.sum;
			//yan
			t.pos.rx = (t.pos.x2-t.pos.x3)/2;
			t.pos.ry = (t.pos.y2-t.pos.y3)/2;
			t.pos.cx = t.pos.x3+t.pos.rx;
			t.pos.cy = t.pos.y3+t.pos.ry;
			t.drawPiece(ctx,t.pos,t.current,pVal,t.sideOpacity,i,t.vars.data[i],'s',false);
			t.current += pVal;
		}
		t.current = 0;
		i = -1;
		while(++i<t.vars.data.length){
			pVal = t.vars.data[i].x / t.sum;
			//üst
			t.pos.rx = (t.pos.x0-t.pos.x1)/2;
			t.pos.ry = (t.pos.y0-t.pos.y1)/2;
			t.pos.cx = t.pos.x1+t.pos.rx;
			t.pos.cy = t.pos.y1+t.pos.ry;
			t.drawPiece(ctx,t.pos,t.current,pVal,t.fillOpacity,i,t.vars.data[i],'t',true);
			t.current += pVal;
		}
	}
};
mj.extend(mj.plotterSeries.pie3D, mj.plotterSeries.pie);

mj.plotterSeries.gauge = function(config){
	mj.plotterSeries.gauge.superclass.constructor.call(this,config);
};
mj.plotterSeries.gauge.prototype = {
	componentClass : 'mj.plotterSeries.gauge',
	start : 180,
	range : 180,
	min : 0,
	max : 100,
	autoFindMax : false,
	scale : .8,
	centerOpacity : .3,
	fillOpacity : .3,
	needleOpacity : .5,
	rangeOpacity : .4,
	fillColor : '#fff',
	rangeColor : '#ccc',
	centerColor : '#fff',
	needleColor : '#f00',
	needleRadius : 110,
	rangeWidth : 30,
	needleRangeDiff : 20,
	needleWidth : 3,
	centerWidth : 100,
	tickCount : 11,
	majorTickStepDivisor : 1,
	minorTickStepDivisor : 5,
	tickCorrectorMin : 1,
	tickCorrectorMax : 10,
	getScaledValue : function(val){
		return this.start + ((val - this.min)/(this.max - this.min) * this.range);
	},
	drawTick : function(ctx, x, y, r, c, w, l, cormin, cormax){
		var x1, x2, y1, y2;
		x1 = x + (r-cormin)*Math.cos((c).toRadian());
		y1 = y + (r-cormin)*Math.sin((c).toRadian());
		x2 = x + (r-w+cormax)*Math.cos((c).toRadian());
		y2 = y + (r-w+cormax)*Math.sin((c).toRadian());
		ctx.lineWidth = l;
		ctx.moveTo(x1,y1);
		ctx.lineTo(x2,y2);
	},
	fillBackGround : function(ctx, x, y, r, s, rng, color,op){
		// sadece range area içini boyama kısmı
		// var x1,y1,p;
		// ctx.beginPath();
		// p = this.getScaledValue(s);
		// x1 = x + (r)*Math.cos((p).toRadian());
		// y1 = y + (r)*Math.sin((p).toRadian());
		// ctx.moveTo(x, y);
		// ctx.arc(x, y, r, (s).toRadian(), (s+rng).toRadian(), false);
		// ctx.lineTo(x, y);
		// ctx.closePath();
		ctx.beginPath();
		ctx.moveTo(0, 0);
		ctx.lineTo(ctx.canvas.width, 0);
		ctx.lineTo(ctx.canvas.width, ctx.canvas.height);
		ctx.lineTo(0, ctx.canvas.height);
		ctx.closePath();
		ctx.fillStyle = this.vars.sc.parseColor(color).scale(null, null, null, op).toString() ;
		ctx.fill();
	},
	drawRangeArea : function(ctx, x, y, r, s, rng, w, color,op){
		var x1,y1,p;
		ctx.beginPath();
		p = this.getScaledValue(s);
		x1 = x + (r)*Math.cos((p).toRadian());
		y1 = y + (r)*Math.sin((p).toRadian());
		ctx.moveTo(x, y);
		ctx.arc(x, y, r, (s).toRadian(), (s+rng).toRadian(), false);
		ctx.arc(x, y, (r-w), (s+rng).toRadian(), (s).toRadian(), true);
		ctx.closePath();
		ctx.fillStyle = this.vars.sc.parseColor(color).scale(null, null, null, op).toString();
		ctx.fill();
	},
	drawRanges : function(i){
		var t=this,ctx=t.vars.ctx,x1,y1;
		ctx.beginPath();
		t.curPos = t.getScaledValue(t.ranges[i].min);
		x1 = t.pos.x + (t.r)*Math.cos((t.curPos).toRadian());
		y1 = t.pos.y + (t.r)*Math.sin((t.curPos).toRadian());
		ctx.moveTo(x1,y1);
		ctx.arc(t.pos.x, t.pos.y, t.r, (t.getScaledValue(t.ranges[i].min)).toRadian(), (t.getScaledValue(t.ranges[i].max)).toRadian(), false);
		ctx.arc(t.pos.x, t.pos.y, (t.r-t.rangeWidth), (t.getScaledValue(t.ranges[i].max)).toRadian(), (t.getScaledValue(t.ranges[i].min)).toRadian(), true);
		ctx.closePath();
		ctx.fillStyle = t.vars.sc.parseColor(t.ranges[i].color).scale(null, null, null, t.rangeOpacity).toString();
		ctx.fill();
	},
	drawNeedle : function(data,count,idx,mll){
		var t=this,ctx=t.vars.ctx,x1,x2,x3,y1,y2,y3;
		var c, i =-1, l, slen, mx, la = false, sz = t.sc.tickSize,mg=sz/25;
		t.needleRadius = t.needleRadius<=t.centerWidth+t.needleRangeDiff?t.needleRadius:t.centerWidth+t.needleRangeDiff;
		t.current = t.getScaledValue(data.x);
		// classic needle draw
		// valR = (t.current-90).toRadian();
		// ctx.beginPath();
		// x1 = t.pos.x + (t.centerWidth)*Math.cos(valR);
		// y1 = t.pos.y + (t.centerWidth)*Math.sin(valR);
		// x2 = t.pos.x + (t.r)*Math.cos((t.current).toRadian());
		// y2 = t.pos.y + (t.r)*Math.sin((t.current).toRadian());
		// x3 = t.pos.x - (t.centerWidth)*Math.cos(valR);
		// y3 = t.pos.y - (t.centerWidth)*Math.sin(valR);
		// ctx.moveTo(t.pos.x, t.pos.y);
		// ctx.lineTo(x1,y1);
		// ctx.lineTo(x2,y2);
		// ctx.lineTo(x3,y3);
		// ctx.closePath();
		// ctx.fillStyle = t.vars.sc.parseColor(data.color||t.needleColor).scale(null, null, null, t.needleOpacity).toString() ;
		// ctx.fill();
		
		x1 = t.pos.x + (t.r)*Math.cos((t.current).toRadian());
		y1 = t.pos.y + (t.r)*Math.sin((t.current).toRadian());
		ctx.beginPath();
		ctx.arc(t.pos.x,t.pos.y,t.needleRadius,(t.current-t.needleWidth).toRadian(),(t.current+t.needleWidth).toRadian(), false);
		ctx.lineTo(x1,y1);
		ctx.closePath();
		ctx.fillStyle = t.vars.sc.parseColor(data.color||t.needleColor).scale(null, null, null, t.needleOpacity).toString() ;
		ctx.fill();
		
		var ch, f, j, k, s, slen;
		ctx.save();
		if(data.label)
			if(t.sc.fontMap){
				slen = t.sc.letters.getLength(sz,data.label,false);
				la = slen instanceof Array;
				mx = la?t.sc.maxVal(slen):slen;
				l = la?slen[0]:slen;
				s = data.label.split(''), j = s.length;
				x1 = x3 = (typeof data.px != 'undefined'?parseInt(data.px):t.pos.x) - mll/2;
				y1 = y3 =(typeof data.py != 'undefined'?parseInt(data.py) + idx*(35*mg)*(la?slen.length:1):t.pos.y - (count-idx)*mg*(la?slen.length*35:35));
				y1 += data.py?0:80;
				ctx.beginPath();
				ctx.moveTo(x1-12,y1+2);
				ctx.lineTo(x1-3,y1+2);
				ctx.lineTo(x1-3,y1+(35*mg));
				ctx.lineTo(x1-12,y1+(35*mg));
				ctx.closePath();
				ctx.fill();
				ctx.save();
				ctx.strokeStyle = '#000000';
				while(++i<j)
					if(c=t.sc.letters.get(s[i])){
						y1 += i==0?(la?10:25)*mg:0;
						t.sc.letters.drawChar(ctx,sz,c,x1,y1,false);
						if(s[i+1]!='\n')
							x1+=c.width*mg;
					}else if(s[i]=='\n'){
						x1 = x3;
						y1+=35*mg;
					}
				ctx.restore();
			}else{
				f = t.sc.images.h;
				slen = t.sc.getStringLength(data.label,f.c,f.w,false);
				j = -1;
				s = data.label.toString().split(''), k = s.length;
				x1 = (typeof data.px != 'undefined'?parseInt(data.px):t.pos.x) - mll/2;
				y1 = (typeof data.py != 'undefined'?parseInt(data.py) + idx*(f.h+1):t.pos.y - (count-idx)*(f.h+1));
				ctx.beginPath();
				ctx.moveTo(x1-12,y1+2);
				ctx.lineTo(x1-3,y1+2);
				ctx.lineTo(x1-3,y1+f.h+1);
				ctx.lineTo(x1-12,y1+f.h+1);
				ctx.closePath();
				ctx.fill();
				while(++j<k)
					if((ch=f.c.indexOf(s[j]))>=0){
						x1 = Math.floor(x1);
						y1 = Math.floor(y1);
						ctx.drawImage(f,f.f[ch],0,f.w[ch],f.h,x1,y1,f.w[ch],f.h);
						x1+=f.w[ch];
					}
			}
		
		ctx.restore();
	},
	draw : function(){
		var t = this, i, j;
		var x1, x2, x3, y1, y2, y3, f, slen, ch, s;
		var mx, la = false, sz = t.sc.tickSize,mg=sz/25,fh;
		t.vars = t.getVars();
		var ctx = t.vars.ctx;
		t.current = 0;
		t.r = t.getRadius();
		t.centerWidth = t.centerWidth>t.r-(t.rangeWidth+t.needleRangeDiff)?t.r-(t.rangeWidth+t.needleRangeDiff):t.centerWidth;
		if(!t.pos)
			t.pos = t.getCenter();
		for (i = t.start; i <= (t.start + t.range); i++) {
			j = i;
			if (j >= 360) j = j - 360;
			if (j == 0) t.vars.ymax = t.r;
			if (j == 90) t.vars.xmax = t.r;
			if (j == 180) t.vars.ymin = 0 - t.r;
			if (j == 270) t.vars.xmin = 0 - t.r;
		}
		
		//autoFindMax
		if(this.autoFindMax){
			i = 0;
			var arr = this.sc._gTicks;
			while (arr[i] > this.autoFindMax) 
				i++;
			t.max = arr[i-1];
			var tr = t.ranges.length,minmax = t.max/(tr-1), step = (t.max/(tr-1))/(tr-1);
			i = tr;
			while(--i>-1)
				if(i==0){
					t.ranges[i].max = t.max-(t.max/(tr-1));
					t.ranges[i].min = 0;
				}else{
					t.ranges[i].max = t.max+(step*(i-(tr-1)));
					t.ranges[i].min = t.ranges[i].max - step;
				}
		}
		
		//major ticks
		t.tickStep = (t.max-t.min)/(t.tickCount-1);
		t.curTick = 0;
		t.curMinTick = 0;
		t.curPos = 0;
		t.curMinPos = 0;
		i = -1;
		while(++i<t.tickCount){
			t.curPos = t.getScaledValue(t.curTick);
			t.drawTick(ctx,t.pos.x,t.pos.y,t.r,t.curPos,t.rangeWidth,2,t.tickCorrectorMin,t.tickCorrectorMin);
			t.curTick += t.tickStep;
		}
		ctx.strokeStyle = 'rgba(0,0,0,1)';
		ctx.stroke();
		
		//tick labels
		i = -1;
		t.curTick = 0;
		t.curPos = 0;
		x1 = 0;
		y1 = 0;
		ctx.save();
		ctx.strokeStyle = '#000000';
		while(++i<t.tickCount){
			if(t.sc.fontMap){
				slen = t.sc.letters.getLength(sz,t.curTick.toString(),false);
				fh=5;
			}else{
				f = t.sc.images.h;
				slen = t.sc.getStringLength(t.curTick.toString(),f.c,f.w,false);
				fh = f.h;
			}
			t.direction = true;
			t.rev = false;
			t.curPos = t.getScaledValue(t.curTick);
			t.curPos = t.curPos%360;
			j = -1;
			s = t.curTick.toString().split(''), k = s.length;
			x1 = t.pos.x + (t.r)*Math.cos((t.curPos).toRadian());
			y1 = t.pos.y + (t.r)*Math.sin((t.curPos).toRadian());
			if(t.curPos>=90&&t.curPos<180){
				t.direction = false;
				x1 += t.curPos==90?slen/2:1;
				y1-=((fh/2)-5);
				y1 += t.sc.fontMap?7:0;
				if(!t.rev){
					s = s.reverse();
					t.rev = true;
				}
			}else if(t.curPos>=180&&t.curPos<270){
				t.direction = false;
				y1-=(fh-3);
				if(!t.rev){
					s = s.reverse();
					t.rev = true;
				}
			}else if(t.curPos>=270&&t.curPos<360){
				x1 -= t.curPos==270?slen/2:0;
				y1 -= (fh-(t.curPos==270?0:3));
			}else if(t.curPos>=0&&t.curPos<90){
				y1 -= t.curPos==0?fh/2:1;
				y1 += t.sc.fontMap?9:0;
			}
			if(x1!=0&&y1!=0)
				while(++j<k){
					if(t.sc.fontMap){
						if(ch=t.sc.letters.get(s[j])){
							x1 = Math.floor(x1);
							y1 = Math.floor(y1);
							if(!t.direction)
								x1-=ch.width*mg;
							t.sc.letters.drawChar(ctx,sz,ch,x1,y1,false);
							if(t.direction)
								x1+=ch.width*mg;
						}
					}else{
						if((ch=f.c.indexOf(s[j]))>=0){
							x1 = Math.floor(x1);
							y1 = Math.floor(y1);
							if(!t.direction)
								x1-=f.w[ch];
							ctx.drawImage(f,f.f[ch],0,f.w[ch],f.h,x1,y1,f.w[ch],f.h);
							if(t.direction)
								x1+=f.w[ch];
						}
					}
				}
			if(t.rev)
				s = s.reverse();
			t.curTick += t.tickStep;
		}
		ctx.restore();
		//minor ticks
		i = -1;
		while(++i<t.tickCount-1){
			t.curMinTick += (t.tickStep/t.minorTickStepDivisor);
			j = -1;
			while(++j<4){
				t.curMinPos = t.getScaledValue(t.curMinTick);
				t.drawTick(ctx,t.pos.x,t.pos.y,t.r,t.curMinPos,t.rangeWidth,1,t.tickCorrectorMin,t.tickCorrectorMax);
				t.curMinTick += (t.tickStep/t.minorTickStepDivisor);
			}
		}
		ctx.stroke();
		ctx.strokeStyle = 'rgba(0,0,0,0)';
		
		//fill background
		if(t.fill)
			t.fillBackGround(ctx,t.pos.x,t.pos.y,t.r,t.start,t.range,t.fillColor,t.fillOpacity);
		
		//range area
		t.drawRangeArea(ctx,t.pos.x,t.pos.y,t.r,t.start,t.range,t.rangeWidth,t.rangeColor,t.rangeOpacity);
		
		//ranges
		i = -1;
		while(++i<t.ranges.length)
			t.drawRanges(i);
		
		//needle draw
		var data = t.vars.data, val, valR, sr, er, f, maxLen=[], maxLabelLength;
		if(t.sc.fontMap){
			i = -1;
			while(++i<data.length){
				slen = t.sc.letters.getLength(sz,data[i].label,false);
				la = slen instanceof Array;
				mx = la?t.sc.maxVal(slen):slen;
				maxLen.push({x:data[i].x,len:mx});
			}
			maxLabelLength = t.vars.sc.maxObjVal(maxLen,'len');
		}else{
			i = -1;
			f = t.sc.images.h;
			while(++i<data.length)
				maxLen.push({x:data[i].x,len:t.sc.getStringLength(data[i].label,f.c,f.w,false)});
			maxLabelLength = t.vars.sc.maxObjVal(maxLen,'len');
		}
		
		i = -1;
		while(++i<data.length)
			t.drawNeedle(data[i],data.length,i,maxLabelLength);
		
		//needle center
		ctx.beginPath();
		ctx.arc(t.pos.x, t.pos.y, t.centerWidth, 0, 2*Math.PI, false);
		ctx.closePath();
		ctx.fillStyle = t.vars.sc.parseColor(t.centerColor).scale(null, null, null, t.centerOpacity).toString() ;
		ctx.fill();
		
	}
};
mj.extend(mj.plotterSeries.gauge, mj.plotterSeries.pie);

mj.plotterTreeSeries.treeElements = function(config){
	mj.plotterTreeSeries.treeElements.superclass.constructor.call(this,config);
};
mj.plotterTreeSeries.treeElements.prototype = {
	componentClass : 'mj.plotterTreeSeries.treeElements',
	corners : false,
	subs : false,
	infos : false,
	nodeDepth : 0,
	currentNode : 0,
	depths : false,
	init : function(){},
	prepData : function(d,c){
		var i = -1;
		if(!d.images)
			d.images = {};
		if(d.detail&&d.detail[0]){
			var l = mj.oLength(d.detail[0].data);
			d.node=c++;
			d.childCount=l;
			d.absChildCount = 0;
			if(!d.collapsed||!this.anim)
				while(++i<l){
					this.prepData(d.detail[0].data[i],c);
					d.absChildCount+=d.detail[0].data[i].absChildCount;
					d.detail[0].data[i].nodeIndex = i;
					if(d.childCount>1){
						d.detail[0].data[i].isFirst = i==0;
						d.detail[0].data[i].isLast = i==l-1;
					}else
						d.detail[0].data[i].isFirst = d.detail[0].data[i].isLast = false;
				}
			else
				d.absChildCount = 1;
		}else{
			d.node=c;
			d.childCount = 0;
			d.absChildCount = 1;
		}
		this.nodeDepth=d.node>this.nodeDepth?d.node:this.nodeDepth;
		return d;
	},
	_draw : function(d,c){
		var ctx = this.vars.ctx, sc = this.vars.sc;
		var i = -1;
		var df = false;
		if(d.detail&&d.detail[0]){
			var j = d.node-1;
			var l = mj.oLength(d.detail[0].data);
			if(!d.collapsed){//?
				while(++i<l)
					this._draw(d.detail[0].data[i],c);
				this.currentNode--;
			}else
				this.currentNode = d.node;
		}
		for(var j=0;j<this.nodeDepth;j++)
			this.depths[j] += this.anim ? ((d.childCount==0 || d.collapsed) ? 1 : 0) : (d.childCount==0 ? 1 : (d.collapsed ? d.absChildCount : 0));
		if(d.node == this.currentNode){
			if(d.childCount>0&&(!d.collapsed||!this.anim)){//?
				var ny = this.drawTieBinds(d.detail[0].data,d);
				d.top = (d.detail[0].data[0].top + mj.oLength(d.detail[0].data) - 1) / 2;
				d.y = parseInt(ny);
			}else{
				d.top = this.depths[this.currentNode-1]-1;
				d.y = parseInt(d.top*(this.scatterHeight+this.margins.b+this.margins.t)+this.margins.t);
			}
			df=true;
		}else if(d.childCount==0){
			this.currentNode = d.node;
			d.top = this.depths[this.currentNode-1]-1;
			d.y = parseInt(d.top*(this.scatterHeight+this.margins.b+this.margins.t)+this.margins.t);
			df=true;
		}
		if(df){
			d.x = parseInt((this.nodeDepth-d.node)*(2*this.tieLength+(this.scatterWidth))+this.margins.l+this.tieLength);
			if(d.detail&&d.detail[1]){
				var elm = {x:parseInt(d.x-8+this.scatterWidth),y:parseInt(d.y-8+this.scatterHeight/2),w:16,h:16,data:d};
				this.subs.push(elm);
				d.sub = elm;
				//this.dp(elm.x,elm.y,2);
				if(!d.images.imgSub){
					d.images.imgSub = new Image();
					d.images.imgSub.onload = function(){
						ctx.drawImage(d.images.imgSub,d.sub.x, d.sub.y,16,16);
					};
				}
				d.images.imgSub.src = mj.glb.imagePath+'pt/application_cascade.png';
				// var obj=d.detail[1].data,i=-1,l=mj.oLength(obj);
				// while(++i<l){
					// var dd = obj[i];
					// dd.node=d.node;
					// dd.aIndex=i+1;
					// dd.x=d.x;dd.y=d.y;dd.h=d.h;dd.w=d.w;dd.opacity=.2;dd.selected=false;
					// this.drawBox(dd);
				// }
			}
			this.drawBox(d);
		}
		return d;
	},
	drawTies : function(data){
		var ctx = this.vars.ctx, sc = this.vars.sc;
		var x,y,w;
		x = data.r.x;
		y = data.r.y;
		w = data.r.w;
		ctx.save();
		ctx.strokeStyle = sc.parseColor(data.color||'#343e40').scale(null, null, null, .5).toString();
		ctx.beginPath();
		ctx.moveTo(x, y);
		if(data.isFirst){
			ctx.lineTo(x + w-this.cornerRadius, y);
			ctx.lineWidth = this.lineWidth;
			ctx.quadraticCurveTo(x+w, y,x+w,y+this.cornerRadius);
		}else if(data.isLast){
			ctx.lineTo(x + w-this.cornerRadius, y);
			ctx.lineWidth = this.lineWidth;
			ctx.quadraticCurveTo(x+w, y,x+w,y-this.cornerRadius);
		}else{
			ctx.lineTo(x + w, y);
			ctx.closePath();
		}
		ctx.stroke();
		ctx.restore();
	},
	drawTieBinds : function(data,d){
		var ctx = this.vars.ctx, sc = this.vars.sc;
		var x,y,w;
		var j = -1,f=false,lx=false,l=mj.oLength(data);
		ctx.strokeStyle = sc.parseColor(data.color||'#343e40').scale(null, null, null, .5).toString();
		ctx.beginPath();
		while(++j<l){
			x = data[j].r.x;
			y = data[j].r.y;
			w = data[j].r.w;
			if(!f){
				ctx.moveTo(x+w,y+this.cornerRadius);
				f=y;
			}else
				ctx.lineTo(x+w,y-this.cornerRadius);
		}
		lx=y;
		ctx.closePath();
		if(!d.collapsed||this.anim)
			ctx.stroke();
		
		d.images.img = new Image();
		d.images.img.onload = function(){
			ctx.drawImage(d.images.img,d.corner.x, d.corner.y,16+sc.zoomLevel*1,16+sc.zoomLevel*1);
		};
		var elm = {x:parseInt(x+w-(8+sc.zoomLevel*.5)),y:parseInt(f+((lx-f)/2)-(8+sc.zoomLevel*.5)),w:16+sc.zoomLevel*1,h:16+sc.zoomLevel*1,data:d};
		this.corners.push(elm);
		d.corner = elm;
		if(!d.collapsed)
			d.images.img.src = mj.glb.imagePath+'pt/minus.png';
		else
			d.images.img.src = mj.glb.imagePath+'pt/plus.png';
		this.drawTies({r:{x:parseInt(x+w),y:parseInt(f+((lx-f)/2)),w:w}});
		return f+((lx-f)/2)-this.scatterHeight/2;
	}
};
mj.extend(mj.plotterTreeSeries.treeElements, mj.plotterTreeSeries);
mj.plotterTreeSeries.productTree = function(config){
	mj.plotterTreeSeries.productTree.superclass.constructor.call(this,config);
};
mj.plotterTreeSeries.productTree.prototype = {
	componentClass : 'mj.plotterTreeSeries.productTree',
	init : function(){
		var t = this;
		t.view3DXMLCode = '';
		t.wins = {
			alternate : new mj.window({
							renderTo : mj.NE(),
							title : '',
							width : 700,
							height : 300,
							resizable : false,
							modal : true
						}),
			info : new mj.window({
							renderTo : mj.NE(),
							title : '',
							width : 700,
							height : 400,
							maximizable : true,
							resizable : true,
							modal : true,
							buttons : [
								{title:mj.lng.glb.exit,sc:t,handler:function(){
									this.sc.wins.info.hide();
								}},
								{title:mj.lng.objects.plotter.getTree,disabled:true,sc:t,handler:function(){
									var tree = this.sc.sc;
									tree.store.params.id = this.sc.grids.info.kullanim.selectedRow.data.id;
									tree.load();
									this.sc.wins.info.hide();
								}}
							]
						})
		};
		t.stores = {
			alternate : new mj.store({data:''}),
			info : {
				bilgi : new mj.store({
					url : t.sc.store.url,
					params : {
						event : 'getDataBilgi'
					}
				}),
				kullanim : new mj.store({
						url : t.sc.store.url,
						params : {
							event : 'getDataKullanilanYer'
						}
					})
			},
			tree : new mj.store({
				url : t.sc.store.url,
				params : {
					event : 'getproductTree'
				}
			})
		};
		t.panels = {
			alternate : new mj.panel({renderTo : t.wins.alternate.getBody()}),
			info : new mj.panel({renderTo : t.wins.info.getBody()})
		};
		t.tabPanels = {
			alternate : new mj.tab({
						renderTo : t.panels.alternate.getBody(),
						activeTab : 0,
						border : false,
						hideHeader : true,
						tabWidth : 120,
						maxTitle : 12,
						items :[
							{
								title: '1',
								iconCls:'tabs',
								closable:false
							},{
								title: '2',
								iconCls:'tabs',
								closable:false
							}
						]
					}),
			info : new mj.tab({
						renderTo : t.panels.info.getBody(),
						activeTab : 0,
						border : false,
						tabWidth : 140,
						maxTitle : 15,
						items :[
							{
								title: mj.lng.objects.plotter.itemInfo,
								iconCls:'tabs',
								closable:false
							},{
								title: mj.lng.objects.plotter.usage,
								iconCls:'tabs',
								closable:false
							},{
								title: mj.lng.objects.plotter.xmlView,
								iconCls:'tabs',
								closable:false
							}
						]
			})
		};
		t.tabs = { 
			alternate : {
				op : t.tabPanels.alternate.tabs[0],
				hm : t.tabPanels.alternate.tabs[1]
			},
			info : {
				bilgi : t.tabPanels.info.tabs[0],
				kullanimMain : t.tabPanels.info.tabs[1],
				view : t.tabPanels.info.tabs[2]
			}
		};
		// t.tabs.info.view.getBody().append("<object type='application/x-3dxmlplugin' width='100%' height='100%' style='MARGIN: 0px' border='0'><param name='DocumentFile' value=''></object>");
		// t.view3DXMLObj = $('object',t.tabs.info.view.getBody())[0];
		t.tabPanels.kullanim = new mj.tab({
			renderTo : t.tabs.info.kullanimMain.getBody(),
			innerTab : t.tabPanels.info,
			activeTab : 0,
			tabPosition:'bottom',
			border:false,
			items:[
				{
					title: mj.lng.glb.records,
					closable:false
				},
				{
					title: mj.lng.objects.plotter.showTree,
					disabled : true,
					closable:false
				}
			]
		});
		t.tabs.info.kullanim = t.tabPanels.kullanim.tabs[0];
		t.tabs.info.agac = t.tabPanels.kullanim.tabs[1];
		var pltLng = mj.lng.objects.plotter;
		t.grids = {	
					alternate : {
						aOp : new mj.grid({
									renderTo : t.tabs.alternate.op.getBody(),
									store : t.stores.alternate,
									pbar : new mj.pager({pos:'bottom',limit:25}),
									fitToParent : true,
									contextMenuWidth : 150,
									cm : [
										{header: pltLng.isDefault, dataIndex: 'isDefault', width: 80,renderer:function(val){return '<center><div class="mj-checkbox '+(val==1?'mj-checkbox-checked':'')+'" style="height:16px;float:none;"></div></center>';}},
										{header: pltLng.station, dataIndex: 'station', width: 100},
										{header: pltLng.maxDelay, dataIndex: 'maxDelay', width: 100, align : 'right'},
										{header: pltLng.operatorCount, dataIndex: 'operatorCount', width: 100, align : 'right'},
										{header: pltLng.setupTime, dataIndex: 'setupTime', width: 100, align : 'right'},
										{header: pltLng.timePerUnit, dataIndex: 'timePerUnit', width: 110, align : 'right'},
										{header: pltLng.receteNotu, dataIndex: 'receteNotu', width: 310}										
									]
								}),
						aHm : new mj.grid({
									renderTo : t.tabs.alternate.hm.getBody(),
									store : new mj.store({data:[]}),
									pbar : new mj.pager({pos:'bottom',limit:25}),
									fitToParent : true,
									cm : [
										{header: pltLng.id, dataIndex: 'id', width: 60, align : 'right'},
										{header: pltLng._id, dataIndex: '_id', width: 60, align : 'right'},
										{header: pltLng.isDefault, dataIndex: 'isDefault', width: 80,renderer:function(val){return '<center><div class="mj-checkbox '+(val==1?'mj-checkbox-checked':'')+'" style="height:16px;float:none;"></div></center>';}},
										{header: pltLng.code, dataIndex: 'code', width: 200}
									]
								})
					},
					info : {
						bilgi : new mj.grid({
							renderTo : t.tabs.info.bilgi.getBody(),
							store : t.stores.info.bilgi,
							pbar : new mj.pager({pos:'bottom',limit:25}),
							fitToParent : true,
							cm :[
								{header: pltLng.id, dataIndex: 'id', width: 60, align : 'right'},
								{header: pltLng._id, dataIndex: '_id', width: 60, align : 'right'},
								{header: pltLng.code, dataIndex: 'code', width: 200},
								{header: pltLng.name, dataIndex: 'name', width: 250},
								{header: pltLng.quantity, dataIndex: 'miktar', width: 70, align : 'right'},
								{header: pltLng.birim, dataIndex: 'birim', width: 70},
								{header: pltLng.type, dataIndex: 'tipi', width: 100}
							]
						}),
						kullanim : new mj.grid({
							adi : 'myGrid',
							renderTo : t.tabs.info.kullanim.getBody(),
							store : t.stores.info.kullanim,
							pbar : new mj.pager({pos:'bottom',limit:25}),
							fitToParent : true,
							cm : [
								{header: pltLng.id, dataIndex: 'id', width: 60, align : 'right'},
								{header: pltLng._id, dataIndex: '_id', width: 60, align : 'right'},
								{header: pltLng.code, dataIndex: 'code', width: 200},
								{header: pltLng.name, dataIndex: 'name', width: 250},
								{header: pltLng.type, dataIndex: 'tipi', width: 100},
								{header: pltLng.boxContent, dataIndex: 'boxContent', width: 70, align : 'right'},
								{header: pltLng.profit, dataIndex: 'profitContent', width: 70, align : 'right'},
								{header: pltLng.stock, dataIndex: 'miktar', width: 70, align : 'right'}
							]
						})
					}
		};
		t.plotterTrees = {
			tree : new mj.plotterTree({
				renderTo : t.tabs.info.agac.getBody(),
				store : t.stores.tree,
				backgroundColor : '#eee',
				resizable : true,
				fontMap : true,
				border : false,
				fontSize : 8,
				marginSize : 0
			})
		};
		t.plotterTrees.tree.on('load',function(){
			this.series.main=[];
			//this.addSeries(new mj.plotterTreeSeries.productTree({store : this.store.data,anim:true,sc:this}));
			this.addSeries(new mj.plotterTreeSeries.productTree({store : this.store.data,anim:true,sc:this,fnClick:false}));
			this.draw();
		});
		t.grids.alternate.aHm.on('rowdblclick',function(g,s){
			var node = this.getNodeFromPath(this.nodePath);
			var sr = mj.cloneObject(g.selectedRow.data,'_');
			var tmp = {};
			mj.apply(tmp,node.detail[1]);
			delete node.detail[0];
			mj.apply(node,sr);
			if(!node.detail[0])
				delete node.collapsed;
			node.detail[1]=tmp;
			this.draw();
			this.wins.alternate.hide();
		},t);
		t.tabPanels.info.on('tabchange',function(scope,n,o){
			if(o==1&&n==0){//bilgi
				this.grids.info.bilgi.load();
				if(!this.wins.info.buttons[1].disabled)
					this.plotterTrees.tree.clear();
			}else if(o==0&&n==1){//kullanılan yer
				this.tabPanels.kullanim.setActive(0);
				this.tabs.info.agac.setDisable();
				this.wins.info.buttons[1].setDisable();
				this.grids.info.kullanim.load();
			}else if(n==2){
				t.tabs.info.view.getBody().empty();
				t.tabs.info.view.getBody().append("<object type='application/x-3dxmlplugin' width='100%' height='100%' style='MARGIN: 0px' border='0'><param name='DocumentFile' value='"+mj.glb.xml3D+t.view3DXMLCode+".3dxml'></object>");
			}
				// t.view3DXMLObj.DocumentFile = mj.glb.xml3D+t.view3DXMLCode+'.3dxml';
		},t);
		t.grids.info.kullanim.on('rowdblclick',function(g,s){
			this.tabs.info.agac.setEnable();
			this.wins.info.buttons[1].setEnable();
			this.tabPanels.kullanim.setActive(1);
			this.plotterTrees.tree.store.params.id = g.selectedRow.data.id;
			this.plotterTrees.tree.load();
		},t);
		t.tabPanels.kullanim.on('tabchange',function(scope,n,o){
			if(o==1&&n==0){
				this.tabs.info.agac.setDisable();
				this.wins.info.buttons[1].setDisable();	
			}
		},t);
	},
	prepData : function(d,c,p,idx){
		var i = -1;
		if(!d.images)
			d.images = {};
		d.path = p?p.path+(p.path!=''?'|':'')+idx:'';
		if(d.detail&&d.detail[0]){
			var l = mj.oLength(d.detail[0].data);
			d.node = c;
			if(c==1)
				mj.apply(d,d.data[0]);
			c+=mj.getIndex(d.detail[0].data,'leafTypeId',4)>-1?2:1;
			d.childCount=l;
			d.absChildCount = 0;
			if(!d.collapsed||!this.anim){
				var pEl,el,nEl;
				var lt4First = false,lt4Last = false,sChange=false;
				var sira = d.detail[0].data[0]._sira;
				while(++i<l){
					el = d.detail[0].data[i];
					el.parent = d;
					if(el.parent.isDefault == 0 && el.parent.path !== '')
						el.isDefault = 0;
					this.prepData(el,c,d,i);
					el.nodeIndex = i;
					if(d.childCount>1){
						pEl = d.detail[0].data[i-1];
						nEl = d.detail[0].data[i+1];
						el.prev = pEl;
						el.next = nEl;
						if(sira!=el._sira){
							sira = el._sira;
							sChange = true;
						}
						if((i==0&&nEl&&nEl.leafTypeId!=4)||(sChange&&nEl&&nEl.leafTypeId!=4))
							el.isFirst = el.leafTypeId!=4;
						
						if(el.leafTypeId!=4&&el.isFirst)
							el.closed = false;
						
						if(pEl&&pEl.leafTypeId!=4&&nEl&&nEl.leafTypeId==4&&!sChange)
							el.isLast = el.leafTypeId!=4;
						
						if(!lt4First&&typeof el.isFirst=='undefined'&&el.leafTypeId==4&&pEl&&(pEl.leafTypeId!=4&&pEl.inputType!='Y')){
							el.isFirst = true;
							el.absChildCount = 0;
							lt4First = true;
						}						
						
						if(typeof el.isLast=='undefined')
							el.isLast = i==l-1;
						if(sChange){
							sChange = false;
							lt4First = false;
						}
					}else
						el.isFirst = el.isLast = false;
					d.absChildCount+=el.absChildCount;
				}
			}
			else{
				d.absChildCount = 1;
				if(d.leafTypeId!=4&&d.isFirst)
					d.closed = false;
			}
		}else{
			d.node= d.inputType=='Y'?c-2:c;
			d.childCount = 0;
			d.absChildCount = (d.inputType=='Y'||(d.leafTypeId==4&&d.isFirst))?0:1;
		}
		this.nodeDepth=d.node>this.nodeDepth?d.node:this.nodeDepth;
		return d;
	},	
	_draw : function(d,c,p,clr){
		var ctx = this.vars.ctx, sc = this.vars.sc;
		var i = -1;
		var df = false;
		if(d.detail&&d.detail[0]){
			var j = d.node-1;
			var l = mj.oLength(d.detail[0].data);
			if(!d.collapsed){//?
					//this._draw(d.detail[0].data[i],c,d.detail[0].data,d.detail[1]&&d.isDefault==0);
				while(++i<l)
					this._draw(d.detail[0].data[i],c,d.detail[0].data);
				this.currentNode-=mj.getIndex(d.detail[0].data,'leafTypeId',4)>-1?2:1;
			}else
				this.currentNode = d.node;
		}
		for(var j=0;j<this.nodeDepth;j++)
			this.depths[j] += 
				this.anim 
					? ((d.childCount==0 || d.collapsed) 
						? (d.inputType=='Y'||(d.leafTypeId==4&&d.isFirst)?0:1) 
						: 0) 
					: (d.childCount==0 
						? (d.inputType=='Y'||(d.leafTypeId==4&&d.isFirst)?0:1) 
						: (d.collapsed ? d.absChildCount : 0)
					);
		if(d.node == this.currentNode){
			if(d.childCount>0&&(!d.collapsed||!this.anim)){//?
				var ny = this.drawTieBinds(d.detail[0].data,d,p);
				d.top = (d.detail[0].data[0].top + mj.oLength(d.detail[0].data) - 1) / 2;
				d.y = parseInt(ny);
			}else{
				d.top = this.depths[this.currentNode-1]-1;
				d.y = parseInt(d.top*(this.scatterHeight+this.margins.b+this.margins.t)+this.margins.t);
			}
			df=true;
		}else if(d.childCount==0){
			this.currentNode = d.node;
			d.top = this.depths[this.currentNode-1]-1;
			d.y = parseInt(d.top*(this.scatterHeight+this.margins.b+this.margins.t)+this.margins.t);
			df=true;
		}
		if(df){
			d.x = parseInt((this.nodeDepth-d.node)*(2*this.tieLength+(this.scatterWidth))+this.margins.l+this.tieLength+(d.leafTypeId == 4?(2*this.tieLength+(this.scatterWidth)):0));
			var r = this.cornerRadius;
			if(d.detail&&d.detail[1]){
				var elm = {x:parseInt(d.x+(r/2)),y:parseInt(d.y+16+r+sc.zoomLevel*1),w:16+sc.zoomLevel*1,h:16+sc.zoomLevel*1,data:d};
				this.subs.push(elm);
				d.sub = elm;
				//this.dp(elm.x,elm.y,2);
				if(!d.images.imgSub){
					d.images.imgSub = new Image();
					d.images.imgSub.onload = function(){
						ctx.drawImage(d.images.imgSub,d.sub.x, d.sub.y,16+sc.zoomLevel*1,16+sc.zoomLevel*1);
					};
				}
				d.images.imgSub.src = mj.glb.imagePath+'pt/information.png';
			}
			//if(d.detail&&d.detail[1]&&d.isDefault==0||clr)
			if(d.isDefault==0)
				d.lineColor = '#f00';
			else
				delete d.lineColor;
			this.drawBox(d,p);
		}
		return d;
	},
	drawTies : function(data,p){
		var ctx = this.vars.ctx, sc = this.vars.sc;
		var x,y,w;
		x = data.r.x;
		y = data.r.y;
		w = data.r.w;
		var px=x-(this.scatterWidth/2),py=y-(this.scatterHeight/2);
		ctx.save();
		ctx.strokeStyle = sc.parseColor(data.color||'#343e40').scale(null, null, null, .5).toString();
		ctx.beginPath();
		ctx.moveTo(x, y);
		if(data.leafTypeId==4){
			if(data.isFirst){
				ctx.moveTo(x-this.scatterWidth-w, y);
				ctx.lineTo(x -this.scatterWidth, y);
				ctx.lineTo(x -this.scatterWidth-w, y);
			}
			if(data.isLast || data.next.inputType=='Y'){
				ctx.moveTo(x,y);
				ctx.lineTo(x+this.tieLength,y);
				ctx.lineTo(x,y);
			}
			var i=parseInt(data.nodeIndex),f=false,elIdx;
			while(--i>-1&&!f)
				if(p[i].leafTypeId==4){
					elIdx = i;
					f = true;
				}
			if(f){
				ctx.moveTo(px,py);
				ctx.lineTo(px,p[elIdx].y+this.scatterHeight);
				ctx.lineTo(px,py);
			}
		}else{
			if(data.inputType=='Y'){
				ctx.moveTo(x-this.scatterWidth-w, y);
				ctx.lineTo(x -this.scatterWidth, y);
				ctx.lineTo(x -this.scatterWidth-w, y);
			}else if(data.isFirst){
				// ctx.lineTo(x + w-this.cornerRadius, y);
				// ctx.lineWidth = this.lineWidth;
				// ctx.quadraticCurveTo(x+w, y,x+w,y+this.cornerRadius);
				ctx.lineTo(x + w, y);
				ctx.lineTo(x , y);
			}else if(data.isLast){
				// ctx.lineTo(x + w-this.cornerRadius, y);
				// ctx.lineWidth = this.lineWidth;
				// ctx.quadraticCurveTo(x+w, y,x+w,y-this.cornerRadius);
				ctx.moveTo(x+w,y);
				ctx.lineTo(x , y);
				ctx.lineTo(x + w, y);
				var ilk = mj.getIndex(p,'closed',false);
				if(ilk>-1){
					var el = p[ilk];
					delete el.closed;
					ctx.lineTo(el.r.x+el.r.w , el.r.y);
					ctx.lineTo(x + w, y);
				}
			}else{
				ctx.lineTo(x + w, y);
				ctx.closePath();
			}
		}
		
		ctx.stroke();
		ctx.restore();
	},
	drawTieBinds : function(data,d,p){
		var ctx = this.vars.ctx, sc = this.vars.sc;
		var x,y,w;
		var j = -1,f=false,lx=false,l=mj.oLength(data);
		ctx.strokeStyle = sc.parseColor(data.color||'#343e40').scale(null, null, null, .5).toString();
		ctx.beginPath();

		x = data[l-1].r.x;
		y = lx = f = data[l-1].r.y;
		w = data[l-1].r.w;
		
		d.images.img = new Image();
		d.images.img.onload = function(){
			ctx.drawImage(d.images.img,d.corner.x, d.corner.y,16+sc.zoomLevel*1,16+sc.zoomLevel*1);
		};
		var elm = {x:parseInt(x+w-(8+sc.zoomLevel*.5)),y:parseInt(f+((lx-f)/2)-(8+sc.zoomLevel*.5)),w:16+sc.zoomLevel*1,h:16+sc.zoomLevel*1,data:d};
		this.corners.push(elm);
		d.corner = elm;
		if(!d.collapsed)
			d.images.img.src = mj.glb.imagePath+'pt/minus.png';
		else
			d.images.img.src = mj.glb.imagePath+'pt/plus.png';
		this.drawTies({r:{x:parseInt(x+w),y:parseInt(f+((lx-f)/2)),w:w}},p);
		return f+((lx-f)/2)-this.scatterHeight/2;
	},
	afterClick : function(el){
		if(el.leafTypeId!=4&&el.isFirst)
			el.closed=false;
	},
	_fnClick : function(e,x,y){
		var s = this.isSub(x,y), pltLng = mj.lng.objects.plotter;
		if(s){
			var w = this.wins.alternate;
			if(s.data.leafTypeId==4){
				if(s.data.detail[1].data.length>1)
					w.setTitle(pltLng.altOperation);
				else
					w.setTitle(pltLng.infoOperation);
				this.stores.alternate.data = s.data.detail[1].data;
				this.grids.alternate.aOp.load();
				w.show();
				this.tabPanels.alternate.setActive(0);
			}else{
				this.nodePath=s.data.path;
				w.setTitle(pltLng.altMaterial);
				this.grids.alternate.aHm.store.data = s.data.detail[1].data;
				this.grids.alternate.aHm.load();
				w.show();
				this.tabPanels.alternate.setActive(1);
			}
		}
		var inf = this.isInfo(x,y);
		if(inf&&inf.data.leafTypeId!=4){
			var w = this.wins.info;
			this.view3DXMLCode = inf.data.code.toString().replace(/ /g,'_');
			w.setTitle(pltLng.infoItem+inf.data.code);
			this.grids.info.kullanim.store.params.id = inf.data.leafId||-1;
			this.grids.info.bilgi.store.params.id = inf.data.leafId||-1;
			this.grids.info.kullanim.store.params.tID = inf.data.id||-1;
			this.grids.info.bilgi.store.params.tID = inf.data.id||-1;
			w.show();
			// this.tabPanels.info.setActive(1);
			// this.tabPanels.kullanim.setActive(0);
			// this.grids.info.kullanim.load();
			this.tabPanels.info.setActive(0);
			this.grids.info.bilgi.load();
		}
	},
	getNodeFromPath : function(path){
		var pre = 'this.store.data',tmp = '.detail[0].data[x]';
		var ta = path.split('|'),i=-1,str='';
		while(++i<ta.length)
			str+=tmp.replace('x',ta[i]);
		return eval(pre+str);
	}
};
mj.extend(mj.plotterTreeSeries.productTree, mj.plotterTreeSeries.treeElements);
mj.desktop = function(config){
	mj.desktop.superclass.constructor.call(this, config);
};
mj.desktop.prototype = {
	componentClass : 'mj.desktop',
	position : 'bottom',
	initTabWidth : 150,
	background : '#fff',
	contextMenu : true,
	fishEye : false,
	multipleWindow : false,
	helpPath : false,
	showSystemTray : false,
	deskIconTpl : new mj.template(['<div class="desktop-icon" id="deskItem-{id}" style="position:absolute;{positionStyle}">',
				'<table><tr><td align="center"><div class=""><img id="img-{id}" src="{deskIcon}" style="z-index:0;" title="{title}"></div></td></tr>',
				'<tr><td align="center"><span id="span-{id}"  class="x-editable">{title}</span></td></tr></table></div>']),
	QLIconTpl : new mj.template('<div class="quick-launch-item" id="QLItem-{id}"><img id="ql-img-{id}" src="{QLIcon}" title="{title}"></div>'),
	render : function(){
		var t=this;
		
		if(t.position=='top'){
			t.tBarCnt = mj.NE(t.renderTo,{tag:'div', cls:'mj-desktop-taskbar-top'});
			t.body = mj.NE(t.renderTo,{tag:'div',cls:'mj-desktop-body mj-resize-handle',style:'background:'+t.background+';overflow:auto;width:'+(t.renderTo.width())+'px;height:'+(t.renderTo.height()-28)+'px;'});
		}else if(t.position=='bottom'){
			t.body = mj.NE(t.renderTo,{tag:'div',cls:'mj-desktop-body mj-resize-handle',style:'background:'+t.background+';overflow:auto;width:'+(t.renderTo.width())+'px;height:'+(t.renderTo.height()-28)+'px;'});
			t.tBarCnt = mj.NE(t.renderTo,{tag:'div', cls:'mj-desktop-taskbar-bottom'});
		} 
		t.tBarMenu = mj.NE(t.tBarCnt,{tag:'div', cls:'mj-desktop-taskbar-menu'});
		t.tBarQL = mj.NE(t.tBarCnt,{tag:'div', cls:'mj-desktop-taskbar-ql'});
		t.tBarTab = mj.NE(t.tBarCnt,{tag:'div', cls:'mj-desktop-taskbar-tab'});
		if(t.showSystemTray){
			t.tBarRA = mj.NE(t.tBarCnt,{tag:'div', cls:'mj-desktop-taskbar-ra'});
			mj.loading = $(mj.NE(t.tBarRA, {cls:'mj-desktop-taskbar-loader'}));
		}
		t.tabContainerWidth = t.renderTo.width()-310;
		var ofs=$(t.tBarQL).offset();
		width=$(t.tBarQL).width();
		height=$(t.tBarQL).height();
		ofs.right = ofs.left + width;
		ofs.bottom = ofs.top + height;

		$().mousemove(function(e){
			if(window.mjDragging){
	            x=e.clientX;
				y=e.clientY;
				if( x>= ofs.left &&x <= ofs.right &&y >= ofs.top &&y <= ofs.bottom){
					$(t.tBarQL).addClass('mj-ql-hover');
					t.onQL=true;
				} 		
				else {
					$(t.tBarQL).removeClass('mj-ql-hover');
					t.onQL=false;
				}
			}
		});

		t.tBarSD = mj.NE(t.tBarQL,{tag:'div', cls:'mj-desktop-taskbar-show-desktop'});
		$(t.tBarSD).bind('click',{scope:t},function(e){
			var s = e.data.scope;
			if(s.beforeSD.length>0){
				for(var i=0,len=s.beforeSD.length;i<len;i++)
					s.windows[s.beforeSD[i]].window.show();
				s.beforeSD=[];	
			}else{
				while(s.winHistory.length>0){
					s.beforeSD.push(s.winHistory[0]);
					s.windows[s.winHistory[0]].window.minimize();		
				}
			
			}
		});
		
		if(t.menuItems){
			mj.apply(t.menuItems,{renderTo:t.tBarMenu,drag : true});
			t.menu = new mj.menu(t.menuItems);
			t.menu.on('itemclick',t._menuItemClick,t);
			t.menu.on('beforedrag',function(d,e,b){
				return !b.subMenu;
			},this);
			t.menu.on('dragstop',function(e,b){
				if(mj.getIndex(this.desktopItems,'id',b.id)==-1){
					var el = $(this.menu.activeSub?this.menu.activeSub._el:b.renderTo);
					var reg=el.offset();
					reg.right=reg.left + el.width();
					reg.bottom=reg.top + el.height();
					var t=parseInt(e.proxy[0].style.top),l=parseInt(e.proxy[0].style.left);
					if(l<reg.left||l>reg.right||t<reg.rop||t>reg.bottom){
						var str = 'top:'+t+'px;left:'+l+'px;'
						var x = this.getMenuItemById(this.menuItems.items,b.id);
						x.positionStyle = str;
						if(x)
							this.desktopItems.push(x)
						this.addDesktopIcon(this.desktopItems.length-1,x);				
						setCookie('deskItem-'+b.id,str,365,'/');
					}
				}
			},this);
		
		}
		if(t.desktopItems){
			var cookieIcons=getCookieArray('deskItem-');
			for(var i=0,len = cookieIcons.length;i<len;i++){
				var x = cookieIcons[i].replace('deskItem-','').trim();
				t.desktopItems.remove(x);
				t.desktopItems.push(x);
			}
		
			for(var i = 0, len = t.desktopItems.length; i < len; i++){
				var x = t.getMenuItemById(t.menuItems.items,t.desktopItems[i]);
				if(x)
					t.desktopItems[i] = x;
			}
			t.showDesktopIcon();
		}
		if(t.QLItems){
			var QLIcons=getCookieArray('QLItem-');
			for(var i=0,len = QLIcons.length;i<len;i++){
				var x = QLIcons[i].replace('QLItem-','').trim();
				t.QLItems.remove(x);
				t.QLItems.push(x);
			}
			for(var i = 0, len = t.QLItems.length; i < len; i++){
				var x = t.getMenuItemById(t.menuItems.items,t.QLItems[i]);
				if(x)
					t.QLItems[i] = x;
			}
			t.showQLIcon();
		}
		if(t.fishEye)
			t.addFishEyeMenu();
		var bgCook=getCookie('backgroundImage');
		if(bgCook)
			this.changeBackground(bgCook);
		$(this.body).bind('contextmenu',{scope : this},function(e){
			if($(e.target).hasClass('mj-desktop-body')){
				var tb = new mj.menu({
					renderTo : mj.NE(),
					canHide : true,
					style : 'vertical',
					width : 170,
					items : [
						{id:'_1', title:'Masaüstü Değiştir',iconCls:''}
					]
				});
				if(e.data.scope.contextMenu){
					tb.trigger('show',tb, e.pageY, e.pageX);
					tb.showAt(e.pageX, e.pageY);
				}
				e.preventDefault();
				e.stopPropagation();
				tb.on('itemclick',function(a,b,c,d){
					this.scope.runApp(this.scope.getMenuItemById(this.scope.menuItems.items,'changeBackground'));
				},e.data);
			}
		});
		$(window).bind("resize", {scope:t},function(e){
			e.data.scope.doDesktop();
		});		
		mj.bindResize(t.body, t.doDesktop, t);		
	},	
	changeBackground : function(url){
		var bg = 'url(\''+url+'\')';
		$(this.body).css('background',bg);
		setCookie('backgroundImage',url,365,'/');
	},
	addFishEyeMenu : function(){
		var t=[	'<td class="fisheye" style="vertical-align:bottom;"><div><img src="{FEIcon}" title="{title}" style="width:48px;height:48px;margin-top:0px;"></div></td>'];
		this.shiftFish = mj.NE(this.body,{tag:'div',style:'width:1px;height:'+($(this.body).height()-150)+'px'});
		var tmp=mj.NE(this.body,{tag:'table',style : 'width :100%;height:150px;',html:'<tbody><tr><td style="width:50%;"><td style="vertical-align:bottom;"><table><tr class="fisheye"></tr></table></td><td style="width:50%;"></tr></tbody>'});
		var el=$(".fisheye",tmp)[0];
		$(tmp).bind('contextmenu',{scope : this},function(e){
			e.preventDefault();
			e.stopPropagation();
		});
		this.fisheyeMenu = new mj.fisheye({
			size : 48,
			magnitude : 1.5,
			renderTo : el,
			mouseCnt : tmp,
			store : new mj.store({
					data : this.QLItems
				}),
			tpl : new mj.template(t),
			overClass : false,
			selectedClass : false,
			selector : 'td.fisheye'
		});
		this.fisheyeMenu.on('itemclick',function(x){
			//var eldiv=$("div",x.selections[0].el);
			//var h=$("img",x.selections[0].el).height();
			this.runApp(x.selections[0].store);
		},this);
		this.fisheyeMenu.load();
	},
	addQLIcon : function(i,x){
		var t = this;
		$(this.tBarQL).append(this.QLIconTpl.apply(x));
		this.QLItems[i].qel = mj.get('QLItem-'+this.QLItems[i].id);
		$(this.QLItems[i].qel).bind('contextmenu',{item:this.QLItems[i],scope:this},function(e){
			var tb = new mj.menu({
				renderTo : mj.NE(),
				canHide : true,
				style : 'vertical',
				width : 130,
				items : [
					{id:'_1', title:'Sil',iconCls:'mj-menu-delete-icon'}
				]
			});
			tb.trigger('show',tb, e.pageY, e.pageX);
			tb.showAt(e.pageX, e.pageY);
			e.preventDefault();
			e.stopPropagation();
			tb.on('itemclick',function(a,b,c,d){
				this.scope.removeQLIcon(this.item);
			},e.data);
		});
		$(this.QLItems[i].qel).bind('click',{item:this.QLItems[i],scope:this},function(e){
			e.data.scope.runApp(e.data.item);
		
		});		
		if(t.fishEye&&t.fisheyeMenu){
			$(t.fisheyeMenu.renderTo).empty();
			t.fisheyeMenu.load();
		}	
	},
	showQLIcon : function(){
		for(var i = 0, len = this.QLItems.length; i < len; i++){
			var x=this.QLItems[i];
			if(typeof x=='object'){	
				this.addQLIcon(i,x)
			}
		}	
	},
	removeQLIcon : function(x){
		this.QLItems.remove(x)
		$(x.qel).remove();
		deleteCookie('QLItem-'+x.id,'/');
		if(this.fishEye&&this.fisheyeMenu){
			$(this.fisheyeMenu.renderTo).empty();
			this.fisheyeMenu.load();
		}	
	},	
	showDesktopIcon : function(){
		var pos = {w:$(this.body).width(),h:$(this.body).height()};
		for(var i = 0, len = this.desktopItems.length; i < len; i++){
			var x=this.desktopItems[i];
			if(typeof x=='object'){
				var cook=getCookie('deskItem-'+x.id);
				if(!cook)
					if(x.position){
						if(x.position.start&&x.position.start!='tl'){
							switch(x.position.start){
								case 'tr' :
									x.position.x = pos.w-parseInt(x.position.x);
									break;
								case 'bl' :
									x.position.y = pos.h-parseInt(x.position.y);
									break;
								case 'br' :
									x.position.x = pos.w-parseInt(x.position.x);
									x.position.y = pos.h-parseInt(x.position.y);
									break;
							}		
						}
						x.positionStyle = 'top:'+x.position.y+'px;left:'+x.position.x+'px;'
					}else{
						x.positionStyle = 'top:'+this.iconTop+'px;left:'+this.iconLeft+'px;'
						if(this.iconTop+140<pos.h){
							this.iconTop=20;
							this.iconLeft+=70; 
						}else
							this.iconTop+=70;
					}				
				else
					x.positionStyle = cook;
				this.addDesktopIcon(i,x);

			}
		}
	},
	removeDesktopIcon : function(x){
		this.desktopItems.remove(x)
		$(x.el).remove();
		deleteCookie('deskItem-'+x.id,'/');
	},
	deselectAll : function(){
		var t = this;
		for(var i=0,l=t.desktopItems.length;i<l;i++){
			var item = t.desktopItems[i];
			if(item.el){
				$(item.el).removeClass('mj-desktop-icon-selected');
				t.setTitle(item,item._shortTitle);
			}
		}
	},
	setTitle : function(item, title){
		item.titleEl[0].innerHTML = title;
	},
	addDesktopIcon : function(i,x){
		var t = this;
		var title=x.title;
		// title = title.split(' ');
		// var j=0;
		// for(var k=0,l=title.length;k<l;k++){
			// j+=title[k].length;
			// if(j>10){
				// title[k]=title[k]+'<br/>';
				// j=0;
			// }
		// }
		// title = title.join(' ');
			
		this.desktopItems[i]._title = title;
		this.desktopItems[i]._shortTitle = (x.title.length>12) ? (x.title.slice(0,10)+'...') : x.title;
		x.title = this.desktopItems[i]._shortTitle;
		$(this.body).append(this.deskIconTpl.apply(x));
		this.desktopItems[i].el = mj.get('deskItem-'+this.desktopItems[i].id);
		this.desktopItems[i].titleEl = $('span', this.desktopItems[i].el);
		$(this.desktopItems[i].el).bind('contextmenu',{item:this.desktopItems[i],scope:this},function(e){
			var tb = new mj.menu({
				renderTo : mj.NE(),
				canHide : true,
				style : 'vertical',
				width : 130,
				items : [
					{id:'_1', title:mj.lng.glb.del,iconCls:'mj-menu-delete-icon'}
				]
			});
			tb.trigger('show',tb, e.pageY, e.pageX);
			tb.showAt(e.pageX, e.pageY);
			e.preventDefault();
			e.stopPropagation();
			tb.on('itemclick',function(a,b,c,d){
				this.scope.removeDesktopIcon(this.item);
			},e.data);
		});
		$(this.body).bind('mousedown',{scope : this},function(e){
			e.data.scope.deselectAll();
		});
		$(this.desktopItems[i].el).bind('click',{item:this.desktopItems[i],scope:this},function(e){
			//t.deselectAll();
			$(e.data.item.el).addClass('mj-desktop-icon-selected');
			t.setTitle(e.data.item,e.data.item._title);
		});
		$(this.desktopItems[i].el).bind('dblclick',{item:this.desktopItems[i],scope:this},function(e){
			e.data.scope.runApp(e.data.item);
		
		});		
		if(!this.desktopItems[i].fixed){
			this.desktopItems[i].dragHandle = new mj.drag({
				el:this.desktopItems[i].el,
				parent:this.body,
				proxy:false});	
			this.desktopItems[i].dragHandle.on('dragstart',function(e,b){
				var el = $(this.el);
				this.beforeDragXY = {top:el.css('top'),left:el.css('left')};
			},this.desktopItems[i]);
			this.desktopItems[i].dragHandle.on('dragstop',function(e,b){
				if(t.onQL){
					if(mj.getIndex(t.QLItems,'id',this.id)==-1){
						if(t.QLItems.length<5){
							t.QLItems.push(this);
							t.addQLIcon(t.QLItems.length-1,this);	
							setCookie('QLItem-'+this.id,'OK',365,'/');
						}
					}
					var el = $(this.el);
					el.css('top',this.beforeDragXY.top);
					el.css('left',this.beforeDragXY.left);	
					$(t.tBarQL).removeClass('mj-ql-hover');	
				}else{
					var str = 'top:'+parseInt(e._el[0].style.top)+'px;left:'+parseInt(e._el[0].style.left)+'px;'
					setCookie('deskItem-'+this.id,str,365,'/');
				}
			},this.desktopItems[i]);
		}
	},
	getMenuItemById : function(items,id){
		for(var i = 0, len = items.length; i < len; i++){
			if(items[i].items){
				var r = this.getMenuItemById(items[i].items,id);
				if(r)
					return r;
			}else{
				if(items[i].id==id)	
					return items[i];
			}
		}
		return false;
	},
	doDesktop : function(){
		$(this.body).width(this.renderTo.width());
		var h=this.renderTo.height()-28;
		$(this.body).height(this.renderTo.height()-28);
		if(this.shiftFish)
			$(this.shiftFish).height(h-150);
		if(this.fishEye&&this.fisheyeMenu)
			this.fisheyeMenu.getCenterPoint();
		$(this.body).trigger('kkresize');
	},
	_menuItemClick : function(a,b,c){
		if(b.url)
			this.runApp(b);
	},
	runApp : function(item){
		var t=this;
		if(item.multipleWindow || !t.windows[item.id]){
			var winDesktopId = item.multipleWindow ? mj.genId('win') : item.id;
			var win = new mj.window({
				destroyOnClose : true,
				minimizable : typeof item.minimizable!='undefined'?item.minimizable:true,
				maximizable : typeof item.maximizable!='undefined'?item.maximizable:true,
				closable : typeof item.closable!='undefined'?item.closable:true,
				resizable : typeof item.resizable!='undefined'?item.resizable:true,
				wM : t.wM,
				id : item.id,
				parent : t.body,
				renderTo : t.body,
				modal : item.modal||false,
				title : item.title,
				width : item.width||600,
				height : item.height||350,
				minWidth : item.minWidth||item.width||600,
				minHeight : item.minHeight||item.height||350,
				buttons : item.buttons,
				autoLoad : {
					url:item.url,
					params:{
						id:item.id,
						winDesktopId:winDesktopId,
						title:item.title,
						jspath:item.jspath,
						jsurl:item.jsurl,
						optparams:item.optparams,
						multipleWindow:item.multipleWindow
					}
				}				
			});
			win.on('close',function(x,y){
				var t=this;
				win.tab.remove();
				win=null;
				this.winHistory.remove(x.winDesktopId);//?				
				this.windows[item.multipleWindow?x.winDesktopId:x.id]=null;
				if(this.tabWidth<this.initTabWidth&&(this.winHistory.length)*(this.tabWidth+12)<(this.tabContainerWidth-12)){
					this.tabWidth = parseInt((this.tabContainerWidth-12)/(this.winHistory.length))-12
					if(this.tabWidth>this.initTabWidth)
						this.tabWidth = this.initTabWidth;
					$(".mj-desktop-taskbar-tab-item").width(this.tabWidth);
					$(".mj-desktop-taskbar-tab-item span").each(function(e){
						this.innerHTML = this.getAttribute('name').ellipse(parseInt((t.tabWidth)/6));
					});
				}
				if(this.winHistory.length>0&&!this.windows[this.winHistory[this.winHistory.length-1]].window.minimized)
					this.windows[this.winHistory[this.winHistory.length-1]].window.show();
			},t);
			win.on('activate', function(win){
				t.activeWindow = win;
			});
			win.on('minimize',function(x,y){
				this.windows[x.winDesktopId].tab.removeClass('active-tab');
				this.winHistory.remove(x.winDesktopId);
				if(this.winHistory.length>0&&!this.windows[this.winHistory[this.winHistory.length-1]].window.minimized)
					this.windows[this.winHistory[this.winHistory.length-1]].window.show();
			},t);			
			var obj={window : win};
			if(item.multipleWindow)
				win.winDesktopId = t.windows.push(obj,winDesktopId);
			else{
				t.windows[item.id] = obj;
				win.winDesktopId = item.id;
			}
			obj.id=win.winDesktopId;
			if((t.winHistory.length+1)*(t.tabWidth+12)>(t.tabContainerWidth-12)){
				t.tabWidth = parseInt((t.tabContainerWidth-12)/(t.winHistory.length+1))-12
				$(".mj-desktop-taskbar-tab-item").width(t.tabWidth);
				$(".mj-desktop-taskbar-tab-item span").each(function(e){
					this.innerHTML = this.getAttribute('name').ellipse(parseInt((t.tabWidth)/6));
				});
			}	
			var tb = obj.tab = win.tab = $(mj.NE(t.tBarTab,{tag:'div', cls:'mj-desktop-taskbar-tab-item',style:'width:'+(t.tabWidth)+'px;',html:'<span name="'+item.title+'">'+item.title.ellipse(parseInt((t.tabWidth)/6))+'</span>'}));
			tb.bind('contextmenu',{obj:obj,scope:t},function(e){
				var tb = new mj.menu({
					renderTo : mj.NE(),
					canHide : true,
					style : 'vertical',
					width : 130,
					items : [
						{id:'_1', title:'Kapat',iconCls:'mj-menu-close-icon'}
					]
				});
				tb.trigger('show',tb, e.pageY, e.pageX);
				tb.showAt(e.pageX, e.pageY);
				e.preventDefault();
				e.stopPropagation();
				tb.on('itemclick',function(a,b,c,d){
					this.obj.window.close();
				},e.data);
			});
			tb.bind('click',{obj:obj,scope:t},function(e){
				var s = e.data.scope,obj=e.data.obj;
				if($(this).hasClass('active-tab')){
					obj.window.minimize();
				}else{
					obj.window.show();
				}
			});
		}
		(obj||t.windows[item.id]).window.show();
	},
	showHelp : function(helpId){
		if(this.helpPath){
			var url = helpId ? (this.helpPath+'index.html?context='+helpId) : this.helpPath+'index.html';
			this.helpWin = mj.newWindow({url:url});
		}
	},
	init : function(){
		var t = this;
		t.wM = new mj.windowManager();
		t.tabStrLen =t.initTabStrLen;
		t.tabWidth =t.initTabWidth;
		t.iconLeft = 20;
		t.iconTop = 20;		
		var _w = t.windows={};
		t.windows.push = function(o,id){
			o.winDesktopId = id;
			_w[o.winDesktopId]=o;
			return o.winDesktopId;
		};
		t.winHistory=[];
		t.beforeSD=[];
		t.render();
		t.wM.on('activate',function(e){
			$(".mj-desktop-taskbar-tab-item").removeClass('active-tab');
			this.windows[e.winDesktopId].tab.addClass('active-tab');
			this.winHistory.remove(e.winDesktopId);
			this.winHistory.push(e.winDesktopId);
		},t);
		if(t.showSystemTray){
			mj.loaderShow = function(){
				mj.loading.addClass('show-loader');
			};
			mj.loaderHide = function(){
				mj.loading.removeClass('show-loader');
			};		
			$().ajaxStart(function(){
				mj.loaderShow();
			}).ajaxStop(function(){
				mj.loaderHide();
			});
		}
		var _t = this;
		mj.shortcuts.on('F1', function(){
			_t.showHelp(_t.activeWindow && _t.activeWindow.helpId ? _t.activeWindow.helpId : false);
		});
		t.fakeInput = mj.NE(mj.NE(mj.bd,{style:'display:none;position:absolute;left:-9999px;top:-9999px;'}),{tag:'input'});
		t.fakeInput.focus();
	}
};
mj.extend(mj.desktop, mj.component);
mj.cpager = function(config){
	mj.cpager.superclass.constructor.call(this,config);
};
mj.cpager.prototype = {
	componentClass : 'mj.cpager',
	actionEvent : 'click',
	render : function(config){		
		var t=this;
		mj.apply(config.scope.store.params,config.scope.pbar.params);
		config.scope.pbar.store=config.scope.store;
		var h = config.scope.cnt.height();
		var w = config.scope.cnt.width();
		if(config.scope.pbar.pos&&config.scope.pbar.pos=='lr'){
			config.scope.pageBarPrev = mj.NE(config.scope.cnt,{tag:'div', style:'height:'+h+'px;', cls:'mj-carousel-left', html:'<div class="mj-split-left">'+mj.insertSpacer(9,10)+'</div>'});
			config.scope.renderTo = mj.NE(config.scope.cnt,{tag:'div',style:'float:left;overflow:hidden;width:'+(w-20)+'px;height:'+h+'px;'});
			config.scope.pageBarNext = mj.NE(config.scope.cnt,{tag:'div', style:'height:'+h+'px;', cls:'mj-carousel-right', html:'<div class="mj-split-right">'+mj.insertSpacer(9,10)+'</div>'});
		}else{
			config.scope.renderTo = mj.NE(config.scope.cnt,{tag:'div',style:'overflow:auto;height:'+((config.scope.cnt.height()||parseInt(config.scope.cnt[0].style.height))-25)+'px;'});
			config.scope.pageBar = mj.NE(config.scope.cnt,{tag:'div', cls:'mj-paging'});
		}
		config.scope.pbar.renderTo = config.scope.pageBar;	
		$(config.scope.pageBarPrev).bind(t.actionEvent,function(){
			t.prev();
		});
		$(config.scope.pageBarNext).bind(t.actionEvent,function(){
			t.next();
		});
	}
};
mj.extend(mj.cpager, mj.pager);


mj.carousel = function(config){
	mj.carousel.superclass.constructor.call(this, config);
};
mj.carousel.prototype = {
	magnitude : 2,
	align : 'center',
	bigClass : 'mj-carousel-big',
	_onItemOver : function(a,b,c){
		c.stopPropagation();
		$("#carousel-dummy").remove();
		var t = this;
		var el = $(b);
		var elOf = el.offset();
		var w = el.width(),h = el.height();
		var of = {};
		of.width = w*t.magnitude;
		of.height = h*t.magnitude;
		if(t.align=='center'){
			of.left = (elOf.left-((w/2)*(t.magnitude-1)));
			of.top = (elOf.top-((h/2)*(t.magnitude-1)));
		}else if(t.align=='topleft'){
			of.left = elOf.left;
			of.top = elOf.top;
		}else if(t.align=='topcenter'){
			of.left = (elOf.left-((w/2)*(t.magnitude-1)));
			of.top = elOf.top-of.height;
		}else if(t.align=='mouselb'){
			of.left = c.clientX;
			of.top = c.clientY;
		}else if(t.align=='mouserb'){
			of.left = c.clientX-of.width;
			of.top = c.clientY;
		}
		var dummy = $(mj.NE(mj.bd,{tag:'div',id:'carousel-dummy',cls:this.bigClass,style:'border:1px solid #ddd;position:absolute;left:'+of.left+'px;top:'+of.top+'px;width:'+of.width+'px;height:'+of.height+'px;'}));
		dummy.append(el.find('img').clone());
		dummy.click(function(){
			el.trigger('click');
			$("#carousel-dummy").remove();
		});
		dummy.mouseout(function(){
			$("#carousel-dummy").remove();
			//var t=setTimeout('$("#carousel-dummy").remove()',1000);
		});
	},
	init : function(){
		var t = this;
		mj.carousel.superclass.init.call(t);
		t.on('onItemOver',function(a,b,c){
			t._onItemOver(a,b,c);
		});
	}
};
mj.extend(mj.carousel, mj.view);

mj.fisheye = function(config){
	mj.fisheye.superclass.constructor.call(this, config);
};
mj.fisheye.prototype = {
	componentClass : 'mj.fisheye',
	magnitude : 2,
	size : 64,
	getCenterPoint : function(){
		var t = this;	
		for(var i=0,len=t.items.length;i<len;i++){
			var el = $(t.items[i].el);
			t.items[i].img = el.find('img');
			t.items[i].img[0].style.width = t.size +'px'; 
			t.items[i].img[0].style.height = t.size +'px';
			el.width(t.size);
			el.height(t.size);
			var elOf = el.offset();
			var cp = {};
			cp.left = elOf.left + (t.size/2);
			cp.top = elOf.top + (t.size/2);
			t.items[i].centerPoint = cp;
			t.items[i].initCP = {top:cp.top,left:cp.left};
			
		}		
	},
	init : function(){
		var t = this;
		t.mouseCnt = $(t.mouseCnt) || t.cnt;
		mj.fisheye.superclass.init.call(t);
		t.on('afterload',function(){
			this.getCenterPoint();
		},t);
		t.mouseCnt.bind('mousemove',function(e){
			for(var i=0,len=t.items.length;i<len;i++){
				var cp = t.items[i].centerPoint;
				var magnitude = 1;
				if(Math.abs(cp.top - e.clientY)<(t.size*(1.5))&&Math.abs(cp.left - e.clientX)<(t.size*2) ){
					magnitude = magnitude + ((t.magnitude-1)*(((t.size*2)-Math.abs(cp.left - e.clientX))/(t.size*2)))
				}
				var newSize = parseInt(t.size*magnitude);
				t.items[i].img[0].style.width = newSize +'px'; 
				t.items[i].img[0].style.height = newSize +'px'; 
				if(newSize>t.size){
					t.items[i].centerPoint.left=t.items[i].initCP.left+((newSize-t.size)/2);				
					t.items[i].centerPoint.top=t.items[i].initCP.top+((newSize-t.size)/2);				
				}
				
			}
		});
		t.mouseCnt.bind('mouseover',function(e){
			t.reg=t.mouseCnt.offset();
			t.reg.right=t.reg.left+t.mouseCnt.width();
			t.reg.bottom=t.reg.top+t.mouseCnt.height();
		});
		$().bind('mousemove',{scope:this},function(e){
			var r=e.data.scope;
			if(r.reg&&(e.clientX<r.reg.left||e.clientX>r.reg.right||e.clientY<r.reg.top||e.clientY>r.reg.bottom))
				for(var i=0,len=r.items.length;i<len;i++){
					var el = r.items[i].img[0].style;
					el.width =r.size+'px';
					el.height=r.size+'px';
				}
		});
	}
};
mj.extend(mj.fisheye, mj.view);
mj.gantt = function(config){
	mj.gantt.superclass.constructor.call(this, config);
};
mj.gantt.prototype = {
	componentClass : 'mj.gantt',
	_firstDateSetted : false,
	_lastDateSetted : false,
	_minPredictionCount : 10,
	barHeight : 15,
	barTop : 2,
	buttons : false,
	cellHeight : 22,
	canvasColor : '#fff',
	canvasItemsDraw : false,
	chartWidth : false,
	checkDependTask : false,
	displayLabels : false,
	doneBarHeight : 5,
	doneBarTop : 7,
	drawResourcesPane : false,
	durationUnit : 'second',
	forms : false,
	stores : false,
	firstColumnWidth : 120,
	firstDate : false,
	grids : false,
	id : false,
	lastDate : false,
	layouts : false,
	lastUpdate : 0,
	liveUpdate : true,
	minResolution : 5000,
	maxResolution : 5000,
	oddEven : false,
	offTime : false,
	prefix : false,
	resCollapsed : true,
	resHeight : 160,
	series : false,
	station : false,
	timeInterval : '6hour',
	timeIntervalWidth : 50,
	updateTaskInterval : 3000,
	windows : false,
	width : 1000,
	details : {
		ref : false,
		customer : false,
		checkDependTasks : false
	},
	timeRangeMap : [{
			ms : 60000,
			f : 'H:i',
			name : 'minute',
			up : '5minute',
			top : 'quarterHour',
			title : '1 dakika'
		},{
			ms : 300000,
			f : 'H:i',
			name : '5minute',
			up : 'quarterHour',
			top : 'halfHour',
			title : '5 dakika'
		},{
			ms : 600000,
			f : 'H:i',
			name : '10minute',
			up : 'halfHour',
			top : 'hour',
			title : '10 dakika'
		},{
			ms : 900000,
			f : 'H:i',
			name : 'quarterHour',
			up : 'hour',
			top : '3hour',
			title : '15 dakika',
			min : true
		},{
			ms : 1800000,
			f : 'H:i',
			name : 'halfHour',
			up : '2hour',
			top : '4hour',
			title : '30 dakika'
		},{
			ms : 3600000,
			f : 'H:i',
			name : 'hour',
			up : '3hour',
			top : '6hour',
			title : '1 saat'
		},{
			ms : 7200000,
			f : 'H:i',
			name : '2hour',
			up : '4hour',
			top : '8hour',
			title : '2 saat'
		},{
			ms : 10800000,
			f : 'H:i',
			name : '3hour',
			up : '6hour',
			top : '12hour',
			title : '3 saat'
		},{
			ms : 14400000,
			f : 'H:i',
			name : '4hour',
			up : '8hour',
			top : '12hour',
			title : '4 saat'
		},{
			ms : 21600000,
			f : 'H:i',
			name : '6hour',
			up : '12hour',
			top : 'day',
			title : '6 saat'
		},{
			ms : 28800000,
			f : 'H:i',
			name : '8hour',
			up : 'day',
			top : '2day',
			title : '8 saat'
		},{
			ms : 43200000,
			f : 'H:i',
			name : '12hour',
			up : 'day',
			top : '2day',
			title : '12 saat'
		},{
			ms : 86400000,
			f : 'd/m',
			name : 'day',
			up : '2day',
			top : 'week',
			title : '1 gün'
		},{
			ms : 172800000,
			f : 'd/m',
			name : '2day',
			up : 'week',
			top : '4week',
			title : '2 gün',
			max : true
		},{
			ms : 604800000,
			f : 'd/m',
			name : 'week',
			title : '1 hafta'
		},{
			ms : 2419200000,
			f : 'd/m',
			name : '4week',
			title : '4 hafta'
	}],
	timeRange : ['minute', '5minute', '10minute', 'quarterHour', 'halfHour', 'hour', '2hour', '3hour', '4hour', '6hour', '8hour', '12hour', 'day', '2day', 'week', '4week'],
	render : function(){
		var t = this, d = t.domEls, id = t.id, n = mj.NE, fcw = t.firstColumnWidth, _w=t.renderTo.width(), _h = t.renderTo.height();
		if(t.lastDate)
			t.setLastDate(t.lastDate.getTime());
		t._labelsOn = t.displayLabels;
		t._window = window.d.windows.plan.window;
		t.waitMask = $(n(t.renderTo,{
			cls:'mj-page-wait-mask mj-opacity-8',
			style:'display:none;width:'+_w+'px;height:'+_h+'px;',
			html:'<table width="100%" height="100%"><tr><td align="center" valign="middle"><img src="'+mj.glb.imagePath+'ajax-loader.gif"/><br/><br/><span class="mj-page-wait-title">Lütfen Bekleyin...</span></td></tr></table>'
		}));
		t._window.addRelated(t.waitMask);
		d.quickMsgEls = {'cnt':$(n(t.renderTo,{
			cls:'mj-gantt-quick-msg',
			style:'width:'+_w+'px;top:-20px',
			html:'<table width="100%" height="20px" cellpadding="0" cellspacing="0" style="position:absolute;top:0;"><tr><td align="center" valign="top"><table cellpadding="0" cellspacing="0"><tr><td style="width:20px;background:transparent url('+mj.glb.imagePath+'gantt-info.png) no-repeat 0 0">'+mj.insertSpacer(20,20)+'</td><td style="background:transparent url('+mj.glb.imagePath+'gantt-info.png) repeat-x 0 -40px"><span>...</span></td><td style="width:20px;background:transparent url('+mj.glb.imagePath+'gantt-info.png) no-repeat 0 -20px">'+mj.insertSpacer(20,20)+'</td></tr></table></td></tr></table>'
		}))};
		d.quickMsgEls.content = $('span', d.quickMsgEls.cnt);
		t.waitMaskShow();
		setTimeout(function(){
			t.windows = {};
			t.forms = {};
			t.grids = {};
			t.layouts = {};
			t.canvasItemsDraw = {
				vardiya : {
					p : {d:true,l:true},
					g : {d:true,l:true}
				},
				personel : {
					p : {d:true,l:false},
					g : {d:true,l:false}
				},
				kasa : {
					a : true,
					ts : false,
					items :t.stores.kasaStore.data//kasa tipleri var ise ilk açılışta alınarak doldurulacak
				}
			};			
			t.series = {};
			var scrollerSize = 16;
			t._chartClientWidth = t.width;
			var _items = [];
			// Müşteri filtresi eklemek için kullanılabilir. silme!
			// if(t.details.customer)
				// _items.push({
					// region : 'north',
					// initial : 50,
					// min : 50,
					// max : 100,
					// split : true,
					// collapsible : true,
					// collapsed : true
				// });
			_items.push({
				region : 'west',
				initial : 260,
				min : 260,
				max : 400,
				split : true,
				collapsible : true
			});
			t.layouts.main = new mj.layout({
				renderTo :n(t.renderTo,{tag:'div',id:'layout-cnt'}),
				layout : 'border',
				items : _items
			});
			t.tasks = t.stores.grid.data;
			if(t.details.ref)
				t.referans = t.stores.referans.data;
			if(t.details.customer)
				t.customer = t.stores.customer.data;
			
			t.layouts.west = new mj.layout({
				renderTo : n(t.layouts.main.getBody('west')),
				layout : 'border',
				items : [
					{
						region : 'south',
						initial : 83,
						min : 83,
						max : 100,
						split : true,
						collapsible : true,
						collapsed : true
					}
				]
			});
			
			t.gridPanel = new mj.panel({
				renderTo : t.layouts.west.getBody('center'),
				fitToParent : true,
				border : false
			});
			var _cm = [
				{header: "id", dataIndex: 'id', width: 30},
				{header: "Süre", dataIndex: 'duration', width: 120,renderer:function(val,task,cell){return t.renderTaskGridEls(val,task,cell,t);}},
				{header: "Operasyon", dataIndex: 'name', width: 70}
			];
			if(t.details.ref)
				_cm.push({header: "Referans", dataIndex: 'referans', width: 70,renderer:function(val){var ref=t.getReferans(val);return ref.name;}});
			if(t.details.customer)
				_cm.push({header: "Müşteri", dataIndex: 'customerId', width: 70,renderer:function(val){var cust=t.getCustomer(val);return cust.code;}});
			_cm.push({header: "Op#", dataIndex: 'operator',width: 60});
			_cm.push({header: "İst.", dataIndex: 'station', renderer:function(val){var st=t.getStationData(val);return st.name;}, width: 60});
			_cm.push({header: "Başlangıç", dataIndex: 'startDate', width: 100,renderer : function(val){return (val instanceof Date)?val.formatDate('d/m/Y H:i'):''}});
			_cm.push({header: "Bitiş", dataIndex: 'finishDate', width: 100,renderer : function(val){return (val instanceof Date)?val.formatDate('d/m/Y H:i'):'';}});
			if(t.details.checkDependTasks)
				_cm.push({header: "Bağlı Görev", dataIndex: 'predecessor', width: 100});
			t.curTime = new Date(t.curTimeMs);
			//t.curTimeMs = t.curTime.getTime();
			t.stores.grid.on('load', function(){
				t.gridloading = true;
				if(t._importing){
					for(var i=0,l=t.station.length;i<l;i++){
						t.station.task = [];
						station.lastTime.setTime(g.firstDate.getTime());
					}
					for(var i=0,l=t.tasks.length;i<l;i++){
						var task = t.tasks[i];
						if(task.el)
							task.el.remove();
						if(task.titleEl)
							task.titleEl.remove();
					}
					t.tasks = t.stores.grid.data;
					t._importing = false;
				}
				if(typeof t.refreshed == 'undefined'){
					var _max = -1;
					// var _refreshElements = false;
					for(var i=0,l=t.stores.grid.data.length;i<l;i++){
						var task = t.stores.grid.data[i];
						task.id = parseInt(task.id);
						if(typeof task.startDate.getTime!='function'){
							task.startDate = new Date(parseInt(task.startDate));
							task.times =  false;
							task.drag =  false;
							task.planned = !!parseInt(task.planned);
							task._reLocate = true;
						}
						if(task.done && typeof task.done.startDate.getTime!='function'){
							task.done.startDate = new Date(parseInt(task.done.startDate));
							task.done.doneSetupStartDate = new Date(parseInt(task.done.doneSetupStartDate));
							task.done.doneSetupFinishDate = new Date(parseInt(task.done.doneSetupFinishDate));
							task.done.doneFinishDate = new Date(parseInt(task.done.doneFinishDate));
						}
						task.modifyTime = t.curTimeMs;
						if(task.station)
							task._station = t.getStationObject(parseInt(task.station));
						if(!task.pending)
							task.pending = [];
						if(task.predecessor){
							var preTask = t.getTask(parseInt(task.predecessor));
							if(!preTask.pending)
								preTask.pending = [];
							preTask.pending.push(task);
						}
						task.loading =  true;
						task.pinned = !!(parseInt(task.pinned));
						t.calculateTask(task);
						task.loading =  false;
						if(task.times.duration>_max)
							_max = task.times.duration;
					}
					t._maxDuration = _max;
					for(var i=0,l=t.stores.grid.data.length;i<l;i++){
						task = t.stores.grid.data[i];
						t.calculateTaskSizes(task);
					}
				}
			});
			t.grids.gorev = new mj.grid({
				//renderTo : d.taskCnt,
				renderTo : t.gridPanel.getBody(),
				store : t.stores.grid,
				pbar : new mj.pager({
					pos:'bottom',
					limit:25,
					elements : {
						first : false,
						prev : false,
						next : false,
						last : false,
						refresh : true,
						pages : false
					},
					sc:t,
					refresh : function(){
						this.sc.refreshed = true;
						this.store.clearFilter();
						this.store.load();
						t.filterInputs.op1.value = '';
						if(t.details.ref)
							t.filterInputs.ref1.value = '';
						if(t.details.customer)
							t.filterInputs.cust1.value = '';
						t.filterInputs.ist1.value = '';
						t.filterInputs.tar1.value = '';
					}
				}),
				fitToParent : true,
				cm : _cm
			});
			t._window.addRelated(t.grids.gorev);
			t.grids.gorev.on('rowclick', function(){
				t.setActiveRegion('grid');
			});
			t.grids.gorev.store.on('load',function(){
				if(typeof t.refreshed != 'undefined')
					delete t.refreshed;
				t.drawCanvas();
				for(var i=0,l=t.tasks.length;i<l;i++){
					var task = t.tasks[i];
					if($.browser.msie){
						task.gridSetupEl[0].style.background='#ffc';
						if(task.color)
							task.gridProductionEl[0].style.background=task.color;
					}else{
						task.gridSetupEl.css('background','#ffc');
						if(task.color)
							task.gridProductionEl.css('background',task.color);
					}
				}
			});
			t.grids.gorev.on('afterload', function(){
				t.gridloading = false;
				t.drawResources();
			});
			t.grids.gorev.pbar.tbar.addSplitter();
			t.buttons.filterBtn = t.grids.gorev.pbar.tbar.addButton({id:'btnFilter',iconCls : 'mj-filter',alt : 'Filtrele',sc:t, handler:t.filterTasks});
			t.grids.gorev.pbar.tbar.addSplitter();
			t.buttons.addBtn = t.grids.gorev.pbar.tbar.addButton({id:'btnAdd',iconCls : 'mj-add',alt : 'Ekle',scope:t, handler:t.newTask});
			t.buttons.deleteBtn = t.grids.gorev.pbar.tbar.addButton({id:'btnDelete',iconCls : 'mj-delete',alt : 'Sil',scope:t, handler:t.deleteTask});
			t.grids.gorev.pbar.tbar.addSplitter();
			t.buttons.compileBtn = t.grids.gorev.pbar.tbar.addButton({id:'btnCompile',iconCls : 'mj-compile',alt : 'Verileri Çek',scope:t, handler:t.importTasks});
			t.buttons.parametersBtn = t.grids.gorev.pbar.tbar.addButton({id:'btnParameters',iconCls : 'mj-components',alt : 'Planlama Parametreleri',scope:t, handler:t.editParameters});

			d.gridFilter = n(t.layouts.west.getBody('south'));
			$(t.layouts.west.getBody('south')).css('background','#EDF3FB');
			t._bindInputKeys = function(input){
				$(input).bind('keydown', {t:t}, function(e){
					if(e.keyCode==13){
						t.sc = t;
						t.filterTasks.call(t);
					}
				});
				$(input).bind('focus', {t:t}, function(e){
					t.filterInputs.isActive = true;
					t.filterInputs.activeInput = input;
					t.setActiveRegion('filter');
					t.isInInput = true;
				});
				$(input).bind('blur', {t:t}, function(e){
					t.filterInputs.isActive = false;
					t.isInInput = false;
				});
			};
			t.filterInputs = {};
			var l1 = n(d.gridFilter,{cls:'row',style:'position:absolute;left:0px;top:0px;'});
				n(l1,{style:'font-size:8pt;float:left;',html:'Operasyon:',cls:'mj-unselectable'});
				t.filterInputs.op1=n(l1,{tag:'input',style:'margin-left:42px;',id:'op-1'});
				t._bindInputKeys(t.filterInputs.op1);
			var top=0;
			if(t.details.ref){
				var l2 = n(d.gridFilter,{cls:'row',style:'position:absolute;left:0px;top:'+(top+=20)+'px;'});
				n(l2,{style:'font-size:8pt;float:left;',html:'Referans:',cls:'mj-unselectable'});
				t.filterInputs.ref1=n(l2,{tag:'input',style:'margin-left:53px;',id:'ref-1'});
				t._bindInputKeys(t.filterInputs.ref1);
			}
			var l3 = n(d.gridFilter,{cls:'row',style:'position:absolute;left:0px;top:'+(top+=20)+'px;'});
				n(l3,{style:'font-size:8pt;float:left;',html:'İstasyon:',cls:'mj-unselectable'});
				t.filterInputs.ist1=n(l3,{tag:'input',style:'margin-left:55px;',id:'ist-1'});
				t._bindInputKeys(t.filterInputs.ist1);
			var l4 = n(d.gridFilter,{cls:'row',style:'position:absolute;left:0px;top:'+(top+=20)+'px;'});
				n(l4,{style:'font-size:8pt;float:left;',html:'Tarih:',cls:'mj-unselectable'});
				t.filterInputs.tar1=n(l4,{tag:'input',style:'margin-left:75px;',id:'tar-1'});
				t._bindInputKeys(t.filterInputs.tar1);
			if(t.details.customer){
				var l5 = n(d.gridFilter,{cls:'row',style:'position:absolute;left:0px;top:'+(top+=20)+'px;'});
				n(l5,{style:'font-size:8pt;float:left;',html:'Müşteri:',cls:'mj-unselectable'});
				t.filterInputs.cust1=n(l5,{tag:'input',style:'margin-left:63px;',id:'ref-1'});
				t._bindInputKeys(t.filterInputs.cust1);
			}
			$('div.row',d.gridFilter).css({'line-height':'18px','margin':'2px 0px 0px 2px'});
			$('input',d.gridFilter).css({'font-size':'8pt','float':'left','width':'80px','height':'14px','border':'1px solid #A0ADB4'});
			var _cnt = $(t.layouts.main.getBody('center'));
			t.chartWidth = _cnt.width();
			t.height = _cnt.height();
			
			t.chartHeight = t.resCollapsed ? t.height - 7 : (t.height - t.resHeight);
			
			var resHeight = t.resHeight-8;
			t.layouts.chart = new mj.layout({
				renderTo : n(_cnt),
				layout : 'border',
				items : [
					{
						region : 'south',
						initial : resHeight,
						min : resHeight,
						max : resHeight,
						split : true,
						collapsible : true,
						collapsed : t.resCollapsed
					}
				]
			});
			t.layouts.chart.on('toggle', function(l,r,ce){
				if(!ce)
					t.drawResources();
			});
			_cnt = t.layouts.chart.getBody('center');
			d.chartCnt = $(n(_cnt,{id:id+'-chart-container mj-resize-handle', cls:'mj-gantt-chart-container',style:'width:'+(t.chartWidth)+'px;height:'+(t.chartHeight)+'px;'}));
			mj.bindResize(_cnt, t.doResize, t);
			var ce = d.chartEls = {};
			var hRH = 23;
			ce.corner = $(n(d.chartCnt, {style:'width:'+fcw+'px;height:'+(3*hRH)+'px;float:left;background:#edf3fb;border-right:1px solid #ccc;'}));
			var btnCnt = n(ce.corner, {style:'margin-left:23px;margin-top:14px;'});
			t.buttons.saveBtn = new mj.speedButton({renderTo:btnCnt, id:'btnSave',iconCls : 'mj-save',alt : 'Kaydet',scope:t, handler:t.save,disabled : true});
			t.buttons.snapshotBtn = new mj.speedButton({renderTo:btnCnt, id:'btnSnapshot',iconCls : 'mj-snapshot',alt : 'Geçerli Plan Görünümünü Kaydet',scope:t, handler:t.saveSnapshot});
			t.buttons.playPauseBtn = new mj.speedButton({renderTo:btnCnt, id:'btnPlayPause',iconCls : t.liveUpdate ? 'mj-pause' : 'mj-play',alt : 'Canlı İzleme Modu',scope:t, handler:t.switchLiveUpdate});
			n(btnCnt,{cls:'clear',html:mj.insertSpacer(1,1)});
			t.buttons.zoomInBtn = new mj.speedButton({renderTo:btnCnt, iconCls:'mj-zoom-in',alt : 'Yakınlaş',scope:t, handler:t.zoomIn});
			t.buttons.zoomOutBtn = new mj.speedButton({renderTo:btnCnt, iconCls:'mj-zoom-out',alt:'Uzaklaş',scope:t, handler:t.zoomOut});
			t.buttons.zoomResetBtn = new mj.speedButton({renderTo:btnCnt, iconCls:'mj-zoom',alt:'Sıfırla',scope:t, handler:t.zoomReset});
			
			ce.header = $(n(d.chartCnt, {id:id+'-headers', cls:'mj-gantt-headers',style:'width:'+(t.chartWidth-fcw-scrollerSize-1)+'px;height:'+(3*hRH)+'px;float:left;overflow:hidden;'}));
			n(d.chartCnt,{style:'width:'+scrollerSize+'px;float:left;height:'+(3*hRH)+'px;background:#edf3fb;',html:mj.insertSpacer(scrollerSize, 3*hRH)});
			ce.headers = {
				line1 : $(n(ce.header, {style:'width:'+t._chartClientWidth+'px;height:'+hRH+'px;',cls:'mj-gantt-header1'})),
				line2 : $(n(ce.header, {style:'width:'+t._chartClientWidth+'px;height:'+hRH+'px;',cls:'mj-gantt-header2'})),
				line3 : $(n(ce.header, {style:'width:'+t._chartClientWidth+'px;height:'+hRH+'px;',cls:'mj-gantt-header3'}))
			};
			t._chartBodyWidth = t.chartWidth-fcw-1;
			t._chartBodyHeight = t.chartHeight-(3*hRH)-1;
			ce.stations = $(n(d.chartCnt, {style:'width:'+fcw+'px;height:'+t._chartBodyHeight+'px;float:left;background:#edf3fb;border:1px solid #ccc;border-left:0;border-bottom:0;overflow:hidden'}));
			ce.stationsCnt = $(n(ce.stations, {id:id+'-stations', style:'width:'+fcw+'px;height:'+(t.chartHeight-(3*hRH)-scrollerSize-1)+'px;overflow:hidden'}));
			ce.chartBody = $(n(d.chartCnt, {id:id+'-chart-body', cls:'mj-gantt-grab', style:'width:'+(t._chartBodyWidth)+'px;height:'+t._chartBodyHeight+'px;float:left;background:#fff;overflow:scroll;border-top:1px solid #ccc;position:relative;'}));
			ce.chartBodyScroll = $(n(ce.chartBody, {id:id+'-chart-body-scroll', style:'float:left;position:relative;width:'+t._chartClientWidth+'px;'}));
			ce.chartRowsBody = $(n(ce.chartBodyScroll));
			
			ce.infoPane = $(mj.NE(t.layouts.main.getBody('center'), {cls:'mj-gantt-task-info',style:'opacity:0.9;width:'+(t.chartWidth-fcw-scrollerSize-3)+'px;height:'+(3*hRH)+'px;background:#f4f9a6;position:absolute;top:0;left:'+(fcw+1)+'px;font-size:11px;padding-left:2px;display:none'}));

			d.resCnt = $(n(t.layouts.chart.getBody('south'),{id:id+'-res-container', cls:'mj-gantt-res-container',style:'overflow:hidden;width:'+(t.chartWidth)+'px;height:'+(resHeight)+'px;'}));
			var re = d.resEls = {
				header : $(n(d.resCnt, {id:id+'-res-header',style:'width:'+fcw+'px;height:'+resHeight+'px;float:left;background:#ddd;border-right:1px solid #ccc;'})),
				cnt : $(n(d.resCnt, {id:id+'-res-cnt',style:'width:'+(t.chartWidth-fcw-1)+'px;height:'+resHeight+'px;float:left;background:#ddd;'}))
			};
			re.cntScroller = $(n(re.cnt,{style:'width:'+(t.chartWidth-fcw-scrollerSize-1)+'px;height:'+resHeight+'px;float:left;overflow:hidden'}));
			n(re.cnt,{style:'width:'+scrollerSize+'px;background:#ddd;float:left;height:'+resHeight+'px;',html:mj.insertSpacer(scrollerSize, resHeight)});
			re.scroller = d.canvasCnt = $(n(re.cntScroller, {id:id+'-res-cnt-scroller',style:'width:'+(t._chartClientWidth)+'px;height:'+resHeight+'px;float:left;',html:'<canvas width="' + t._chartClientWidth + '" height="' + resHeight + '" style="width:'+t._chartClientWidth+'px;height:'+resHeight+'px;"></canvas>'}));
			d.canvasInfo = $(n(re.cntScroller,{tag:'div',id:'canvas-info-panel',cls:'mj-invisible mj-gantt-tip',style:'left:'+fcw+'px;'}));
			re.cntScroller.bind('mouseout', function(){
				d.canvasInfo.addClass('mj-invisible');
			});
			if(!$.browser.msie){
				re.scroller.bind('mousedown',function(e){
					if(e.which==1){
						re._dragStarted={x:e.layerX,y:e.layerY};
						re.scroller[0].style.cursor='url('+mj.glb.imagePath+'pt/closedhand.cur'+'),default;';
					}
				});
				re.scroller.bind('mouseup',function(e){
					re._dragStarted=false;
					re.scroller[0].style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
				});
				re.scroller.bind('mouseout',function(e){
					re._dragStarted=false;
					re.scroller[0].style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
				});
				re.scroller[0].style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
				re.scroller.bind('mousemove',function(e){
					if(re._dragStarted){
						var _x = re._dragStarted.x-e.layerX, _y = re._dragStarted.y-e.layerY;
						re.cntScroller[0].scrollLeft += _x;
						ce.chartBody[0].scrollLeft += _x;
						ce.header[0].scrollLeft += _x;
					}
				});
				
				ce.chartBody.bind('mousedown',function(e){
					var isXul = false;
					if(e.originalTarget){
						try{
							isXul = false;
							if(e.originalTarget.localName=='thumb')
								isXul = true;
						}catch(e){
							isXul = true;
						}
					}
					if(!isXul)
						if(e.which==1&&$(e.target).hasClass('mj-gantt-grab')){
							ce._dragStarted={x:e.layerX,y:e.layerY};
							ce.chartBody[0].style.cursor='url('+mj.glb.imagePath+'pt/closedhand.cur'+'),default;';
						}
				});
				ce.chartBody.bind('mouseup',function(e){
					if(e.which==1&&$(e.target).hasClass('mj-gantt-grab')){
						ce._dragStarted=false;
						ce.chartBody[0].style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
					}
				});
				ce.chartBody.bind('mouseout',function(e){
					if(e.which==1&&$(e.target).hasClass('mj-gantt-grab')){
						ce._dragStarted=false;
						ce.chartBody[0].style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
					}
				});
				ce.chartBody[0].style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
				ce.chartBody.bind('mousemove',function(e){
					if(ce._dragStarted){
						var _x = ce._dragStarted.x-e.layerX, _y = ce._dragStarted.y-e.layerY;
						ce.chartBody[0].scrollLeft += _x;
						ce.chartBody[0].scrollTop += _y;
					}
				});
			}
			if(t.drawResourcesPane){
				d.canvasCnt.bind('mousemove',t,function(e){
					var scope = e.data,p={x:e.layerX,y:e.layerY},iDiv=scope.domEls.canvasInfo;
					var vs = function(h,v){return v/h;};
					var ch = scope.ctx.canvas.offsetHeight;
					var bul = function(item){
						var y = item.max>0?(ch+20 - (item.h/vs(ch,item.max))):item.y
						return item.x < p.x && item.x+item.w>p.x && y < p.y && y+(item.h/vs(ch,item.max))>p.y;
					};
					var current = scope.canvasItemsDraw.points.filter(bul,false,0), l=current.length;
					if(l>0){
						var _cDetails =[];
						for(var i=0;i<l;i++)
							_cDetails.push('<span style="color:'+('rgb('+current[i].fs.substr(5,current[i].fs.lastIndexOf(',')-5)+')')+'">'+current[i].type+'&nbsp;'+current[i].h+'</span>');
						iDiv.removeClass('mj-invisible').html(_cDetails.join('<br>'));
					}else
						iDiv.addClass('mj-invisible');
				});
				d.canvas = $('canvas',d.canvasCnt).get(0);
				if ($.browser.msie)
					d.canvas = window.G_vmlCanvasManager.initElement(d.canvas);
				t.ctx = d.canvas.getContext("2d");
			}
			ce.taskPreviewPane = $(mj.NE(re.cnt, {cls:'mj-gantt-task-preview',style:'width:'+(t.chartWidth-fcw-scrollerSize-6)+'px;height:'+(resHeight-5)+'px;left:'+(fcw+1)+'px;'}));
			$(t.grids.gorev.cnt[0].lastChild.firstChild).hover(function(){
				if(!t.layouts.chart.regions.south.collapsed)
					ce.taskPreviewPane.show();
			},function(){
				if(!t.layouts.chart.regions.south.collapsed)
					ce.taskPreviewPane.hide();
			});

			t.tasks = t.stores.grid.data;

			t.lastColorIndex = 0;
			t.windows.detay = $(n(_cnt,{cls:'mj-gantt-task-detail', style:'display:none;width:'+t.chartWidth+'px;height:'+t.height+'px;z-index:100'}));
			
			t.windows.detay.isActive = false;
			t.setActiveRegion('body');
			
			t.windows.detay._els = {center:$(n(t.windows.detay,{cls:'mj-gantt-task-detail-center',style:'width:'+t.chartWidth+'px;height:'+(t.height-30)+'px;'})), south:$(n(t.windows.detay,{cls:'mj-gantt-task-detail-south',style:'width:'+t.chartWidth+'px;'}))};
			var _btnCnt = n(t.windows.detay._els.south, {style:'float:right;padding:1px;'});
			t.windows.detay._buttons = {
				'vazgec':new mj.button({renderTo:n(_btnCnt), title:'Vazgeç', iconCls:'mj-menu-close-icon', handler:function(){
					if(t.activeRegion != 'message'){
						if(t.forms.tForm.modified){
							t.setActiveRegion('message');
							mj.shortcuts.on('e', function(){
								mj.message.activeMessageWin.close();
								t.hideDetayWindow();
								t.focusFakeInput();
							});
							mj.shortcuts.on('h', function(){
								t.setActiveRegion('detaywindow');
								mj.message.activeMessageWin.close();
							});
							mj.shortcuts.on('k', function(){
								mj.message.activeMessageWin.close();
								t.windows.detay._buttons.kaydet.handler.call(t);
							});
							mj.message.defaults.buttonTitles.SAVEANDEXIT = 'Kaydet ve Çık';
							mj.message({
								title:'Uyarı',
								modal : true,
								msg:'Yaptığınız değişiklikler kaydedilmeden çıkılsın mı?',
								buttons:['NO','YES','SAVEANDEXIT'],
								cb:function(el,btn){
									if(btn=='YES'){
										t.hideDetayWindow();
										t.focusFakeInput();
									}else if(btn=='SAVEANDEXIT'){
										mj.message.activeMessageWin.close();
										t.windows.detay._buttons.kaydet.handler.call(t);
									}else
										t.setActiveRegion('detaywindow');
									el.window.close();
								}
							});
							mj.message.activeMessageWin.on('beforeclose', function(){
								mj.shortcuts.mon('e');
								mj.shortcuts.mon('h');
								mj.shortcuts.mon('k');
							});
						}else{
							t.hideDetayWindow();
							t.focusFakeInput();
						}
					}
				}}),
				'kaydet':new mj.button({renderTo:n(_btnCnt), title:'Kaydet', iconCls:'mj-accept', handler:function(){
					if(t.forms.tForm.modified){
						if(t.forms.tForm.recMode == 'edit')
							t.updateTask();
						else
							t.createTask();
					}
					t.hideDetayWindow();
					t.focusFakeInput();
				}})
			};
			t.stores['dieGroup'] = new mj.store({url : t.url,params : {event : 'getdieGroup', table : 'dieGroup'}});
			t.forms.tForm = new mj.form({
				renderTo : t.windows.detay._els.center,
				items : [
					new mj.form.fieldSet({
						id : 'fsGorev',
						title : 'Görev Detayları',
						items : [
							// new mj.form.textField({
								// title : 'Görev',
								// dataIndex : 'name',
								// labelWidth : '110px',
								// readOnly : true,
								// width : 150
							// }),
							///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							new mj.form.triggerField({
								triggerClass:'trigger-field',
								title : 'Görev',
								dataIndex : 'name',
								labelWidth : '110px',
								width : 150,
								handler : function(){
									t.forms.tForm.dataFilterTrigger = new mj.dataFilterTrigger({
										filterEvent : 'getDieTriggerList',
										url : t.url,
										table : 'die',
										width : 500,
										fields : [
											{header: "Id", dataIndex: 'dieId', width: 50},
											{header: "Kod", dataIndex: 'code', width: 100,filter:'single',table:'die'},
											{header: "Türü", dataIndex: 'dieGroupCode', width: 100, filter:'single', type:'combo',store:t.stores['dieGroup'],table:'diegroup',filterIndex:'id'},
											{header: "TürId", dataIndex: 'dieGroupId', hide:true},
											{header: "TürAd", dataIndex: 'dieGroupName', hide:true},
											{header: "Ad", dataIndex: 'name', width: 150,filter:'single',table:'die'},
											{header: "Açıklama", dataIndex: 'description', width: 150,filter:'single',table:'die'}
										],
										returns : {
											el : t.forms.tForm.items[0].items[0],
											values : [
												{
													name : 'dieId'
												},{
													name : 'description'
												}
											]
										}
									});
									t.forms.tForm.dataFilterTrigger.show();
								}
							}),
							new mj.form.numberField({
								title : 'Operasyon',
								dataIndex : 'leafId',
								labelWidth : '110px',
								width : 150,
								defaultZero : false,
								hidden : true
							}),
							///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							new mj.form.combo({
								title : 'İstasyon',
								dataIndex : 'station',
								mode : 'local',
								store : t.stores.station,//t.stores.activeStation,
								width : 150,
								displayField : 'name',
								labelWidth : '110px'
							}),
							new mj.form.combo({
								title : 'Müşteri',
								dataIndex : 'customer',
								mode : 'local',
								clearOnTriggerClick : true,
								store : t.stores.customer,//t.stores.activeStation,
								width : 150,
								displayField : 'code',
								labelWidth : '110px'
							}),
							// new mj.form.numberField({
								// title : 'Öteleme',
								// dataIndex : 'lag',
								// labelWidth : '110px',
								// width : 150,
								// decimalPrecision:0,
								// decimalPrecisionReal:0,
								// suffix:'',
								// defaultZero : false,
								// allowDecimals:false					
							// }),
							new mj.form.numberField({
								title : 'Ayar Süresi(dk)',
								dataIndex : 'setup',
								labelWidth : '110px',
								width : 150,
								defaultZero : false
							}),
							new mj.form.numberField({
								title : 'Br. Ürt. Sür.(sn)',
								dataIndex : 'tpp',
								labelWidth : '110px',
								width : 150,
								money : true,
								suffix : '',
								decimalPrecision : 3,
								defaultZero : false	
							}),
							new mj.form.numberField({
								title : 'Üretim Sayısı',
								dataIndex : 'production',
								labelWidth : '110px',
								width : 150,
								defaultZero : false
							}),
							new mj.form.numberField({
								title : 'Operatör Sayısı',
								dataIndex : 'operator',
								labelWidth : '110px',
								width : 150,
								defaultZero : false	
							}),
							new mj.form.numberField({
								title : 'Kasa İçi Miktar',
								dataIndex : 'inBox',
								labelWidth : '110px',
								width : 150,
								defaultZero : false
							}),
							new mj.form.checkBox({
								title : 'Deneme Üretimi',
								labelWidth : '110px',
								dataIndex : 'sampleProduction'
							})
						]
					}),
					new mj.form.fieldSet({
						id : 'fsGorevGerceklesen',
						title : 'Gerçekleşen Değerler',
						items : [
							new mj.form.numberField({
								title : 'Operatör Sayısı',
								dataIndex : 'actualOperator',
								labelWidth : '110px',
								width : 80,
								defaultZero : false
							})
							,new mj.form.dateField({
								title : 'Ayar Başlangıç',
								epoch : true,
								labelWidth : '110px',
								dataIndex : 'doneStartDate1',
								itemStyle : '',
								width : 80
							})
							,new mj.form.timeField({
								title : '-',
								labelWidth : '10px',
								right : true,
								itemStyle : 'width:70px;',
								dataIndex : 'doneStartDate2',
								width : 50
							})
							,new mj.form.dateField({
								title : 'Ayar Bitiş',
								epoch : true,
								labelWidth : '110px',
								dataIndex : 'doneSetupFinishDate1',
								width : 80
							})
							,new mj.form.timeField({
								title : '-',
								labelWidth : '10px',
								right : true,
								itemStyle : 'width:70px;',
								dataIndex : 'doneSetupFinishDate2',
								width : 50
							})
							,new mj.form.dateField({
								title : 'Üretim Bitiş',
								epoch : true,
								labelWidth : '110px',
								dataIndex : 'doneFinishDate1',
								width : 80
							})
							,new mj.form.timeField({
								title : '-',
								labelWidth : '10px',
								right : true,
								itemStyle : 'width:70px;',
								dataIndex : 'doneFinishDate2',
								width : 50
							})
							,new mj.form.checkBox({
								title : 'Üretim Sonlandı',
								labelWidth : '110px',
								dataIndex : 'finished'
							})
						]
					}),
					new mj.form.fieldSet({
						id : 'fsMiktar',
						title : 'Üretim Miktarları'
					})
				]
			});
			t.forms.tForm._dieTriggerField = t.forms.tForm.items[0].items[0];
			t.forms.tForm._leafId = t.forms.tForm.items[0].items[1];
			t.forms.tForm._dieTriggerField.on('dataselect', function(triggerEl, data){
				var form = t.forms.tForm;
				form.setValue({
					setup : parseInt(data.setup/60),
					tpp : parseFloat(data.production),
					customer : parseInt(data.customerId),
					station : parseInt(data.stationId),
					inBox : parseInt(data.inBox),
					operator : parseInt(data.operatorCount)
				});
				form._leafId.setValue(data.firstLeafId);
				form._productionDetails = eval(data.productionDetails);
				form.newTask = {productionDetails : form._productionDetails, description:data.description, stations : eval(data.stations), dieId:parseInt(data.id)};
				t.createProductionDetailsForm(form.newTask);
			});
			
			t._window.addRelated(t.forms.tForm);
			var form = t.forms.tForm, edtSetup = form.getField(3), edtTpp = form.getField(4), edtProduction = form.getField(5);
			n(form.fieldSets[2].fieldSetEl, {html : '<div style="float:left;width:120px;height:15px;">'+mj.insertSpacer(120,15)+'</div><div style="float:left;width:50px;height:15px;">Üretim</div><div style="float:left;width:18px;height:15px;">'+mj.insertSpacer(18,15)+'</div><div style="float:left;width:120px;height:15px;">Iskarta</div><div style="clear">&nbsp;</div>'});
			t._productionCountCnt = $(n(form.fieldSets[2].fieldSetEl,{style:'clear:both'}));
			var invalidFn = function(edt, msg){
				mj.message({
					title : 'Bilgi',
					msg : msg,
					modal : true
				});
			};
			edtSetup.on('invalid', invalidFn);
			edtTpp.on('invalid', invalidFn);
			edtProduction.on('invalid', invalidFn);
			t.cM = new mj.contextmenu({
				renderTo : n(),
				parent : t.domEls.chartEls.chartBody,
				canHide : true,
				style : 'vertical',
				width : 150,
				items : [
					{title:'Geri Al',iconCls:'mj-menu-delete-icon',scope:t,handler:function(){
						if(typeof this.undoStation == 'function')
							this.undoStation();
					} },'|',
					{title:'Yakınlaştır',iconCls:'mj-zoom-in',scope:t,handler:t.zoomIn},
					{title:'Uzaklaştır',iconCls:'mj-zoom-out',scope:t,handler:t.zoomOut}
				]
			});
			t._window.addRelated(t.cM);
			t.getStation();
			t.fillStation();
			t.fillChartTimeline();
			t.fillOpMeter();
			t.initGanttData();
			t.getOffTime();
			t.drawOffTime();
			t.drawCurrentTimeLine();

			t.hiddenElements = n(ce.header, {style:'position:absolute;top:-10000px;left:-100000px; display:none'});
			t.fakeInput = n(t.hiddenElements, {tag:'input'});
			t.ajaxForm = new mj.form({renderTo:n(t.hiddenElements), url : t.url});
			t._window.addRelated(t.ajaxForm);
			t.focusFakeInput();

			t._ganttTrigger = function(){
				if(this != arguments.callee._oScope){
					return arguments.callee.apply(arguments.callee._oScope, arguments);
				};
				var triggerFn = function(){
					if(this != arguments.callee._oScope){
						return arguments.callee.apply(arguments.callee._oScope, arguments);
					};
					t._ganttTrigger();
				};
				triggerFn._oScope = t;
				var timeResolution = parseInt(t.time.ms/t.timeIntervalWidth);//1000;
				timeResolution = timeResolution < t.minResolution ? t.minResolution : timeResolution;
				timeResolution = timeResolution > t.maxResolution ? t.maxResolution : timeResolution;
				t.updateTaskInterval = timeResolution;
				t._timer=setTimeout(triggerFn,timeResolution);
				var _t = t.curTimeMs += timeResolution;
				t.curTime = new Date(_t);
				//t.curTime = new Date();
				var _t = t.curTimeMs = t.curTime.getTime();
				t.drawCurrentTimeLine.call(t);
				for(var i in t.station)
					if(typeof t.station[i] != 'function' && t.station[i].lastTime.getTime()<_t)
						t.station[i].lastTime.setTime(_t);
				if(t.liveUpdate)
					for(var i in t.tasks)
						//if(typeof t.tasks[i] != 'function' && ((t.tasks[i].modifyTime>_t || t.tasks[i].drawZoomLevel!=t.timeIntervalIndex) || !t.tasks[i].drawTime || (!t.tasks[i].done.setupFinishDate && t.tasks[i].drawTime<_t)))
						if(typeof t.tasks[i] != 'function' && t.tasks[i].done)
							t.drawTaskDone(t.tasks[i]);
			};
			t._ganttTrigger._oScope = t;
			t._ganttTrigger();
			t.updateTaskValues._oScope = t;
			t.updateTaskValuesCb._oScope = t;
			if(t.liveUpdate)
				t.startLiveUpdate();
			t.gotoNow();
			t.grids.gorev.load();
			ce.chartBody.scroll(function(e){
				ce.header[0].scrollLeft = e.target.scrollLeft;
				ce.stationsCnt[0].scrollTop = e.target.scrollTop;
				re.cntScroller[0].scrollLeft = e.target.scrollLeft;
			});
			t.bindShortcuts();
			var w = t._window;
			w.on('beforeclose', function(){
				if(t.modified && t.modified.length>0){
					mj.message({
						title:'Uyarı',
						modal : true,
						msg:'Yaptığınız değişiklikler kaydedilmeden çıkılsın mı?',
						buttons:['NO','YES'],
						cb:function(el,btn){
							if(btn=='YES'){
								t.modified = false;
								t.dropEls = false;
								t.stopLiveUpdate();
								w.close();
							}
							el.window.close();
						}
					});
					return false;
				}
				t.dropEls = false;
				t.stopLiveUpdate();
			});
			t.gotoNow();
			t.waitMaskHide();
		},10);
	},
	addOffTimeTick : function(sd,durMs){
		var t=this;
		var addMs=durMs;
		var fd = sd + durMs;
		for(var i=0,len=t.offTimeTick.length;i<len;i++){
			var off = t.offTimeTick[i];
			if((sd<=off.start&&fd>=off.finish)||(fd>=off.start&&fd<=off.finish)){
				addMs += off.finish - off.start;
				fd+=off.finish - off.start;
			}else if(fd<off.start)
				break;
		}
		return addMs;
	},
	addOffTimeTickReverse : function(fd,durMs){
		var t=this;
		var addMs=durMs;
		var sd = fd - durMs;
		for(var i=0,len=t.offTimeTick.length;i<len;i++){
			var off = t.offTimeTick[i];
			if(fd<off.start)
				break;
		}
		if(i<len)
			for(var j=i;j>=0;j--){
				var off = t.offTimeTick[j];
				if((sd<=off.start&&fd>=off.finish)||(fd>=off.start&&fd<=off.finish)){
					addMs += off.finish - off.start;
					sd-=off.finish - off.start;
				}else if(sd>off.finish)
					break;
			}
		return addMs;
	},
	ajaxSuccess : function(data){
		this.waitMaskHide();
		if(data.msg!='')
			this.showQuickMsg(data.msg);
		mj.removeModified(this);
	},
	ajaxFailure : function(){
		this.waitMaskHide();
		if(data.msg!='')
			mj.message(data.msg);
	},
	arrangeTask : function(e,task,station,t){
		var left = e.proxy[0].offsetLeft;
		var time=t.checkStationTask(task,station,t.getTimeFromPx(left));
		if(time){
			e.proxy.css('left',t.getPxFromTime(time));
			task.startDate.setTime(time);
			t.calculateTask(task);
			t.calculateTaskSizes(task);
			t.setTaskLeftWidth(task,task.times.actualDuration);	
			if (task.times.finishDate>station.lastTime.getTime()){
				station.lastTime.setTime(task.times.finishDate);
			}
			t.setTaskValue(task);
		}else
			e.proxy.css('left',t.getPxFromTime(task.startDate.getTime()));
		var nt = t.getDependTasks(task);	
		for(var i=0,len=nt.length;i<len;i++){
			var ct = nt[i];
			if(ct.planned){
				var time=t.checkStationTask(ct,t.station[ct.station],ct.startDate.getTime());
				if(time)
					$(ct.el).css('left',t.getPxFromTime(time));
			}
		}
	},
	assignTaskToStation : function(task,station,t){
		if(!task.planned || task.station!=station.id)
			task.startDate = new Date(t.getTaskStartDate(task,station));
		t.calculateTask(task);
		t.calculateTaskSizes(task);
		t.drawTaskToStation(task,station);
		t.setTaskLeftWidth(task,task.times.actualDuration);
		if(station.lastTime.getTime()<task.times.finishDate)
			station.lastTime.setTime(task.times.finishDate);
		task.station = station.id;
		task._station = station;
		if(typeof t.refreshed == 'undefined')
			station.task.push(task);
		var tasks = station.task;
		tasks._sort('startDate');
		for(var i=0,l=tasks.length;i<l;i++)
			tasks[i].order = i;
		//task.order = station.task.length-1;
		task.planned = true;
		t.saveStation(station);
		t.drawTaskDone(task,station);
		t.drawResources();
	},
	backupStation : function(station){//eksik
		return false;
		var t=this, _backup = [];
		tasks=station.task;
		for(var i=0,l=tasks.length;i<l;i++)
			_backup.push(tasks[i].times.startDate);
		station._backup = _backup;
	},
	bindTaskContextMenu : function(task){
		var t = this;
		task.el.bind('mousedown', function(e){
			t._contextTask = task;
		});
		if(!t.taskCM){
			t.taskCM = new mj.contextmenu({
				renderTo : mj.NE(),
				//parent : task.el,
				_dontBindParent : true,
				canHide : true,
				style : 'vertical',
				width : 130,
				items : [
					{title:'Geri Al',iconCls:'mj-menu-close-icon',handler:function(){
						if(typeof t.undoStation == 'function')
							t.undoStation();
					}},'|',
					{title:'Sil',iconCls:'mj-menu-delete-icon',handler:function(){
						if(typeof t.removeTask == 'function')
							t.removeTask(t._contextTask);
					} },'|',
					{title:'Sabitle',handler:function(){
						if(t._contextTask.pinned)
							t.unpinTask(t._contextTask);
						else
							t.pinTask(t._contextTask);
					}}
				]
			});
			t.taskCM.on('show', function(){
				var btn = t.taskCM.buttons[2];
				if(t._contextTask.pinned){
					btn.setTitle('Aç');
					btn.els.ci.removeClass('mj-lock');
					btn.els.ci.addClass('mj-unlock');
				}else{
					btn.setTitle('Sabitle');
					btn.els.ci.removeClass('mj-unlock');
					btn.els.ci.addClass('mj-lock');
				}
			});
			t._window.addRelated(t.taskCM);
		}
		t.taskCM.bindParent(task.el);
	},
	bindInfoPane : function(task){
		var t = this, infoPane = t.domEls.chartEls.infoPane;
		task.el.bind('mouseout', function(){
			if(window.activeTimer)
				clearTimeout(window.activeTimer);
			infoPane.fadeOut(250);
		});
		task.el.bind('mouseover', {task:task}, function(e){
			var task = e.data.task;
			t.showTaskQuickInfo(task);
		});
	},
	bindShortcuts : function(){
		var t = this, sOn = mj.shortcuts.on;
		sOn('esc', function(){
			if(t.activeRegion=='message'){
				mj.message.activeMessageWin.close();
				t.focusFakeInput();
			}else if(t.windows.detay.isActive)
				t.windows.detay._buttons.vazgec.handler.call(t);
			else if(t.filterInputs.isActive){
				t.focusFakeInput();
				t.grids.gorev.selectRow(t.grids.gorev, 0);
				t.setActiveRegion('grid');
			}
		});
		sOn('f5', function(){
			t.grids.gorev.pbar.refresh();
		});
		sOn('ctrl+f', function(){
			var l1 = t.layouts.west, r1 =l1.regions['south'], l2 = t.layouts.main, r2 =l2.regions['west'];
			if(r2.collapsed)
				l2._toggleRegion('west',false);
			if(r1.collapsed)
				l1._toggleRegion('south',false);
			t.filterInputs.op1.focus();
		});
		sOn('ctrl+q', function(){
			if(!t.time.min)
				t.zoom(-1);
		});
		sOn('ctrl+w', function(){
			if(!t.time.max)
				t.zoom(1);
		});
		sOn('f2', function(){
			if(t.activeRegion=='detaywindow'&&!mj.message.activeMessageWin){
				t.windows.detay._buttons.kaydet.handler.call(t);
			}
		});
		sOn('ctrl+l', function(){
			t.labelsShowHide();
		});

		// window.onbeforeunload = function() {
			// if(t.modified && t.modified.length>0)
				// return "Yaptığınız değişiklikleri kaydetmeden çıkmak istediğinize emin misiniz?";
		// };
		// mj.on('unload', function(){
			// if(t.modified && t.modified.length>0)
				// return "Yaptığınız değişiklikleri kaydetmeden çıkmak istediğinize emin misiniz?";
		// });
	},
	calculateBoxes : function(){
		var t=this;
		if(t.drawResourcesPane){
			var item=t.canvasItemsDraw.kasa.items,i=-1,bs="rgba(0, 0, 255, 0.3)";
			while(++i<item.length){
				item[i].points=[];
				item[i].l=false;
				item[i].fs=bs;
			}
			t.ticks = [];
			t.ticks.push({tick:t.firstDate.getTime(),box:0});
			for(var index in t.station){
				var st = t.station[index]; 
				if(typeof st=='object'){
					for(var i=0,len=st.task.length;i<len;i++ ){
						var task = st.task[i];
						if(task.planned){
							t.ticks.push({tick:task.startDate.getTime(),box:0});
							var newTime = task.startDate.getTime()+(task.times.actualSetup);
							t.ticks.push({tick:newTime,box:1});
							var boxInterval = task.inBox*task.tpp*t.durationMsMultiplier;
							var prod=task.inBox;
							while(prod<=task.production){
								newTime += t.addOffTimeTick(newTime, boxInterval);
								prod += task.inBox;
								t.ticks.push({tick:newTime,box:1});
							}
							if(newTime<task.times.finishDate)
								t.ticks.push({tick:task.times.finishDate,box:0});
						}
					}	
				}
			}
			t.ticks.sort(function(a,b){
				return a.tick-b.tick;
			});
			var lastPoint = t.firstDate.getTime();
			var tick,width=0,height=0,left=0,totalBox = 0;
			for(var i=0,len=t.ticks.length;i<len;i++){
				tick = t.ticks[i];
				height = totalBox * t.heightPerBox;
				width = (((tick.tick-lastPoint)*this.timeIntervalWidth)/this.time.ms);
				//burada kasa tipi bulunup o kasa tipinin noktalarının arrayine eklenecek
				//şimdilik 1. nolu kasa tipine ekliyoruz hepsini
				item[0].points.push({x:left,y:t.ctx.canvas.height-height,w:width,h:height,fs:bs,l:item[0].l,type:'Kasa'});
				lastPoint = tick.tick;
				totalBox += tick.box;
				left += width;
			}
		}
	},
	calculateOperators : function(){
		var t=this;
		if(t.drawResourcesPane){
			var item=t.canvasItemsDraw.personel.p;
			item.points=[];
			t.ticks = [];
			t.ticks.push({tick:t.firstDate.getTime(),operator:0});
			for(var index in t.station){
				var st = t.station[index]; 
				if(typeof st=='object'){
					for(var i=0,len=st.task.length;i<len;i++ ){
						var task = st.task[i];
						if(task.planned){
							t.ticks.push({tick:task.times.startDate,operator:task.operator});
							t.ticks.push({tick:task.times.finishDate,operator:(task.operator*(-1))});
						}
					}	
				}
			}
			t.ticks.sort(function(a,b){
				return a.tick-b.tick;
			});
			var lastPoint = t.firstDate.getTime();
			var tick,width=0,height=0,left=0,totalOperator = 0,os="rgba(255, 0, 0, 0.5)";
			t.fillVardiya();
			if(item.d){
				item.fs = os;
				for(var i=0,len=t.ticks.length;i<len;i++){
					tick = t.ticks[i];
					height = totalOperator ;
					width = (((tick.tick-lastPoint)*this.timeIntervalWidth)/this.time.ms);
					item.points.push({x:left,y:t.ctx.canvas.height-height,w:width,h:height,fs:os,l:item.l, type:'Gerekli Operatör Sayısı'});
					lastPoint = tick.tick;
					totalOperator += tick.operator;
					left += width;
				}
			}
		}
	},
	calculateTask : function(task){
		if(!task.times || !task.loading){
			var t = this, tt = task.times = {
				startDate : t.shiftStartForOffTime(task.startDate.getTime()),
				lag : (task.lag||0) * t.durationMsMultiplier,
				setup : task.setup * t.durationMsMultiplier,
				tpp : task.tpp * t.durationMsMultiplier
			};
			task.startDate.setTime(tt.startDate);
			tt.productionDuration = parseInt(task.production * tt.tpp);
			tt.duration = tt.lag + tt.setup + tt.productionDuration;
			tt.actualLag = t.addOffTimeTick(tt.startDate, tt.lag);
			tt.setupStartDate = t.shiftStartForOffTime(tt.startDate + tt.actualLag);
			tt.actualSetup = t.addOffTimeTick(tt.setupStartDate, tt.setup);
			tt.productionStartDate = t.shiftStartForOffTime(tt.setupStartDate + tt.actualSetup);
			tt.actualProductionDuration = t.addOffTimeTick(tt.productionStartDate, tt.productionDuration);
			tt.productionFinishDate = t.shiftStartForOffTime(tt.productionStartDate + tt.actualProductionDuration);
			tt.actualDuration = tt.actualLag + tt.actualSetup + tt.actualProductionDuration;
			tt.finishDate = tt.startDate + tt.actualDuration;
		}
	},
	calculateTaskSizes : function(task){
		var t = this, tt = task.times, ts = task.sizes = {}, maxWidth = t.grids.gorev.cm[1].width-13, _scale = maxWidth/t._maxDuration;
		ts.gridElWidth = parseInt(_scale*tt.duration);
		ts.gridSetupElWidth = parseInt(_scale*tt.setup);
		ts.gridProductionElWidth = ts.gridElWidth - ts.gridSetupElWidth;
		var _timeScale = t.timeIntervalWidth/t.time.ms;
		ts.elWidth = parseInt(_timeScale * tt.actualDuration)-1;
		ts.setupElWidth = parseInt(_timeScale * tt.actualSetup)-1;
		ts.lagWidth = parseInt(_timeScale * tt.actualLag);
		ts.productionElWidth = ts.elWidth - (ts.setupElWidth - ts.lagWidth);
	},
	clearChartComponents : function(){
		var t = this, de = t.domEls, ce = de.chartEls, he = ce.headers;
		he.line1.empty();
		he.line2.empty();
		he.line3.empty();
		for(var i=0,len=t.offTimeTick.length;i<len;i++)
			if(t.offTimeTick[i].el){
				$(t.offTimeTick[i].el).remove();
				t.offTimeTick[i].el = false;
			}
	},
	checkDependTasks : function(task){//?
return;
		// var t=this,tasks=t.tasks;
		// for(var i = 0, len = tasks.length; i < len; i++){
			// if(tasks[i]['predecessor']==task.id)
				// t.checkTaskStatus(tasks[i]);
		// }
	},
	checkStationLastTime : function(station){
		if(station.task.length>0)
			station.lastTime.setTime(station.task[station.task.length-1].times.finishDate);
	},
	checkStationTask : function(task,station,time){
		var t=this,isOn=false,curOrder = -1;
		switch(task.dragType){
			case 'move' :
				break;
			case 'station' :
				break;
			case 'shift' :
				break;
			default :
				break;
		}
		return time;
			
		// var t=this,isOn=false,curOrder = -1;
		// var sO=-1,a,s;
		// var xtime=null;
		// var preTask =  t.getTask(task.predecessor);
		// if(preTask&&time<t.getPreTaskShift(task,preTask)){
			// time = t.getPreTaskShift(task,preTask);
		// }
		// var _start = task.startDate.getTime();
		// task.startDate.setTime(time);
		// t.calculateTask(task);
		// var len=station.task.length;
		// xtime = time;
		// if(len>1){
			// for(var i=0,len=station.task.length;i<len;i++){
				// var sTask = station.task[i];
				// if(sTask.id!=task.id&&xtime>=sTask.times.startDate&&xtime<sTask.times.finishDate){
					// isOn=true;
					// xtime = sTask.times.finishDate;
					// task.startDate.setTime(xtime);
					// t.calculateTask(task);
				// }else if(sTask.id!=task.id&&task.times.finishDate>sTask.times.startDate&&task.times.finishDate<sTask.times.finishDate){
					// isOn=true;
					// xtime = sTask.times.finishDate;
					// task.startDate.setTime(xtime);
					// t.calculateTask(task);
				// }
				// if(sTask.id!=task.id&&time<sTask.startDate.getTime()){
					// if(sTask.pinned){
						// if((time+(task.times.actualDuration)>sTask.startDate.getTime())){
							// xtime = sTask.finishDate.getTime();
							// sO = sTask.order+2;
							// break;
						// }
						// else{
							// sO = sTask.order;
							// break;								
						// }						
					// }else{
						// sO = sTask.order;
						// break;					
					// }
				// }
			// }
			// if(sO>-1&&sO<station.task.length){
				// if(sO<task.order){
					// a = sO;
					// s = sO;
				// }	
				// else{	
					// a=task.order;
					// s=task.order
				// }
			// }else{
				// a = station.task.length-1;
				// s = task.order; 
			// }
			// station.task.splice(task.order,1);
			// station.task.splice(a,0,task);
			// if(xtime)
				// time = xtime;
			// time = t.shiftStartForOffTime(time);
			// /*
			// var oldpin = task.pinned;
			// task.pinned =true;
			// t.rearrangeStation(station,s);
			// task.pinned = !!(oldpin);
			// */
			// t.setTaskValue(task);
		// }
		// task.startDate.setTime(_start);
		// t.calculateTask(task);
		// return time;
	},
	checkTaskStatus : function(task){
		var t=this;
		if(task.planned){
			if(!task.color)
				t.getColor(task);
			if($.browser.msie){
				task.gridSetupEl[0].style.background='#ffc';
				if(task.color)
					task.gridProductionEl[0].style.background=task.color;
			}else{
				task.gridSetupEl.css('background','#ffc');
				if(task.color)
					task.gridProductionEl.css('background',task.color);
			}
			task.drag.pause = true;
			t.checkDependTasks(task);
		}
		else{
			if (task.drag)
				task.drag.pause = false;
			// if($.browser.msie){
				// task.gridSetupEl[0].style.background='#8c8';
				// task.gridProductionEl[0].style.background='#0a0';
			// }else{
				// task.gridSetupEl.css('background','#8c8');
				// task.gridProductionEl.css('background','#0a0');
			// }
			task.gridProductionEl.addClass('mj-gantt-task-grid-unplanned-el');
			task.gridProductionEl[0].style.background=null;

			if (task.predecessor){
				var preTask = t.getTask(task.predecessor);
				if(preTask&&preTask.planned!=true){
					if($.browser.msie){
						task.gridSetupEl[0].style.background='#c60';
						task.gridProductionEl[0].style.background='#600';
					}else{
						task.gridSetupEl.css('background','#c60');
						task.gridProductionEl.css('background','#600');
					}
					if (task.drag) task.drag.pause = true;
				}	
			}
			t.checkDependTasks(task);
		}	
	},
	checkTaskOver : function(task, checkTask){
		return	(
			(task.times.startDate>=checkTask.times.startDate && task.times.startDate<=checkTask.times.finishDate) 
			|| 
			(task.times.finishDate>=checkTask.times.startDate && task.times.finishDate<=checkTask.times.finishDate)
			|| 
			(task.times.startDate<=checkTask.times.startDate && task.times.finishDate>=checkTask.times.finishDate)
		);
	},
	clearCanvas : function(){
		this.ctx.save();
		this.ctx.fillStyle = this.canvasColor;
		this.ctx.fillRect(0, 0, this.ctx.canvas.width, this.ctx.canvas.height);
		this.ctx.restore();
	},
	createProductionDetailsForm : function(task){
		var t = this, form = t.forms.tForm;
		var cnt = t._productionCountCnt, productionDetails = task.productionDetails, l = productionDetails.length;
		form.fieldSets[2].fieldSetEl.height(40+(l*23));
		cnt.empty();
		var formItems = [];
		for(var i=0;i<l;i++){
			var pd = productionDetails[i];
			formItems.push(
				new mj.form.numberField({
					title : pd.leafCode,
					dataIndex : 'leafProduction_'+pd.leafId,
					width : 50,
					labelWidth : '110px',
					emptyValue : 0,
					defaultZero : true
				})
			);
			formItems.push(
				new mj.form.numberField({
					title : ' - ',
					dataIndex : 'leafScrap_'+pd.leafId,
					right : true,
					width : 50,
					labelWidth : '10px',
					emptyValue : 0,
					defaultZero : true
				})
			);
		}
		task._pdForm = new mj.form({
			renderTo : cnt,
			items : formItems
		});
		t._window.addRelated(task._pdForm);
	},
	createTask : function(){
		var t = this, form = t.forms.tForm, fv = form.getValue();
		fv.startDate = t.curTimeMs;
		fv.productionDetails = form.newTask.productionDetails;
		fv.name = form.newTask.description;
		fv.dieId = form.newTask.dieId;
		fvJSON = fv.toJSONString();
		t.submit({
			event : 'createTask',
			task : fvJSON,
			success : function(data){
				newTask = mj.apply({ id : parseInt(data.taskId) }, fv);
				newTask = mj.apply(newTask, form.newTask);
				newTask.name = newTask.description;
				newTask.customerId = newTask.customer;
				newTask.startDate = new Date(parseInt(newTask.startDate));
				newTask.modifyTime = t.curTimeMs;
				if(newTask.station){
					newTask._station = t.getStationObject(newTask.station);
					if(newTask.stations.indexOf(newTask.station)==-1)
						newTask.stations.push(newTask.station);
				}
				newTask.pending = [];
				newTask.pinned = false;
				newTask.planned = false;
				newTask.times = false;
				newTask.setup = newTask.setup * 60;
				
				t.calculateTask(newTask);
				t.stores.grid.data.push(newTask);
				t.stores.grid.load();
				t.waitMaskHide();
			}
		}, true);
	},
	deleteTask : function(){
		var t = this, sr=t.grids.gorev.selectedRow;
		if(sr&&sr.data){
			mj.message({
				title:'Onay',
				modal : true,
				msg:'Seçili görevi silmek istediğinizden emin misiniz?',
				buttons:['NO','YES'],
				cb:function(el,btn){
					el.window.close();
					if(btn=='YES'){
						if(sr.data.el)
							t.removeTask(sr.data);
						t.submit({
							event : 'deleteTask',
							task : sr.data.id,
							success : function(data){
								t.stores.grid.data.remove(sr.data);
								t.grids.gorev.load();
								t.waitMaskHide();
							}
						}, true);
					}
				}
			});
		}
	},
	doResize : function(){
		var t = this, _cnt = $(t.layouts.main.getBody('center')), _clientRect = t.layouts.main.renderTo, w = _cnt.width(), h = _cnt.height(), cw = _clientRect.width(), ch = _clientRect.height();
		t.setChartWidth(w, cw);
		t.setChartHeight(h, ch);
	},
	dragOpacityDec : function(station){
		var t=this, tasks = t.station[station].task;
		for(var i=0,l=tasks.length;i<l;i++){
			tasks[i].el.css('opacity', .35);
		}
	},
	dragOpacityInc : function(station){
		var t=this, tasks = t.station[station].task;
		for(var i=0,l=tasks.length;i<l;i++){
			tasks[i].el.css('opacity', .7);
		}
	},
	drawCanvas : function(){
		var t=this;
		if(t.drawResourcesPane){
			var items=t.canvasItemsDraw;
			t.clearCanvas();
			var draw = function(ctx,items,mx){
				var vs = function(h,v){return v/h;};
				var i=-1,item=items.points,ch=ctx.canvas.offsetHeight;
				while(++i<item.length){
					ctx.fillStyle = item[i].fs;
					var x=item[i].x,y=mx>0?(ch +20- (item[i].h/vs(ch,mx))):item[i].y,w=item[i].w,h=item[i].h;
					if(item[i].l){
						if(i==0)
							ctx.moveTo(x,y);
						else
							ctx.lineTo(x,y);
						ctx.lineTo(x+w,y);
						ctx.stroke();
					}
					ctx.fillRect (x, y, w, ch);
				}
			};
			var maxObjVal = function(obj,key){
				var val=-999999999999,i=-1;
				while(++i<obj.length)
					val = obj[i][key]>val?obj[i][key]:val;
				return val;
			};
			var i=-1,v=0;
			items.points = [];
			 for(var el in items)
				if(typeof items[el]!='function'&&el!='max'&&el!='points')
					if(el!='kasa'){
						if(items[el].p.d&&items[el].p.points&&items[el].p.points.length>0){
							v = maxObjVal(items[el].p.points, 'h');
							var pi=-1
							while(++pi<items[el].p.points.length){
								items[el].p.points[pi].max=v;
								items.points.push(items[el].p.points[pi]);
							}
							items[el].p.max=v;
							draw(t.ctx, items[el].p, v);
						}
						if(items[el].g.d&&items[el].g.points&&items[el].g.points.length>0){
							v = maxObjVal(items[el].g.points, 'h');
							var pi=-1
							while(++pi<items[el].g.points.length){
								items[el].g.points[pi].max=v;
								items.points.push(items[el].g.points[pi]);
							}
							items[el].g.max=v;
							draw(t.ctx, items[el].g, v);
						}
					}else{
						while(++i<items[el].items.length){
							if(items[el].items[i].d&&items[el].items[i].points&&items[el].items[i].points.length>0){
								v = maxObjVal(items[el].items[i].points, 'h');
								var pi=-1;
								while(++pi<items[el].items[i].points.length){
									items[el].items[i].points[pi].max=v;
									items.points.push(items[el].items[i].points[pi]);
								}
								items[el].items[i].max=v;
								draw(t.ctx, items[el].items[i], v);
							}
						}
					}
		}
	},
	drawCurrentTimeLine : function(){
		var t=this;
		if(t.liveUpdate){
			var left = t.getPxFromTime(t.curTime);
			if(!t.currentTimeLine)
				t.currentTimeLine = $(mj.NE(t.domEls.chartEls.chartBodyScroll, {style:'position:absolute;top:0px;left:'+ left +'px;opacity:0.7;background:#6f6;z-index:99;border:1px solid #aaa;width:2px;height:'+(t.chartBodyHeight-2)+'px;'}));
			else
				t.currentTimeLine.css('left',left+'px');
		}
	},
	drawResources : function(){
		var t=this;
		if(t.drawResourcesPane && !t.gridloading && !t.layouts.chart.regions.south.collapsed){
			t.calculateOperators();
			t.calculateBoxes();
			t.drawCanvas();
		}
	},
	drawTaskDone : function(task){
		var t=this, n=mj.NE;
		if(task.planned){
			if(task.el && task.done && task.done.setupStartDate && !task.done.finished){
				if(task.doneEls)
					t.redrawTaskDone(task);
				else{
					var station=task._station, de = task.doneEls = {
						doneEl : task.el.clone().appendTo(station.chartEl)
					};
					de.doneEl.css({"position":"absolute","opacity":"1","z-index":"10","top":t.doneBarTop+"px","height":t.doneBarHeight+"px"});
					de.doneSetupEl = de.doneEl.children('div:first');
					de.doneProductionEl = de.doneSetupEl.next();
					de.doneEl.removeClass('mj-opacity-7');
					de.doneSetupEl.removeClass('mj-opacity-7');
					de.doneProductionEl.removeClass('mj-opacity-7');
					de.doneSetupEl.css({'height':t.doneBarHeight, 'background-color':'#ffff6b'});
					de.doneProductionEl.css({'height':t.doneBarHeight, 'background-color':'#fff'});
					de.doneActualSetupEl = $(n(de.doneEl,{style:'height:'+t.doneBarHeight+'px;background-color:#c2c229;position:absolute'}));
					de.doneActualProductionEl = $(n(de.doneProductionEl,{style:'height:'+t.doneBarHeight+'px;background-color:#aed68f;'}));
					de.doneEl.bind('dblclick',{scope:t,task:task},t.getTaskForm);
					de.doneEl.bind('mouseout', function(){
						if(window.activeTimer)
							clearTimeout(window.activeTimer);
						t.domEls.chartEls.infoPane.hide();
					});
					de.doneEl.bind('mouseover', {task:task}, function(e){
						var task = e.data.task;
						t.showTaskQuickInfo(task);
					});
					de.stopCnt = $(n(de.doneEl));
					t.redrawTaskDone(task);
				}
			}
			task.doneElExists = task.el && task.done && task.done.setupStartDate && !task.done.finished;
			if(task.doneElExists){
				task.titleCnt = task.doneEls.doneEl;
				task._titleAbsolute = false;
			}else{
				var l = task.left ? task.left : t.getPxFromTime(task.times.startDate);
				task.titleCnt = $(n(task._station.chartEl,{style:'position:absolute;left:'+l+'px;top:8px;z-index:10;'}));
				task._titleAbsolute = true;
			}
			if(task.titleEl)
				task.titleEl.remove();
			if(t.displayLabels){
				var titleLeft = 5, titleTop = -5, tn = task.name;
				task.titleEl = $(n(task.titleCnt,{cls:'mj-unselectable', style:'white-space:nowrap;font-size:11px;font-weight:bold;color:#1d1d1d;display:'+(t._labelsOn?'block':'none'),html : '<div style="height: 17px; top: -4px; left: 6px; position: absolute;">'+tn+'</div><div style="height: 17px; top: -4px; left: 4px; position: absolute;">'+tn+'</div><div style="height: 17px; top: -6px; left: 6px; position: absolute;">'+tn+'</div><div style="height: 17px; top: -6px; left: 4px; position: absolute;">'+tn+'</div><div style="height: 17px; top: -5px; left: 5px; position: absolute;color:white;">'+tn+'</div>'}));
				t.setTaskLabelLeft(task, t.getPxFromTime(task.times.startDate));
			}
		}
	},
	drawTaskToStation : function(task,station){
		var t=this;
		task.el = $(task.gridEl).clone().appendTo(station.chartEl);
		t.bindInfoPane(task);
		task.setupEl = task.el.children('div:first');
		task.productionEl = task.setupEl.next();
		if(!task.color)
			t.getColor(task);
		task.gridSetupEl.css('background','#ffc');
		task.gridProductionEl.css('background',task.color);
		if(task.pinned)
			task.el.css('border','1px solid #f00;');
		task.el.css({"position":"absolute","top":t.barTop + "px"});
		task.el.addClass('mj-gantt-task-el');
		task.el.attr('name','task-'+task.id);
		task.el.children('div').attr('name','task-'+task.id);

		task.setupEl.css({ background: "#ffc" });

		task.productionEl.css({ background: task.color });
		//task.productionEl.append('<span style="padding:1px;font-size:10px;color:#fff;font-weight:bold;">'+task.name+'</span>');
		
		task.chartDrag = new mj.drag({
			el:task.el[0],
			parent : station.chartEl,
			appendParent:true, 			
			dragType : 'h',
			proxyOpacity : .7
		});
		task.el.bind('mouseup', function(){
			task.el.css('opacity', 1);
		});
		var _calculateMinMax = function(task, onlyPredecessors){
			var _prev = t.getPreviousTask(task);
			if(!onlyPredecessors){
				var minTime = _prev ? _prev.times.finishDate+(t.time.ms/50) : t.curTime.getTime();
				t.getTaskStartDate(task, task._station);
				if(task._minTime)
					minTime = task._minTime>minTime ? task._minTime : minTime;
			}else
				minTime = task._minTime;
			var _maxStart=false,_maxFinish=false;
			for(var i=0, l = task.pending.length;i<l;i++){
				var pendingTask = task.pending[i], _startLimit = 0, _finishLimit = 0;
				if(pendingTask.planned){
					if(pendingTask.preType=='s')
						_startLimit = pendingTask.times.startDate - (pendingTask.preTime*t.durationMsMultiplier);
					else if (pendingTask.preType=='f')
						_finishLimit = pendingTask.times.startDate - (pendingTask.preTime*t.durationMsMultiplier);
					_maxStart = (_maxStart && _maxStart < _startLimit) ? _maxStart : _startLimit;
					_maxFinish = (_maxFinish && _maxFinish < _finishLimit) ? _maxFinish : _finishLimit;
				}
			}
			return {_maxStart : _maxStart, _maxFinish : _maxFinish, minTime : t.shiftStartForOffTime(minTime)};
		};
		task.chartDrag.on('beforedrag', function(e){
			return !task.pinned && !task.done;
		});
		task.chartDrag.on('dragstart',function(drag, e){
			t._draggingTask = task;
			task.chartDrag.minWidth = false;
			task.chartDrag.maxWidth = false;
			if(e.ctrlKey&&!e.shiftKey){
				task.dragType = 'move';//üzerinden atlama
				var _minmax = task._minmax = _calculateMinMax(task, true);
				task.chartDrag._maxStart = _minmax._maxStart;
				task.chartDrag._maxFinish = _minmax._maxFinish;
			}else if(e.shiftKey&&!e.ctrlKey){
				task.dragType = 'shift';//toplu kaydırma
				var _minmax = task._minmax = _calculateMinMax(task);
				task.chartDrag._maxStart = _minmax._maxStart;
				task.chartDrag._maxFinish = _minmax._maxFinish;
			}else{
				task.dragType = 'default';//sol sağ sınırlara kadar gezdir
				var _minmax = _calculateMinMax(task);
				task.chartDrag._maxStart = _minmax._maxStart;
				task.chartDrag._maxFinish = _minmax._maxFinish;
				task.chartDrag.minWidth = t.getPxFromTime(_minmax.minTime);
			}
			t.dragOpacityDec(task.station);
			task._dragFirstDate = t.firstDate.getTime();
			task._dragMsFactor = t.time.ms/t.timeIntervalWidth;
			task._dragPx = function(px){
				var ms = px*task._dragMsFactor, mod = ms % t.durationMsMultiplier;
				return task._dragFirstDate+(ms-mod);
			};
		});
		var _getMax = function(task, x, pWidth, cPos, onlyPredecessors){
			var drag = task.chartDrag;
			task.startDate.setTime(cPos);
			t.calculateTask(task);
			pWidth = task.dragType=='move' ? 3 : t.getPx(task.times.actualDuration);
			drag.proxy.width(pWidth);
			var _next = t.getNextTask(task), _max = 0;
			if(_next && !onlyPredecessors)
				_max = _next.times.startDate-task.times.actualDuration-1000;
			_max = t.shiftStartForOffTimeBack(_max+task.times.actualDuration)-task.times.actualDuration;
			if(task.chartDrag._maxStart){
				var _max2 = task.chartDrag._maxStart;
				_max = (_max && _max<_max2) ? _max : _max2;
			}
			if(task.chartDrag._maxFinish){
				var _max2 = task.chartDrag._maxFinish-task.times.actualDuration;
				_max = (_max && _max<_max2) ? _max : _max2;
			}
			return _max;
		};
		task.chartDrag.on('dragmove',function(drag, x, y){
			var pWidth = 0, ce = t.domEls.chartEls;
			switch(task.dragType){
				case 'move' : 
					var cPos = task._dragPx(x), _max = _getMax(task, x, pWidth, cPos, true), _minmax = task._minmax;
					if(_minmax.minTime)
						task.chartDrag.minWidth = t.getPxFromTime(_minmax.minTime);
					if(_max)
						task.chartDrag.maxWidth = t.getPxFromTime(_max);
					break;
				case 'shift' : 
					var cPos = task._dragPx(x), _max = _getMax(task, x, pWidth, cPos);
					var _minmax = task._minmax;
					if(_max && cPos>_max){
						task._minmax = _minmax = _calculateMinMax(task);
						task.chartDrag._maxStart = _minmax._maxStart;
						task.chartDrag._maxFinish = _minmax._maxFinish;
						return t.shiftTasksForward(task, cPos-_max+parseInt(t.time.ms/50));
					}else if(_minmax.minTime && cPos<_minmax.minTime){
						task._minmax = _minmax = _calculateMinMax(task);
						task.chartDrag._maxStart = _minmax._maxStart;
						task.chartDrag._maxFinish = _minmax._maxFinish;
						return t.shiftTasksBack(task, _minmax.minTime-cPos);
					}
					break;
				default : 
					var cPos = task._dragPx(x), _max = _getMax(task, x, pWidth, cPos);
					if(_max)
						task.chartDrag.maxWidth = t.getPxFromTime(_max);
					break;
			}
			var nd = new Date(cPos), infoPane = t.domEls.chartEls.infoPane;
			infoPane.empty();
			var _html = [
				'<table cellpadding="0" cellspacing="0" width="100%"><tr><td align="center" valign="middle">'+
				nd.formatDate('d/m/Y H:i')+
				'</td></tr></table>'
			];
			mj.NE(infoPane,{html:_html.join('')});
			infoPane.show();
		});
		var v=this;
		task.chartDrag.on('dragstop',function(e){
			t.domEls.chartEls.infoPane.hide();
			t._draggingTask = false;
			t.dragOpacityInc(task.station);
			var station = task._station;
			t.arrangeTask(e,this,station,t);
			if(task.dragType=='move'){
				var sd = task.times.startDate, station = task._station, tasks = station.task;
				for(var i=0,l=tasks.length;i<l;i++){
					var cto = t.checkTaskOver(task, tasks[i]);
					if(task!=tasks[i] && cto){
						// task.startDate.setTime(tasks[i].times.startDate);
						// t.calculateTask(task);
						// t.calculateTaskSizes(task);
						// t.setTaskLeftWidth(task,task.times.actualDuration);	
						t.insertTask(task, tasks[i], station);
						break;
					}
				}
				tasks._sort('startDate');
				for(var i=0,l=tasks.length;i<l;i++)
					tasks[i].order = i;
			}else if(task.dragType=='station'){
				// with(task.chartDrag){
					// parent = mj.bd;
					// appendParent = false;
					// moving = false;
					// dragType = 'h';
				// }
				// task.el.css({'top':e.pageY-e.layerY,'left':e.pageX-e.layerX});
			}
			t.checkStationLastTime(station);
			t.setModified(task);
			return false;
		},task);
		task.el.bind('dblclick',{scope:t,task:task},t.getTaskForm);
		task.el.bind('mouseup',function(){
			t.dragOpacityInc.call(t, task.station);
		});
		t.bindTaskContextMenu(task);
	},
	drawOffTime : function(){
		var t=this;
		var height = t.stores.station.data.length*t.cellHeight;
		for(var i=0,len=t.offTimeTick.length;i<len;i++){
			var tick = t.offTimeTick[i];
			var left = t.getPxFromTime(tick.start);
			var width = t.getPx(tick.finish-tick.start);	
			var sdate = new Date(tick.start);
			var fdate = new Date(tick.finish);
			if((sdate<t.firstDate && fdate>t.firstDate &&fdate<t.lastDate)||(sdate>t.firstDate && fdate<t.lastDate)||(sdate>t.firstDate && sdate<t.lastDate &&fdate>t.lastDate)){
				if(!tick.el)
					tick.el=mj.NE(t.domEls.chartEls.chartBody, {cls:'mj-gantt-grab mj-gantt-off-time', style:'left:'+(left)+'px;width:'+(width)+'px;height:'+(height)+'px;',title:tick.name+sdate.formatDate(' [H:i-')+fdate.formatDate('H:i]')});
				else
					$(tick.el).css('left',left+'px').css('width',width+'px');
			}
		}
	},
	editParameters : function(){
		var t = this;
		if(!t.parametersWindow){
			var w = new mj.window({
				renderTo : mj.NE(),
				title : 'Planlama Parametreleri',
				modal : true,
				width : 230,
				height : 350,
				buttons : [
					{iconCls : 'mj-save',title : 'Kaydet',scope:t, handler:function(){
						for(var i=0,l=t.sorter.items.length;i<l;i++)
							t.sorter.items[i].sortItem.value = (t.sorter.items[i].index+1).toString();
						t.ganttParameters._sort('value');
						t.submit({
							event : 'saveGanttParameters',
							autoPlan : t.parametersWindow.autoCheck.getValue(),
							params : t.ganttParameters.toJSONString()
						}, true);
						w.close();
					}},
					{iconCls : 'mj-menu-close-icon',title : 'Vazgeç',scope:t, handler:function(){
						w.close();
					}}
				]
			});
			var n = mj.NE, wb = w.getBody(), checkCnt = n(wb,{style:'margin:2px;'}), cnt = n(wb,{style:'margin:2px;'});
			w.autoCheck = new mj.form.checkBox({
				renderTo : checkCnt,
				title : t.lng.autoPlan,
				labelWidth : 130
			});
			w.autoCheck.setValue(t.autoPlan);
			t.ganttParameters._sort('priority');
			var itemArr = [];
			for(var i=0,l=t.ganttParameters.length;i<l;i++){
				var c = n(cnt, {style:'position:relative;height:24px;'});
				var itemEl = n(c, {html:t.lng[t.ganttParameters[i].name],style:'border:1px solid #336699;background:#efefef;padding:2px;margin:1px;'});
				itemEl.sortItem = t.ganttParameters[i];
				itemArr.push(itemEl);
			}
			t.sorter = new mj.itemSorter({
				sortItems : itemArr
			});
			for(var i=0,l=t.ganttParameters.length;i<l;i++)
				t.sorter.items[i].sortItem = t.ganttParameters[i];
			
			t._window.addRelated(w);
			t.parametersWindow = w;
		}
		var w = t.parametersWindow;
		w.show();
	},
	fillChartTimeline : function(){
		var maxDivCount = 200;
		var t=this, hEls = t.domEls.chartEls.headers, oddEven = t.oddEven;
		var height = t.stores.station.data.length*t.cellHeight;
		t.chartBodyHeight = height;
		t.firstDate.setHours(0,0,0,0);
		t.time = t.timeRangeMap[t.timeRange.indexOf(t.timeInterval)];
		t.timeTop = t.timeRangeMap[t.timeRange.indexOf(t.time.top)];
		t.timeUp = t.timeRangeMap[t.timeRange.indexOf(t.time.up)];
		var minInterval = t.time.ms;
		
		if(!t._lastDateSetted){
			t.lastDate = new Date(t.firstDate.getTime() + (minInterval * maxDivCount));
			if(((t.lastDate.getTime()-t.firstDate.getTime())/minInterval)>=maxDivCount)
				t.lastDate.setTime(t.firstDate.getTime() + (minInterval * maxDivCount));
			t.lastDate.setTime(t.lastDate.getTime() + 86400000);
			t.lastDate.setHours(0, 0, 0, 0);
		}
		t.setTimeLineWidth(t.timeIntervalWidth*((t.lastDate-t.firstDate)/minInterval));
		
		hEls.line3.attr('title', t.time.title);
		
		t.upperTimeInterval = t.timeUp.ms;
		hEls.line2.attr('title', t.timeUp.title);
		
		t.topTimeInterval = t.timeTop.ms;
		hEls.line1.attr('title', t.timeTop.title);
		
		t.timeLine = [];
		t.domEls.chartEls.chartBodyScroll.css('background', 'transparent url('+mj.glb.ganttPath+'?w='+t.timeIntervalWidth+')');
		var _t = t.firstDate.getTime(), curDate = new Date(_t), upDate = new Date(_t), topDate = new Date(_t);
		var bg='#fff';
		var downK = t.time.ms/minInterval, upK = t.timeUp.ms/minInterval, topK = t.timeTop.ms / minInterval, totalStep = (t.lastDate.getTime()-t.firstDate.getTime())/minInterval, j = 0;
		var downTitles = '', upTitles = '', topTitles = '';
		t.time.k = downK;
		t.timeUp.k = upK;
		t.timeTop.k = topK;
		var _getCell = function(timeScope, cDate, pos){
			var longTitle = cDate.formatDate('d/m/Y H:i');
			return {width : t.timeIntervalWidth*timeScope.k-4, longTitle : longTitle, title : '<span title="'+longTitle+'">'+cDate.formatDate(timeScope.f)+'</span>'};
		};
		while (curDate<t.lastDate){
			if(j%topK == 0){
				var oeCls = oddEven ? (parseInt(j/topK) % 2 ? '-o' : '' ) : '';
				var cell = _getCell(t.timeTop, curDate);
				topTitles += '<div class="mj-gantt-header1'+oeCls+' mj-unselectable" style="float:left;border-right:1px solid #aaa;width:'+ cell.width +'px;padding-top:7px;padding-left:3px;height:16px;">'+cell.longTitle+'</div>';
			}
			if(j%upK == 0){
				var oeCls = oddEven ? (parseInt(j/upK) % 2 ? '-o' : '' ) : '';
				var cell = _getCell(t.timeUp, curDate);
				upTitles += '<div class="mj-gantt-header2'+oeCls+' mj-unselectable" style="float:left;border-right:1px solid #aaa;width:'+ cell.width +'px;padding-top:7px;padding-left:3px;height:16px;">'+cell.title+'</div>';
			}
			if(j%downK == 0){
				var oeCls = oddEven ? (parseInt(j/downK) % 2 ? '-o' : '' ) : '';
				var cell = _getCell(t.time, curDate);
				downTitles += '<div class="mj-gantt-header3'+oeCls+' mj-unselectable" style="float:left;border-right:1px solid #aaa;width:'+ cell.width +'px;padding-top:7px;padding-left:3px;height:16px;">'+cell.title+'</div>';
			}
			curDate.setTime(curDate.getTime()+minInterval);
			++j;
		}
		hEls.line1[0].innerHTML = topTitles;
		hEls.line2[0].innerHTML = upTitles;
		hEls.line3[0].innerHTML = downTitles;
	},
	fillOpMeter : function(){//?
		return;
		var t=this;
		if(t.drawResourcesPane){
			var p = new mj.panel({
				renderTo : t.domEls.resEls.header,
				border : false
			});
			t.accordion = new mj.accordion({
				renderTo : p.getBody(),
				active : 0,
				items : [
					// {
						// title : 'Vardiya',
						// titleCls : ''
					// },
					{
						title : 'Personel',
						titleCls : ''
						//,handler : function(){}
					},{
						title : 'Kasa',
						titleCls : ''
						//,handler : function(){}
					}
				]
			});
			var innerLabelWidth = t.accordion.activeItem.width-22;
			var a1 = t.accordion.panels[0].getBody();
			new mj.form.checkBox({
				renderTo : a1,
				title : 'Planlanan',
				checked : t.canvasItemsDraw.vardiya.p.d,
				dataIndex : 'p',
				labelWidth : innerLabelWidth+'px',
				handler : function(){
					t.canvasItemsDraw.vardiya.p.d = !t.canvasItemsDraw.vardiya.p.d;
					t.drawResources();
				}
			});
			new mj.form.checkBox({
				renderTo : a1,
				title : 'Gerçekleşen',
				checked : t.canvasItemsDraw.vardiya.g,
				disabled : true,
				dataIndex : 'g',
				labelWidth : innerLabelWidth+'px',
				handler : function(){
					t.canvasItemsDraw.vardiya.g = !t.canvasItemsDraw.vardiya.g;
					t.drawResources();
				}
			});
			var a2 = t.accordion.panels[1].getBody();
			new mj.form.checkBox({
				renderTo : a2,
				title : 'Planlanan',
				checked : t.canvasItemsDraw.personel.p.d,
				dataIndex : 'p',
				labelWidth : innerLabelWidth+'px',
				handler : function(){
					t.canvasItemsDraw.personel.p.d = !t.canvasItemsDraw.personel.p.d;
					t.drawResources();
				}
			});
			new mj.form.checkBox({
				renderTo : a2,
				title : 'Gerçekleşen',
				checked : t.canvasItemsDraw.personel.g,
				disabled : true,
				dataIndex : 'g',
				labelWidth : innerLabelWidth+'px',
				handler : function(){
					t.canvasItemsDraw.personel.g = !t.canvasItemsDraw.personel.g;
					t.drawResources();
				}
			});
			var a3 = t.accordion.panels[2].getBody();
			var items = t.canvasItemsDraw.kasa.items;
			new mj.form.checkBox({
				renderTo : a3,
				title : 'Tümü',
				checked : t.canvasItemsDraw.kasa.a,
				dataIndex : 'a',
				labelWidth : (innerLabelWidth-15)+'px',
				handler : function(){
					t.canvasItemsDraw.kasa.a = !t.canvasItemsDraw.kasa.a;
					t.canvasItemsDraw.kasa.ts = true;
					var i = -1;
					while(++i<items.length)
						items[i].d=t.canvasItemsDraw.kasa.a;
					var els = $('div.mj-checkbox',a3).not($('div.mj-checkbox:first',a3));
					if(t.canvasItemsDraw.kasa.a)
						els.addClass('mj-checkbox-checked');
					else
						els.removeClass('mj-checkbox-checked');
					t.tsCheck(a3);
					t.drawResources();
				}
			});
			var i=-1;
			while(++i<items.length)
				new mj.form.checkBox({
					renderTo : a3,
					title : items[i].name,
					checked : items[i].d,
					dataIndex : 'kasa'+i,
					labelWidth : (innerLabelWidth-8)+'px',
					handler : function(){
						var ind = t.canvasItemsDraw.kasa.items.getIndex('name',this.title);					
						if(ind!=-1){
							t.canvasItemsDraw.kasa.items[ind].d = !t.canvasItemsDraw.kasa.items[ind].d;
							t.drawResources();
						}
						t.tsCheck(a3);
					}
				});
			t.tsCheck(a3);
			$('div.mj-form-caption',t.domEls.resEls.header).css({'padding-top':'0px','padding-left':'2px','font-size':'8pt','line-height':'18px'});
			$('div.mj-form-item',a3).not($('div.mj-form-item:first',a3)).css({'padding-top':'0px'}).children('.mj-form-caption').css({'padding-left':'10px'});
		}
	},
	filterTasks : function(){
		var t = this.sc, data = t.grids.gorev.store,f=false, op1=t.filterInputs.op1, ref1=t.filterInputs.ref1,ist1=t.filterInputs.ist1,tar1=t.filterInputs.tar1,cust1=t.filterInputs.cust1;
		t.refreshed = true;
		if(op1.value!=''){
			data.filter('name',op1.value,f,true);
			f=true;
		}
		if(t.details.ref && ref1.value!=''){
			var v = t.referans.filter(function(val){
				return val.name.toString().toLowerCase().substring(0,ref1.value.length)===ref1.value.toLowerCase();
			},true);
			data.filter('referans',(v instanceof Array&&v[0])?v[0].id:'',f);
			f=true;
		}
		if(ist1.value!=''){
			data.filter('station',ist1.value,f);
			f=true;
		}
		if(tar1.value!=''){
			var tmp = tar1.value.split('/');
			if(tmp.length==3)
				data.filter('startDate',tar1.value,f);
		}
		if(t.details.customer && cust1.value!=''){
			var v = t.customer.filter(function(val){
				return val.code.toString().toLowerCase().substring(0,cust1.value.length)===cust1.value.toLowerCase();
			},true);
			data.filter('customerId',(v instanceof Array&&v[0])?v[0].id:'',f);
			f=true;
		}
		if(data.data.length==1 && data.data[0].el){
			t.gotoTaskEl.call(t, data.data[0]);
		}
	},
	fillStation : function(){
		var t=this, ce = t.domEls.chartEls;
		var sts = t.stores.station.data;
		var height = sts.length*t.cellHeight;
		t.domEls.chartEls.chartBodyScroll.height(height);
		ce.stationsCnt.empty();
		ce.chartStationBody = mj.NE(ce.stationsCnt, {cls:'mj-unselectable', style:'float:left;background:#ddd;border-right:1px solid #aaa;width:'+ (t.firstColumnWidth) +'px;height:'+(height)+'px;'});
		if(ce.chartRowsBody)
			ce.chartRowsBody.remove();
		ce.chartRowsBody = $(mj.NE(ce.chartBodyScroll, {style:'position:relative;'}));
		t.dropEls = [];
		for (var i=0,len=sts.length;i<len;i++){
			var st = sts[i], _st = t.station[st.id];
			_st.el = mj.NE(ce.chartStationBody, {html : st.name.ellipse(15)+'<div class="mj-gantt-fill-station">'+mj.insertSpacer(10,21)+'</div>',cls:'mj-gantt-station-title',style:'cursor:pointer;text-align:left;padding-left:2px;float:left;border-bottom:1px solid #D3D3D3;width:'+ (t.firstColumnWidth) +'px;height:'+(t.cellHeight-4)+'px;padding-top:3px;',title:'Görevleri otomatik olarak düzenlemek için çift tıklayın'});
			_st.chartEl =  $(mj.NE(ce.chartRowsBody, {name:'station-'+st.id,cls:'mj-gantt-grab',style:'position:absolute;top:'+((i*t.cellHeight))+'px;background:transparent;border-bottom:1px solid #D3D3D3;width:'+t._chartClientWidth+'px;height:'+(t.cellHeight-1)+'px;'}));
			t.dropEls.push(_st.chartEl);
			$(_st.el).bind('dblclick',{station:st.id,scope:t},t.getStationTask);
			
			// _st.chartEl.bind('mouseover', {station:_st, scope:t}, function(e){
				// e.data.scope.labelsShowHide(e.data.station);
			// });
			// _st.chartEl.bind('mouseout', {station:_st, scope:t}, function(e){
				// e.data.scope.labelsShowHide(e.data.station);
			// });
		}		
	},
	fillVardiya : function(){//Vardiyada olması planlanan personel sayısı
		return;
		// var t=this,vardiya=t.stores.vardiya.data,item=t.canvasItemsDraw.vardiya.p,vs="rgba(134, 152, 203, 0.7)";
		// item.points=[];
		// if(item.d){
			// item.fs = vs;
			// for(var i=0,len=vardiya.length;i<len;i++){
				// v = vardiya[i];
				// height = v.personel * t.heightPerOp;
				// width = t.getPx(v.finish.getTime()-v.start.getTime());
				// left = t.getPxFromTime(v.start);
				// item.points.push({x:left,y:t.ctx.canvas.height-height,w:width,h:height,fs:vs,l:item.l,type:'Vardiya Operatör Sayısı'});
			// }
		// }
	},
	focusFakeInput : function(){
		this.fakeInput.focus();
		this.setActiveRegion('body');
	},
	getCustomer : function(i){
		var _i = mj.getIndex(this.stores.customer.data,'id',i);
		if(_i>-1)
			return this.stores.customer.data[_i];
		else
			return {id:0,code:'-'};
	},	
	getColor : function (task){
		return task.color = this.colorGenerator.generate();
	},
	getDependTasks : function(task){//?
		return [];
		// var t=this,tasks=t.tasks,ret=[];
		// for(var i = 0, len = tasks.length; i < len; i++){
			// if(tasks[i]['predecessor']==task.id)
				// ret.push(tasks[i]);
		// }	
		// return ret;
	},
	getNextTask : function(task){
		var next = mj.getIndex(task._station.task, 'order', task.order+1);
		return next>-1 ? task._station.task[next] : false;
	},
	getOffTime : function(){
		var t=this;
		t.offTime.sort(function(a,b){
			return a.start-b.start;
		});
		var i=0;
		while(i<t.offTime.length){
			var curTick = t.offTime[i];
			if(i+1<t.offTime.length&&curTick.finish>=t.offTime[i+1].start){
				if(curTick.finish<t.offTime[i+1].finish)
					curTick.finish = t.offTime[i+1].finish;
				t.offTime.splice(i+1,1);
			}else
				i++;
		}
		for(var i=0,len=t.offTime.length;i<len;i++){
			t.offTime[i].start = parseInt(t.offTime[i].start+'000');
			t.offTime[i].finish = parseInt(t.offTime[i].finish+'000');
		}
		t.offTimeTick = t.offTime;
		/*
		var tempTick = [];
		var fd=t.firstDate.getTime(),ld=t.lastDate.getTime();
		
		for(var i=0,len=t.offTime.length;i<len;i++){
			var x = t.offTime[i];
			switch(x.scope){
				case 'day':
					for(var j=0;j<x.items.length;j++){
						var obj = x.items[j], ts = obj.s*1000,te = obj.e*1000;
						if ((ts>=fd&&ts<ld)||(te>fd&&te<=ld)){
							var start=(ts>fd?ts:fd),finish=(te>ld?ld:te);
							tempTick.push({name:obj.name,start:start,finish:finish});
						}
					}
					break;
				case 'weekday':
					var cdate = new Date(fd);
					var offTime = [];
					for(var j=0;j<x.items.length;j++){
						var obj = x.items[j];
						if(!obj.s)
							var start = 0;
						else{
							var m = /(\d*):(\d*)/.exec(obj.s);
							var start = (m[1]*(60*60*1000))+(m[2]*(60*1000));
						}
						if(!obj.e)
							var finish = 86400000;
						else{
							var m = /(\d*):(\d*)/.exec(obj.e);
							var finish = (m[1]*(60*60*1000))+(m[2]*(60*1000));
						}
						offTime.push({name:obj.name,d:obj.d,s:start,f:finish,gecerlilikBaslangici:obj.gecerlilikBaslangici,gecerlilikBitimi:obj.gecerlilikBitimi});
					}
					ti=24*60*60*1000;
					cdate.setHours(0,0,0,0);
					while (cdate.getTime()<ld){
						var curday = cdate.getTime();
						for(var j=0;j<offTime.length;j++){
							var obj = offTime[j];
							if(obj.d==((cdate.getDay()+1)%7)){
								var ts = curday+obj.s,te = curday+obj.f;
								if (((ts>=fd&&ts<ld)||(te>fd&&te<=ld)) && ((ts>=obj.gecerlilikBaslangici&&ts<obj.gecerlilikBitimi)||(te>obj.gecerlilikBaslangici&&te<=obj.gecerlilikBitimi))){
									var start=(ts>fd?ts:fd),finish=(te>ld?ld:te);
									start=(start>obj.gecerlilikBaslangici?start:obj.gecerlilikBaslangici);
									finish=(finish>obj.gecerlilikBitimi?obj.gecerlilikBitimi:finish);
									tempTick.push({name:obj.name,start:start,finish:finish});
								}
							}
						}
						cdate.setTime(cdate.getTime()+ti);
					}
					break;
				case 'hour':
					var cdate = new Date(fd>obj.gecerlilikBaslangici ? fd : obj.gecerlilikBaslangici);
					var ti=60*60*1000;
					while (cdate.getTime()<ld){
						var _i = x.items.indexOf(cdate.getHours());
						if(_i>-1){
							var obj = x.items[_i];
							var ts = cdate.getTime(),mod=ts%ti,ts=ts-mod,te = ts + ti;
							if((ts>=obj.gecerlilikBaslangici&&ts<obj.gecerlilikBitimi)||(te>obj.gecerlilikBaslangici&&te<=obj.gecerlilikBitimi)){
								var start=(ts>fd?ts:fd),finish=(te>ld?ld:te);
								start=(start>obj.gecerlilikBaslangici?start:obj.gecerlilikBaslangici);
								finish=(finish>obj.gecerlilikBitimi?obj.gecerlilikBitimi:finish);
								tempTick.push({name:x.name,start:start,finish:finish});
							}
						}
						cdate.setTime(cdate.getTime()+ti);
					}
					break;	
				case 'time':
					var cdate = new Date(fd);
					var offTime = [];
					for(var j=0;j<x.items.length;j++){
						var obj = x.items[j];
						if(obj.f=='G:i'){
							var m = /(\d*):(\d*)/.exec(obj.s);
							var start = (m[1]*(60*60*1000))+(m[2]*(60*1000));
							var m = /(\d*):(\d*)/.exec(obj.e);
							var finish = (m[1]*(60*60*1000))+(m[2]*(60*1000));
							offTime.push({name:obj.name,s:start,f:finish,gecerlilikBaslangici:obj.gecerlilikBaslangici,gecerlilikBitimi:obj.gecerlilikBitimi});
						}else
							break;
					}
					ti=24*60*60*1000;
					cdate.setHours(0,0,0,0);
					while (cdate.getTime()<ld){
						var curday = cdate.getTime();
						for(var j=0;j<offTime.length;j++){
							var obj = offTime[j];
							var ts = curday+obj.s,te = curday+obj.f;
							if(te<=ts)
								te += ti;
							if (((ts>=fd&&ts<ld)||(te>fd&&te<=ld)) && ((ts>=obj.gecerlilikBaslangici&&ts<obj.gecerlilikBitimi)||(te>obj.gecerlilikBaslangici&&te<=obj.gecerlilikBitimi))){
								var start=(ts>fd?ts:fd),finish=(te>ld?ld:te);
								start=(start>obj.gecerlilikBaslangici?start:obj.gecerlilikBaslangici);
								finish=(finish>obj.gecerlilikBitimi?obj.gecerlilikBitimi:finish);
								tempTick.push({name:obj.name,start:start,finish:finish});
							}
						}
						cdate.setTime(cdate.getTime()+ti);
					}
					break;
			}			
		}		
		t.offTimeTick =[];
		if(tempTick.length>0){
			tempTick.sort(function(a,b){
				return a.start-b.start;
			});
			var i=0;
			while(i<tempTick.length){
				var curTick = tempTick[i];
				if(i+1<tempTick.length&&curTick.finish>=tempTick[i+1].start){
					if(curTick.finish<tempTick[i+1].finish)
						curTick.finish = tempTick[i+1].finish;
					tempTick.splice(i+1,1);
				}else
					i++;
			}
			t.overTime.load();
			for(var j=0,l=t.overTime.recordCount;j<l;j++){
				t.overTime.data[j].startdate=t.overTime.data[j].startdate*1000;
				t.overTime.data[j].finishdate=t.overTime.data[j].finishdate*1000;
			}
			var i=0;
			while(i<tempTick.length){
				var tt = tempTick[i];
				var dontInc = false;
				for(var j=0,l=t.overTime.recordCount;j<l;j++){
					var ot = t.overTime.data[j];
					if(tt.start<=ot.startdate && tt.finish>=ot.startdate && tt.finish<=ot.finishdate){
						tt.finish=ot.startdate-1;
					}else if(tt.start>=ot.startdate && tt.finish<=ot.finishdate){
						tempTick.splice(i,1);
						dontInc = true;
						break;
					}else if(tt.start>=ot.startdate && tt.start<=ot.finishdate && tt.finish>=ot.finishdate){
						tt.start=ot.finishdate+1;
					}else if(tt.start<=ot.startdate && tt.finish>=ot.finishdate){//20.03.2009 EKLENEN KOD
						tempTick.splice(i+1,0,{name:tt.name,start:ot.finishdate+1,finish:tt.finish});
						tt.finish=ot.startdate-1;
					}
				}
				if(!dontInc)
					i++;
			}
			t.offTimeTick = tempTick;
		}
		*/
	},
	getPreTaskShift : function(task,preTask){
		var t=this;
		if(task.preType=='s')
			return preTask.times.startDate+ (task.preTime*t.durationMsMultiplier);
		else if (task.preType=='f')
			return preTask.times.finishDate+ (task.preTime*t.durationMsMultiplier);
	},
	getPreviousTask : function(task){
		var prev = mj.getIndex(task._station.task, 'order', task.order-1);
		return prev>-1 ? task._station.task[prev] : false;
	},
	getPx : function(timeMs){
		return parseInt((timeMs*this.timeIntervalWidth)/this.time.ms);
	},
	getPxFromTime : function(time,d){
		if(!(d instanceof Date))
			d = this.firstDate;	
		if(time instanceof Date)
			var fark = (time.getTime()-d.getTime());
		else
			var fark = (time-d.getTime());
		return parseInt((fark*this.timeIntervalWidth)/this.time.ms);
	},	
	getReferans : function(i){
		var _i = mj.getIndex(this.stores.referans.data,'id',i);
		if(_i>-1)
			return this.stores.referans.data[_i];
		else
			return {id:0,name:'-'};
	},	
	getStation : function(){
		var t=this,sts = t.stores.station.data;
		for (var i=0,len=sts.length;i<len;i++){
			t.station[sts[i].id]={
				id:sts[i].id, 
				order : i,
				task : [],
				lastTime : new Date(t.firstDate.getTime())
			};
			t.saveStation(t.station[sts[i].id]);
		}
	},
	getStationData : function(val){
		var _i = mj.getIndex(this.stores.station.data,'id',val);
		if(_i>-1)
			return this.stores.station.data[_i];
		else
			return {id:0,name:'-'};
	},
	getStationObject : function(val){
		var _i = mj.getIndex(this.station,'id',val);
		if(_i>-1)
			return this.station[_i];
	},
	getStationTask : function(e){
		var t = e.data.scope, stationId = e.data.station, station = t.getStationObject(stationId);
		t.rearrangeStation(station);
		for(var i=0,l=t.tasks.length;i<l;i++){
			var task = t.tasks[i];
			if(!task.planned && task.station == stationId){
				t.assignTaskToStation(task, station, t);
				t.setModified(task);
			}
		}
	},
	getTask : function(i){
		return this.tasks[mj.getIndex(this.tasks,'id',i)];
	},
	getTaskForm : function(e){
		var t = e.data.scope, task = e.data.task, form = t.forms.tForm, win = t.windows.detay;
		form.recMode = 'edit';
		if(!win.isActive || (win.isActive && form.editingTask != task)){
			form.startLoad();
			form.clear();
			t.forms.tForm._dieTriggerField.readOnly = !!(task._code);
			t.forms.tForm._dieTriggerField.disabled = !!(task._code);

			if(task.done && task.done.startDate && !task.done.finished){
				form.fieldSets[1].fieldSetEl.hide();
				form.fieldSets[2].fieldSetEl.hide();
			}else{
				form.fieldSets[1].fieldSetEl.show();
				form.fieldSets[2].fieldSetEl.show();
				t.createProductionDetailsForm(task);
				var l = task.productionDetails.length;
				for(var i=0;i<l;i++){
					var pd = task.productionDetails[i];
					var val = eval("task._pdForm.setValue({'leafProduction_"+pd.leafId+"': pd.production, 'leafScrap_"+pd.leafId+"': pd.scrap})");
				}
				if(task.done && task.done.setupStartDate)
					with(task.done)
						form.setValue({
							actualOperator : actualOperatorCount,
							doneStartDate1 : setupStartDate ? (new Date(setupStartDate.formatDate('m/d/Y'))).getTime()/1000 : 0,
							doneStartDate2 : setupStartDate ? setupStartDate.formatDate('H:i') : '',
							doneSetupFinishDate1 : setupFinishDate ? (new Date(setupFinishDate.formatDate('m/d/Y'))).getTime()/1000 : 0,
							doneSetupFinishDate2 : setupFinishDate ? setupFinishDate.formatDate('H:i') : '',
							doneFinishDate1 : finishDate ? (new Date(finishDate.formatDate('m/d/Y'))).getTime()/1000 : 0,
							doneFinishDate2 : finishDate ? finishDate.formatDate('H:i') : '',
							finished : finished
						});
			}
			if(task.planned){
				var _maxStart=false,_maxFinish=false;
				for(var i=0, l = task.pending.length;i<l;i++){
					var pendingTask = task.pending[i], _startLimit = 0, _finishLimit = 0;
					if(pendingTask.planned){
						if (pendingTask.preType=='f')
							_finishLimit = pendingTask.times.startDate - (pendingTask.preTime*t.durationMsMultiplier);
						_maxFinish = (_maxFinish && _maxFinish < _finishLimit) ? _maxFinish : _finishLimit;
					}
				}
				var _next = t.getNextTask(task);
				if(_next)
					_maxFinish = (_maxFinish && _maxFinish < _next.times.startDate) ? _maxFinish : _next.times.startDate;
				task._maxFinish = _maxFinish;
				if(_maxFinish){
					var _maxDuration = _maxFinish-task.times.startDate, edtSetup = form.getField(3), edtTpp = form.getField(4), edtProduction = form.getField(5), totalTime = _maxFinish-(task.done&&task.done.startDate?task.done.startDate:task.times.startDate);
					var sd = task.times.startDate, fd = _maxFinish, addMs = 0;
					for(var i=0,len=t.offTimeTick.length;i<len;i++){
						var off = t.offTimeTick[i];
						if(sd<=off.start&&fd>=off.finish)
							_maxDuration -= off.finish - off.start;
						else if(fd<off.start)
							break;
					}
					edtSetup.validate = edtTpp.validate = edtProduction.validate = function(val){
						switch(this.dataIndex){
							case 'setup' :
								var fTpp = form.getValue('tpp'), fProduction = form.getValue('production');
								fTpp = fTpp.tpp;
								fProduction = fProduction.production;
								var _maxSetup = parseInt((_maxDuration - (fTpp * fProduction * 1000)) / 1000);
								if(parseInt(val) > _maxSetup){
									this.markInvalid('Bu görev için ayar süresini en fazla '+_maxSetup+' sn tanımlayabilirsiniz!');
									this.focus();
									this.setValue(_maxSetup);
									return false;
								}else
									this.clearInvalid();
								break;
							case 'tpp' :
								var fSetup = form.getValue('setup'), fProduction = form.getValue('production');
								fSetup = fSetup.setup;
								fProduction = fProduction.production;
								var _maxTpp = parseInt((_maxDuration - (fSetup*1000)) / (fProduction * 1000));
								if(parseInt(val) > _maxTpp ){
									this.markInvalid('Bu görev için birim üretim süresini en fazla '+_maxTpp +' sn tanımlayabilirsiniz!');
									this.focus();
									this.setValue(_maxTpp);
									return false;
								}else
									this.clearInvalid();
								break;
							case 'production' :
								var fSetup = form.getValue('setup'), fTpp = form.getValue('tpp');
								fSetup = fSetup.setup;
								fTpp = fTpp.tpp;
								var _maxProduction = parseInt((_maxDuration - (fSetup*1000)) / (fTpp * 1000));
								if(parseInt(val) > _maxProduction ){
									this.markInvalid('Bu görev için üretim miktarını en fazla '+_maxProduction +' tanımlayabilirsiniz!');
									this.focus();
									this.setValue(_maxProduction);
									return false;
								}else
									this.clearInvalid();
								break;
						}
						return true;
					};
				}
			}
			with(task)
				form.setValue({
					customer : customerId,
					dieId : dieId,
					leafId : leafId,
					name : name,
					station : station,
					setup : parseInt(setup/60),
					tpp : tpp,
					production : production,
					operator : operator,
					sampleProduction : sampleProduction,
					inBox : inBox
				});
			form.finishLoad();
			form.editingTask = task;
			win.show();
			form.cnt.height(win._els.center.height());
			win.isActive = true;
			t.setActiveRegion('detaywindow');
		}
	},
	getTaskStartDate : function(task,station,pinnable){
		var t=this;
		var preTask = task.predecessor?t.getTask(task.predecessor):null;
		if(preTask){
			var controlTime = t.getPreTaskShift(task,preTask);
			task._minTime = controlTime;
			if(controlTime>station.lastTime.getTime())
				station.lastTime.setTime(controlTime);
		}
		if(task.pinned&&task.times.finishDate>station.lastTime.getTime())
			station.lastTime.setTime(task.times.finishDate);
		var st = station.lastTime.getTime();
		for(var i=0,len=t.offTimeTick.length;i<len;i++){
			var off = t.offTimeTick[i];
			if(st>off.start&&st<off.finish){
				st = off.finish;
			}
		}
		station.lastTime.setTime(st);
		return st;
	},
	getTimeFromPx : function(px,d){
		if(!(d instanceof Date))
			d = this.firstDate;
		var ms = (px*this.time.ms)/(this.timeIntervalWidth), mod = ms % this.durationMsMultiplier;
		return d.getTime()+(ms-mod);
	},	
	gotoNow : function(){
		this.gotoTime(this.curTime);
	},
	gotoTaskEl : function(task){
		if(task.el){
			var t = this, _firstElO = t.station[t.stores.station.data[0].id].chartEl.offset(), _o = task.el.offset();
			t.domEls.chartEls.chartBody.animate({scrollTop : _o.top-_firstElO.top, scrollLeft:task.el[0].offsetLeft},1000, function(){
				window.mj._ganttGridElBorderBlinkCount = 5;
				window.mj._ganttGridElBorderBlinkColors = ['red', 'yellow'];
				window.mj._ganttGridElBorderBlinkTrigger = function(){
					if(window.mj._ganttGridElBorderBlinkCount-- >0){
						t._ganttGridElBorderBlinkTimer=setTimeout(function(){mj._ganttGridElBorderBlinkTrigger.call(t);},100);
						task.el.css('borderColor', mj._ganttGridElBorderBlinkColors[mj._ganttGridElBorderBlinkCount % 2]);
					}else
						task.el.css('borderColor', '#000');
				};
				window.mj._ganttGridElBorderBlinkTrigger();
				t.showTaskQuickInfo(task, true);
			});
		}
	},
	gotoTime : function(time){
		var t = this;
		t.domEls.chartEls.chartBody.animate({scrollLeft:t.getPxFromTime(time)-parseInt(t._chartBodyWidth/2)},1000);
	},
	gridElClick : function(e){
		var t = e.data.t, task = e.data.task;
		if(e.ctrlKey)
			t.gotoTaskEl(task);
	},
	hideDetayWindow : function(){
		this.windows.detay.isActive = false;
		this.windows.detay.hide();
	},
	importTasks : function(){
		var t=this;
		t._importing = true;
		t.stores.grid.url = t.url;
		t.stores.grid.params.event = 'importTasksAndLoad';
		t.stores.grid.load();
	},
	initGanttData : function(){
		var t=this;
		t.timeIntervalIndex = t.timeRange.indexOf(t.timeInterval);
		t.durationMsMultiplier = t.durationUnit=='minute'?60*1000:1000;
		t.time = t.timeRangeMap[t.timeRange.indexOf(t.timeInterval)];
		t.timeTop = t.timeRangeMap[t.timeRange.indexOf(t.time.top)];
		t.timeUp = t.timeRangeMap[t.timeRange.indexOf(t.time.up)];
		t.heightPerOp = 3;
		t.heightPerBox = 1;
		t.curTime = t.curTime || new Date();
		t.pastStation=[];
	},
	insertTask : function(task, posTask, station){
		var t=this, tasks = station.task, o = -1, _o=posTask.order;
		task.order = -1;
		tasks._sort('order');
		for(var i=0,l=tasks.length;i<l;i++){
			if(tasks[i]==posTask)
				o++;
			tasks[i].order = o++;
		}
		task.order = _o;
		tasks._sort('order');
		var shiftSize = posTask.times.startDate-task.times.startDate+task.times.actualDuration;
		posTask.startDate.setTime(task.times.finishDate);
		t.calculateTask(posTask);
		t.calculateTaskSizes(posTask);
		t.setTaskLeftWidth(posTask,posTask.times.actualDuration);
		if(posTask.times.finishDate>station.lastTime.getTime())
			station.lastTime.setTime(posTask.times.finishDate);
		t.shiftTasksForward(posTask, shiftSize);
	},
	labelsShowHide : function(station){
		var t = this, _tasks = station ? station.task : t.tasks, task;
		if(t.displayLabels){
			t._labelsOn = !t._labelsOn;
			for(var i=0,l=_tasks.length;i<l;i++){
				task = _tasks[i];
				if(task.titleEl)
					task.titleEl.css('display', t._labelsOn ? 'block' : 'none');
			}
		}
	},
	locateTask : function(task){
		var t=this;
		t.calculateTask(task);
		t.calculateTaskSizes(task);
		var ts=task.sizes, tt=task.times;
		var left = task.left = t.getPxFromTime(tt.startDate);
		t.setTaskLabelLeft(task, left);
		task.gridEl.width(ts.gridElWidth);
		task.gridSetupEl.width(ts.gridSetupElWidth);
		task.gridProductionEl.css({width:ts.gridProductionElWidth,left:ts.gridSetupElWidth});
		if(task.el){
			task.el.css({"left":left + "px","width": (ts.elWidth)+'px'});
			task.setupEl.width(ts.setupElWidth);
			task.productionEl.css({width:ts.productionElWidth,left:ts.setupElWidth+ts.lagWidth});
		}
	},
	maskStation : function(station){
		station.masked = true;
		if(station.maskEl)
			return station.maskEl.show();
		var t = this, crb = t.domEls.chartEls.chartRowsBody;
		station.maskEl = station.chartEl.clone(false).appendTo(crb).addClass('mj-gantt-station-mask').css({
			'border':'0',
			'background':'#B2B2FF'
		});
	},
	maskStations : function(stations){
		var t = this;
		for(var i in t.station)
			if(typeof t.station[i]!='function'){
				var s =t.station[i], isntAlternative = true;
				for(var j=0,l2=stations.length;j<l2;j++)
					if(stations[j]==s.id)
						isntAlternative = false;
				if(isntAlternative)
					t.maskStation(s);
			}
	},
	moveTaskToStation : function(task, newStation){
		var t=this;
		t.removeTaskFromStation(task);
		t.assignTaskToStation(task, t.getStationObject(newStation), t);
	},
	newTask : function(){
		var t = this, form = t.forms.tForm, win = t.windows.detay;
		form.newTask = {};
		form.clear();
		form.recMode = 'add';
		win.show();
		form._dieTriggerField.readOnly = false;
		form._dieTriggerField.disabled = false;
		form.cnt.height(win._els.center.height());
		win.isActive = true;
		t.setActiveRegion('detaywindow');
	},
	pinTask : function(task){
		task.pinned = true;
		task.el.css('border','1px solid #f00;');
		this.setModified(task);
	},
	rearrangeStation : function(station,start){
		var t=this;
		start = typeof start=='number'?start:-1;
		station.lastTime.setTime((start == -1) ? t.curTime.getTime():station.task[start].times.finishDate);
		if(start > -1)
			station.task[start].order = start;
		for(var i=start+1,len=station.task.length;i<len;i++){
			var task = station.task[i];
			t.setModified(task);
			if(task.done){
				station.lastTime.setTime(task._finishTimePrediction);
				continue;
			}
			task.oldStartDate = new Date(task.startDate.getTime());
			task.oldOrder = task.order;
			task.startDate = new Date(t.getTaskStartDate(task,station));
			t.calculateTask(task);
			t.setTaskLeftWidth(task,task.times.actualDuration);
			station.lastTime.setTime(station.lastTime.getTime()+task.times.actualDuration); 
			task.finishDate = new Date(station.lastTime.getTime());  
			task.order = i;
			t.setTaskValue(task);
		}
		t.saveStation(station);
	},
	redrawTaskDone : function(task){
		if(task.done){
			var dbg = {};
			if(task.done.setupStartDate && typeof task.done.setupStartDate.getTime!='function')
				task.done.setupStartDate=new Date(task.done.setupStartDate);
			if(task.done.setupFinishDate && typeof task.done.setupFinishDate.getTime!='function')
				task.done.setupFinishDate=new Date(task.done.setupFinishDate);
			var t = this, de = task.doneEls, 
			setupLeft = t.getPxFromTime(task.done.setupStartDate), 
			actualSetupFinishDate = (task.done.setupFinishDate ? task.done.setupFinishDate.getTime() : task.done.setupStartDate.getTime()+task.times.actualSetup), 
			totalSetupWidth = t.getPx(actualSetupFinishDate-task.done.setupStartDate.getTime()),
			actualSetupWidth = t.getPx((task.done.setupFinishDate ? task.done.setupFinishDate.getTime() : t.curTimeMs)-task.done.setupStartDate.getTime());
			totalSetupWidth = Math.max(totalSetupWidth, actualSetupWidth);
			de.doneSetupEl.width(totalSetupWidth);
			de.doneActualSetupEl.width(actualSetupWidth);
			dbg.actualSetupFinishDate = actualSetupFinishDate;
			var productionDuration = 0;
			var stopCnt = de.stopCnt, n = mj.NE, stopDuration = 0,titleEl=de.titleEl;
			stopCnt.empty();
			var qcall = task.done.qualityCall, setupStart = task.done.setupStartDate.getTime();
			if(qcall){
				var qcame = task.done.qualityCame ? task.done.qualityCame : t.curTimeMs;
				var qdone = task.done.qualityDone;
				var dur = qcame-qcall, w = t.getPx(dur), l = t.getPx(qcall-setupStart);
				n(stopCnt,{style:'cursor:default;width:'+w+'px;height:5px;top:-1px;left:'+l+'px;background:#fbc11f;border:1px solid #4d3b07;position:absolute;',html:mj.insertSpacer(w,5),title:'Kalite Personeli Bekleme'});
				stopDuration += dur;
				dbg['qcame-qcall'] = dur;
				if(qdone){
					var dur = qdone-qcame, w = t.getPx(dur), l = t.getPx(qcame-setupStart);
					stopDuration += dur;
					dbg['qdone-qcame'] = dur;
					n(stopCnt,{style:'cursor:default;width:'+w+'px;height:5px;top:-1px;left:'+l+'px;background:#df641e;border:1px solid #451e07;position:absolute;',html:mj.insertSpacer(w,5),title:'Kalite Onayı'});
				}
			}
			if(task.stops){
				for(var ii=0,l=task.stops.length;ii<l;ii++){
					var st = task.stops[ii];
					if(st && typeof st!='function'){
						if(!task.done.finished){
							var sd = parseInt(st.time), fd = sd + parseInt(st.fark);
							stopDuration += parseInt(st.fark)*1000;
							dbg['st'+ii] = parseInt(st.fark)*1000;
							for(var i=0,len=t.offTimeTick.length;i<len;i++){
								var off = t.offTimeTick[i];
								if(sd<=off.start&&fd>=off.finish){
									stopDuration -= off.finish - off.start;
								}else if(sd<=off.start && fd>=off.start && fd<=off.finish){
									stopDuration -= fd - off.start;
								}else if(sd>=off.start&&fd<=off.finish){
									stopDuration -= fd - sd;
								}else if(sd<=off.start)
									break;
							}
						}
						var time = st.time*1000, fark = st.fark*1000;
						if(fark>=parseInt(t.time.ms/50)){
							var w = t.getPx(fark)-2, l = t.getPx(time-setupStart), d = new Date(time);
							w = w>0 ? w : 1;
							if(st.duruskod)
								var fd = new Date(time+fark);
							d=st.duruskod ? (d.formatDate('d.m H:i')+" - "+fd.formatDate('d.m H:i')+" arasında '"+st.description+"' sebebiyle "+mj.timeShow(fark,true)+" duruldu.") : (d.formatDate('d.m H:i')+"'den itibaren duruş devam ediyor.( "+mj.timeShow(fark,true)+")");
							st.el = n(stopCnt,{style:'cursor:default;width:'+w+'px;height:'+(t.doneBarHeight+2)+'px;top:-2px;left:'+l+'px;background:'+st.colorRGB+';border:1px solid black;position:absolute;',html:mj.insertSpacer(w,7),title:d});
						}
					}
				}
			}
			if(task.done.finishDate){
				productionDuration = task.done.finishDate.getTime() - actualSetupFinishDate;
			}else if(task.done.production){
				var pCount = task.productionDetails.length>0 ? -1 : task.done.production;
				if(task.productionDetails && task.productionDetails.length>0)
					for(var i=0,l=task.productionDetails.length;i<l;i++){
						var pd = task.productionDetails[i], total = parseInt(pd.production) + parseInt(pd.scrap);
						if(total>pCount)
							pCount = total;
					}
				var passed = t.curTimeMs-actualSetupFinishDate;
				dbg.curTimeMs=t.curTimeMs;
				dbg.passed=passed;
				// if(task.done.qualityDone)
					// stopDuration += task.done.qualityDone - task.done.qualityCall;
				// else if(task.done.qualityCame)
					// stopDuration += task.done.qualityCame - task.done.qualityCall;
				passed -= stopDuration;
				dbg.stopDuration=stopDuration;
				
				task._calculatedTpp = pCount<t._minPredictionCount ? task.tpp * 1000 : passed / pCount;
				productionDuration = task._calculatedTpp * (task.production - pCount);// + stopDuration;
// console.log(task.name+' = '+task._calculatedTpp+' ('+task.tpp+')');
// console.dir(dbg);
				productionDuration = t.addOffTimeTick(t.curTimeMs, productionDuration);
				productionDuration += t.curTimeMs-actualSetupFinishDate;
			}else
				productionDuration = task.times.productionDuration;
			// if(!task.done.finished)
				// productionDuration = t.addOffTimeTick(task.done.setupFinishDate ? task.done.setupFinishDate.getTime() : t.curTimeMs, productionDuration);
			productionWidth = t.getPx(productionDuration);
			
			if(task.done.setupFinishDate)
				de.doneActualProductionEl.css({'width':t.getPx((task.done.finishDate ? task.done.finishDate.getTime() : t.curTimeMs) - actualSetupFinishDate), 'display':'block'});
			else
				de.doneActualProductionEl.css('display', 'none');
			de.doneProductionEl.css({'width':productionWidth, 'left':totalSetupWidth});
			de.doneEl.css({'left':setupLeft,'width':(totalSetupWidth+productionWidth)});
			task.drawTime = t.curTimeMs;
			task.drawZoomLevel = t.timeIntervalIndex;
			task._finishTimePrediction = (task.done.setupFinishDate ? task.done.setupFinishDate.getTime() : t.curTimeMs)+productionDuration;
			
			// SİLME!!!
			// var next = t.getNextTask(task);
			// if(next && next.times.startDate<task._finishTimePrediction){
				// t._dontShowLiveUpdateMessage = true;
				// t.shiftTasksForward(task, task._finishTimePrediction-next.times.startDate);
				// t.save(true);
				// t._dontShowLiveUpdateMessage = false;
			// }
		}
		t.setTaskLabelLeft(task, t.getPxFromTime(task.times.startDate));
	},
	removeTask : function(task){
		var t=this,station = t.station[task.station];
		var start = task.order-1;
		var nt=t.getDependTasks(task);
		var st='';
		for(var i=0,len=nt.length;i<len;i++){
			if(nt[i].planned)
				st = st=='' ?nt[i].id:st+','+nt[i].id;
		}
		if(st!=''){
			new mj.message({
				title:'Uyarı',
				modal : true,
				msg:'Silmeden önce bu işe bağlı <b>' + st + '</b> nolu işler silinmelidir!',
				buttons:['OK'],
				cb:function(el,btn){
					el.window.close();
				}
			});
		}else{
			t.removeTaskFromStation(task);
			// station.task.remove(task);
			// var _o=-1;
			// for(var i=0,l=task._station.task.length;i<l;i++)
				// task._station.task[i].order=_o++;
			t.setTaskValue(task);
			t.saveStation(station);
			new mj.message({
				title:'Uyarı',
				modal : true,
				msg:'İstasyon Görevleri tekrar düzenlensin mi?',
				buttons:['NO','YES'],
				cb:function(el,btn){
					if(btn=='YES')
						t.rearrangeStation(station,start);
					el.window.close();
				}
			});
		}
		t.setModified(task);
	},
	removeTaskFromStation : function(task){
		task.chartDrag = null;
		task.el.remove();
		if(task.doneEl)
			task.doneEl.remove();
		else if(task.titleCnt)
			task.titleCnt.remove();
		task.planned = false;
		//task.startDate = null;
		task.finishDate = null;
		task.drag.pause = false;
		var station = task._station, tasks = station.task, _o=0;
		station.task.remove(task);
		for(var i=0,l=tasks.length;i<l;i++)
			tasks[i].order=_o++;
		tasks._sort('order');
		station.lastTime.setTime(tasks.length>0? tasks[tasks.length-1].times.finishDate : t.curTimeMs);
	},
	renderTaskGridEls : function(val,task,cell,t){
		var bg = task.planned?'#00f':'#f00';
		cell.height(17);
		task.gridEl = $(mj.NE(cell,{cls:'mj-gantt-task-grid-el mj-opacity-7',style:'z-index:1;position:relative;background:#fff;height:'+t.barHeight+'px;width:'+task.sizes.gridElWidth+'px;border:1px solid #000;'}));
		task.gridEl.bind('dblclick',{scope:t,task:task},t.getTaskForm);
		var p = t.domEls.chartEls.taskPreviewPane;
		$(task.gridEl[0].parentNode.parentNode.parentNode).hover(function(){
			var _t = task.gridEl.clone().appendTo(p).css('margin-top',parseInt((t.resHeight-t.barHeight)/2));
			p.append('<span>'+task.production+' adet '+task.name+' : '+' Toplam '+task.operator+' kişi, '+mj.timeShow(task.times.duration,true)+'<br>Kasa içi miktar '+task.inBox+'</span>');
			_t.width(task.sizes.elWidth+task.sizes.setupElWidth+1);
			$(_t[0].childNodes[0]).width(task.sizes.setupElWidth);
			$(_t[0].childNodes[1]).css('left',task.sizes.setupElWidth+1).width(task.sizes.elWidth);
		},function(){
			p.empty();
		});
		task.gridSetupEl = $(mj.NE(task.gridEl,{cls:'mj-gantt-task-grid-setup-el mj-opacity-7',style:'position:absolute;background:#8c8;height:'+t.barHeight+'px;width:'+task.sizes.gridSetupElWidth+'px;border-right:1px solid #000;'}));
		task.gridProductionEl = $(mj.NE(task.gridEl,{cls:'mj-gantt-task-grid-production-el mj-opacity-7 mj-gantt-task-grid-unplanned-el',style:'position:absolute;height:'+t.barHeight+'px;width:'+task.sizes.gridProductionElWidth+'px;left:'+task.sizes.gridSetupElWidth+'px;'}));
		task.gridEl.bind('click', {t:t, task:task}, t.gridElClick);
		task.gridEl.bind('mouseup', function(){
			t.unMaskStations.call(t);
		});
		t.setTaskDrag(task);
		task.loading = true;
		if(typeof t.refreshed == 'undefined')
			if(parseInt(task.planned))
				t.assignTaskToStation(task,t.station[task.station],t);
		task.loading = false;
		if(task.planned && task._reLocate){
			t.assignTaskToStation(task, task._station, t);
			t.locateTask(task);
			t.drawTaskDone(task);
			task._reLocate = false;
		}
		return val;
	},
	restoreStation : function(station){
		var t=this;
		var _backup = station._backup;
		tasks=station.task;
		for(var i=0,l=tasks.length;i<l;i++){
			tasks[i].startDate.setDate(_backup[i]);
			t.calculateTask(tasks[i]);
		}
	},
	save : function(autoSave){
		var t = this;
		if(t.modified){
			var _save = function(){
				var modifiedTasks = [];
				for(var i=0,l=t.modified.length;i<l;i++){
					var task = t.modified[i], updObj;
					with(task){
						updObj = {
							id : id,
							dieId : dieId,
							leafId : leafId,
							name : name,
							//description : text,
							operator : operator,
							station : station,
							setup : setup,
							tpp : tpp,
							production : production,
							inBox : inBox,
							planned : planned,
							pinned : pinned ? 1 : 0,
							sampleProduction : sampleProduction ? 1 : 0,
							startDate : parseInt(times.startDate/1000),
							finishDate : parseInt(times.finishDate/1000),
							productionDuration : parseInt(times.productionDuration/1000),
							duration : parseInt(times.duration/1000),
							actualLag : parseInt(times.actualLag/1000),
							setupStartDate : parseInt(times.setupStartDate/1000),
							actualSetup : parseInt(times.actualSetup/1000),
							productionStartDate : parseInt(times.productionStartDate/1000),
							actualProductionDuration : parseInt(times.actualProductionDuration/1000),
							productionFinishDate : parseInt(times.productionFinishDate/1000),
							actualDuration : parseInt(times.actualDuration/1000)
						};
						if(task.done){
							if(done.startDate)
								updObj.doneStartDate = done.startDate.getTime()/1000;
							if(done.setupStartDate)
								updObj.doneSetupStartDate = done.setupStartDate.getTime()/1000;
							if(done.setupFinishDate)
								updObj.doneSetupFinishDate = done.setupFinishDate.getTime()/1000;
							if(done.finishDate)
								updObj.doneFinishDate = done.finishDate.getTime()/1000;
							if(done.finished)
								updObj.finished = done.finished;
							if(done.actualOperatorCount)
								updObj.actualOperatorCount = done.actualOperatorCount;
							if(done.production)
								updObj.doneProduction = done.production;
						}
						var pd = [];
						for(var i2=0,l2=task.productionDetails.length;i2<l2;i2++){
							var pdi = task.productionDetails[i2];
							pd.push({id:pdi.id,production:pdi.production,scrap:pdi.scrap});
						}
						updObj.productionDetails = pd;
					}
					modifiedTasks.push(updObj);
				}
				modifiedTasks = modifiedTasks.toJSONString();
				t.submit({
					event : 'saveGantt',
					tasks : modifiedTasks,
					success : function(data){
						if(data.msg)
							t.showQuickMsg(data.msg);
						if(data.success)
							t.modified = false;
						t.waitMaskHide();
					}
				}, true);
			};
			if(autoSave==true)
				_save();
			else
				mj.message({
					title:'Onay',
					modal : true,
					msg:'Değişiklikleri kaydetmek istediğinizden emin misiniz?',
					buttons:['NO','YES'],
					cb:function(el,btn){
						el.window.close();
						if(btn=='YES')
							_save();		
					}
				});
		}
	},
	saveSnapshot : function(){
		var t = this;
		mj.message({
			title:'Onay',
			modal : true,
			msg:'Geçerli plan görüntüsünü kaydetmek istediğinizden emin misiniz?',
			scope : t,
			buttons:['NO','YES'],
			cb:function(el,btn){
				var t = this;
				el.window.close();
				if(btn=='YES'){
					var snapshotDetails = [];
					for(var i in t.station)
						if(typeof t.station[i]!='function'){
							for(var j=0,ls=t.station[i].task.length;j<ls;j++){
								var task = t.station[i].task[j];
								with(task)
									snapshotDetails.push({
										id : id,
										station : station,
										startDate : parseInt(times.startDate/1000),
										setupFinishDate : parseInt(times.productionStartDate/1000),
										finishDate : parseInt(times.finishDate/1000),
										operatorCount : operator,
										production : production
									});
							}
						}
					snapshotDetails = snapshotDetails.toJSONString();
					t.submit({
						event : 'saveSnapshot',
						startDate : parseInt(t.firstDate.getTime()/1000),
						finishDate : parseInt(t.lastDate.getTime()/1000),
						timeInterval : t.timeInterval,
						snapshotDetails : snapshotDetails
					}, true);
				}						
			}
		});
	},
	saveStation : function(station){//?
		return false;
		
		// if (!station.past)
			// station.past = [];
		// var obj = {};
		// obj.station = station.id;
		// obj.lastTime = new Date(station.lastTime.getTime());
		// obj.task = [];
		// for(var i=0,len=station.task.length;i<len;i++){
			// var stask = station.task[i];
			// var dtask = {};
			// dtask.id = stask.id;
			// dtask.startDate = new Date(stask.startDate.getTime());
			// obj.task.push(dtask);
		// }		
		// station.past.splice(0,0,obj);
		// this.pastStation.splice(0,0,station.id);
	},
	setActiveRegion : function(region){
		this.activeRegion = region;
	},
	setChartHeight : function(h, ch){
		var t = this, d = t.domEls, ce = d.chartEls;
		var scrollerSize = 16, hRH = 23;
		t.waitMask.height(ch);
		var resCollapsed = t.layouts.chart.regions.south.collapsed, resHeight = resCollapsed ? 0 : t.resHeight;
		var ch = h - (resCollapsed ? 7 : (resHeight));
		d.chartCnt.height(ch);
		ce.stations.height(ch-(3*hRH)-1);
		ce.stationsCnt.height(ch-(3*hRH)-scrollerSize-1);
		t._chartBodyHeight = ch-(3*hRH)-1;
		ce.chartBody.height(t._chartBodyHeight);
		t.windows.detay.height(h);
		t.windows.detay._els.center.height(h-30);
		if(t.waitMaskActive)
			t.waitMask.height(t.renderTo.height());
	},
	setChartWidth : function(w, cw){
		var t = this, d = t.domEls, ce = d.chartEls, fcw = t.firstColumnWidth;
		var scrollerSize = 16, hRH = 23;
		t.waitMask.width(cw);
		d.quickMsgEls.cnt.width(cw);
		ce.infoPane.width(w-fcw-scrollerSize-3);
		ce.taskPreviewPane.width(w-fcw-scrollerSize-3);
		d.chartCnt.width(w);
		ce.header.width(w-fcw-scrollerSize-1);
		t._chartBodyWidth = w-fcw-1;
		ce.chartBody.width(t._chartBodyWidth);
		d.resCnt.width(w);
		d.resEls.cnt.width(w-fcw-1);
		d.resEls.cntScroller.width(w-fcw-scrollerSize-1);
		t.windows.detay.width(w);
		t.windows.detay._els.center.width(w);
		t.windows.detay._els.south.width(w);
		if(t.waitMaskActive)
			t.waitMask.width(t.renderTo.width());
	},
	setFirstDate : function(val){
		var t = this, d = new Date(val);
		d.setHours(0);
		d.setMinutes(0);
		d.setSeconds(0);
		d.setMilliseconds(0);
		t._firstDateSetted = true;
		t.firstDate = d;
	},
	setLastDate : function(val){
		var t = this, d = new Date(val);
		d.setHours(0);
		d.setMinutes(0);
		d.setSeconds(0);
		d.setMilliseconds(0);
		d.setDate(d.getDate()+1);
		t._lastDateSetted = true;
		t.lastDate = d;
	},
	setModified : function(task){
		var t = this;
		if(!t.modified)
			t.modified = [];
		if(t.modified.indexOf(task)==-1)
			t.modified.push(task);
		mj.addModified(t);
		if(!t._dontShowLiveUpdateMessage && t.liveUpdate){
			t.stopLiveUpdate();
			t.showQuickMsg('Görevlerde değişiklik yapıldığı için canlı izleme modu durduruldu.');
		}
		t.buttons.saveBtn.setEnable();
	},
	setStartFinishDate : function(task,time){
		var t=this;
		task.startDate.setTime(time);
		t.calculateTask(task);
		task.finishDate.setTime(task.times.startDate + task.times.actualDuration);  
	},
	setTimeLineWidth : function(width){
		var t = this, d = t.domEls, ce = d.chartEls, ceh = ce.headers;
		ceh.line1.width(width);
		ceh.line2.width(width);
		ceh.line3.width(width);
		ce.chartBodyScroll.width(width);
		d.resEls.scroller.width(width);
		
		if(t.drawResourcesPane){
			d.canvas.width = width;
			d.canvas.style.width = width+'px';
			t.clearCanvas();
		}
		
		for(var i in t.station)
			if(typeof t.station[i] != 'function')
				t.station[i].chartEl.width(width);
	},
	setTaskDrag : function(task){
		var t=this,task;
			task.drag = new mj.drag({
				el:task.gridEl,
				parent : mj.bd,
				position:'absolute',
				appendParent:true, 
				moving:false
			});
			task.drag.on('beforedrag', function(e){
				if(task.planned || t.activeRegion=='message' || t.activeRegion=='detaywindow' || (t.checkDependTask && !task.plannable))
					return false;
				if(task.predecessor){
					var _pT = t.getTask(task.predecessor);
					if(_pT && !_pT.planned){
						t.showQuickMsg('Öncelikle '+task.predecessor+' numaralı işi planlamalısınız!');
						return false;
					}
				}
				if(task.station){
					task.drag.dropEls = [];
					if(typeof task.stations=="string")
						task.stations = eval(task.stations);
					for(var i=0,l=task.stations.length;i<l;i++)
						if(t.getStationObject(task.stations[i]))
							task.drag.dropEls.push(t.getStationObject(task.stations[i]).chartEl);
					if(task.drag.dropEls.length==1){
						var cbody = t.domEls.chartEls.chartBody, of = task._station.chartEl.offset({relativeTo:cbody});
						cbody.animate({scrollTop : of.top},250);
					}
					t.maskStations(task.stations);
				}
				if(task.drag.dropEls.length==0){
					t.showQuickMsg(mj.lng.glb.accessDenied);
					return false;
				}else
					return true;
			});
			task.drag.on('dragstop',function(e,target){
				if(target){
					var station = $(target).attr('name').replace('station-','');
					station = t.station[station];
					t.assignTaskToStation(this,station,t);
					t.setModified(task);
				}
				t.unMaskStations.call(t);
			},task);	
			if (task.planned)
				task.drag.pause = true;	
	},
	setTaskLabelLeft : function(task, left){
		var t = this;
		if(task._titleAbsolute && task.titleEl)
			task.titleCnt.css('left', left);
	},
	setTaskLeftWidth : function(task,durMs){
		var t=this, tt = task.times, ts = task.sizes;
		var left = t.getPxFromTime(tt.startDate);
		if(task.el)
			task.el.css({"left":left + "px","width": (ts.elWidth)+'px'});
		t.setTaskLabelLeft(task, left);
		if(task.setupEl)
			$(task.setupEl).css('left',ts.lagWidth+'px').css('width',ts.setupElWidth+'px');
		if(ts.lagWidth>0)
			$(task.setupEl).css('border-left','1px solid #000');
		task.productionEl.css('left',(ts.lagWidth+ts.setupElWidth)+'px').css('width',ts.productionElWidth+'px');
	},
	setTaskValue : function(task){
		var t=this,g = t.grids.gorev ;
		if(g.rows.length>0){
			var rowIndex = mj.getIndex(g.rows,'data',task);
			for(var i=0,len=g.cm.length;i<len;i++){
				var c = g.cm[i];
				if(c.dataIndex!='duration'&&rowIndex!=-1)
					g.setCellValue(rowIndex,mj.getIndex(g.rows[rowIndex].cols,'dataIndex',c.dataIndex),task[c.dataIndex],c.renderer);
			}
			t.locateTask(task);
			t.drawTaskDone(task);
		}
		t.checkTaskStatus(task);
		t.drawResources();
	},
	shiftStartForOffTime : function(sd){
		var t=this;
		for(var i=0,len=t.offTimeTick.length;i<len;i++){
			var off = t.offTimeTick[i];
			if(sd>=off.start&&sd<=off.finish)
				sd = off.finish+1000;
			else if(sd<off.finish)
				break;
		}
		return sd;
	},
	shiftStartForOffTimeBack : function(sd){
		var t=this;
		for(var i=t.offTimeTick.length-1;i>-1;i--){
			var off = t.offTimeTick[i];
			if(sd>=off.start&&sd<=off.finish)
				sd = off.start-1000;
			else if(sd>off.finish)
				break;
		}
		return sd;
	},
	shiftTasksBack : function(task, shiftSize){
		var t=this, station = task._station, tasks=station.task, prev = t.getPreviousTask(task);
		if(prev)
			if(!prev.pinned && !(prev.done&&prev.done.startDate)){
				var prev2 = t.getPreviousTask(prev), _maxShift;
				if(prev2 &&(prev2.pinned || (prev2.done && prev2.done.startDate))){
					var prevLimit = (prev2.done && prev2._finishTimePrediction) ? prev2._finishTimePrediction : prev2.times.finishDate;
					if(prev.times.startDate-shiftSize<prevLimit)
						shiftSize = prevLimit-prev.times.startDate+1;
					if(shiftSize<=0)
						return false;
				}
				prev.startDate.setTime(prev.times.startDate-shiftSize);
				t.calculateTask(prev);
				t.calculateTaskSizes(prev);
				t.setModified(prev);
				t.setTaskLeftWidth(prev,prev.times.actualDuration);	
				if (prev.times.finishDate>station.lastTime.getTime()){
					station.lastTime.setTime(prev.times.finishDate);
				}
				t.setTaskValue(prev);
				t.shiftTasksBack(prev, shiftSize);
			}else
				return false;
		var preTask = t.getTask(task.predecessor);

		if(preTask && preTask.el)
			if(!preTask.pinned && !(preTask.done&&preTask.done.startDate)){
				var prev2 = t.getPreviousTask(preTask), _maxShift;
				if(prev2 &&(prev2.pinned || (prev2.done && prev2.done.startDate))){
					var prevLimit = (prev2.done && prev2._finishTimePrediction) ? prev2._finishTimePrediction : prev2.times.finishDate;
					if(preTask.times.startDate-shiftSize<prevLimit)
						shiftSize = prevLimit-preTask.times.startDate+1;
					if(shiftSize<=0)
						return false;
				}
				preTask.startDate.setTime(preTask.times.startDate-shiftSize);
				t.calculateTask(preTask);
				t.calculateTaskSizes(preTask);
				t.setModified(preTask);
				t.setTaskLeftWidth(preTask,preTask.times.actualDuration);	
				if (preTask.times.finishDate>preTask._station.lastTime.getTime()){
					preTask._station.lastTime.setTime(preTask.times.finishDate);
				}
				t.setTaskValue(preTask);
				t.shiftTasksBack(preTask, shiftSize);
			}else
				return false;
	},
	shiftTasksForward : function(task, shiftSize){
		var t=this, station = task._station, tasks=station.task, next = t.getNextTask(task);
		if(next)
			if(!next.pinned && !(next.done&&next.done.startDate)){
				var next2 = t.getNextTask(next), _maxShift;
				if(next2 &&(next2.pinned || (next2.done && next2.done.startDate))){
					var nextLimit = (next2.done && next2.done.startDate) ? next2.done.startDate : next2.times.startDate;
					var maxStart = nextLimit - t.addOffTimeTickReverse(nextLimit,next.times.duration);
					if(next.times.startDate+shiftSize>maxStart)
						shiftSize = maxStart-next.times.startDate-1;
					if(shiftSize<=0)
						return false;
				}
				next.startDate.setTime(next.times.startDate+shiftSize);
				t.calculateTask(next);
				t.calculateTaskSizes(next);
				t.setModified(next);
				t.setTaskLeftWidth(next,next.times.actualDuration);	
				if (next.times.finishDate>station.lastTime.getTime()){
					station.lastTime.setTime(next.times.finishDate);
				}
				t.setTaskValue(next);
				t.shiftTasksForward(next, shiftSize);
			}else
				return false;
		for(var i=0,l=task.pending.length;i<l;i++){
			var pendingTask = task.pending[i], _shiftSize = pendingTask.times.startDate - task.times.finishDate + shiftSize;
			if(pendingTask.planned)
				if(!pendingTask.pinned && !(pendingTask.done&&pendingTask.done.startDate)){
					var next2 = t.getNextTask(pendingTask), _maxShift;
					if(next2 &&(next2.pinned || (next2.done && next2.done.startDate))){
						var nextLimit = (next2.done && next2.done.startDate) ? next2.done.startDate : next2.times.startDate;
						var maxStart = nextLimit - t.addOffTimeTickReverse(nextLimit,pendingTask.times.duration);
						if(next.times.startDate+shiftSize>maxStart)
							shiftSize = maxStart-pendingTask.times.startDate-1;
						if(shiftSize<=0)
							return false;
					}
					pendingTask.startDate.setTime(pendingTask.times.startDate+shiftSize);
					t.calculateTask(pendingTask);
					t.calculateTaskSizes(pendingTask);
					t.setModified(pendingTask);
					t.setTaskLeftWidth(pendingTask,pendingTask.times.actualDuration);	
					if (pendingTask.times.finishDate>pendingTask._station.lastTime.getTime()){
						pendingTask._station.lastTime.setTime(pendingTask.times.finishDate);
					}
					t.setTaskValue(pendingTask);
					t.shiftTasksForward(pendingTask, shiftSize);
				}else
					return false;
		}
	},
	showQuickMsg : function(msg){
		var t = this, _e = t.domEls.quickMsgEls;
		_e.content[0].innerHTML = msg;
		_e.cnt.animate({
			top:'0'
		}, "slow", "swing",function(){
			setTimeout(function(){
				_e.cnt.animate({
					top:'-20'
				}, "slow");
			}, 1500);
		});
	},
	showTaskQuickInfo : function(task, autoHide){
		var t = this, infoPane = t.domEls.chartEls.infoPane;
		if(window.activeTimer)
			clearTimeout(window.activeTimer);
		window.activeTimer = setTimeout(function(){
			if(window.activeTimer){
				if(task.done && !task.done.finishDate && task.done.startDate)
					var estimatedFinishDate = new Date(task._finishTimePrediction);
				else
					var estimatedFinishDate = false;
				var fd = new Date(task.times.finishDate);
				var pd = task.productionDetails, pdl = pd.length, pdHtml = '&nbsp;';
				if(pdl==0){
					pdHtml = '<span class="mj-gantt-task-production" style="margin-left:5px;">0</span><span class="mj-gantt-task-production-planned">/'+task.production+'</span>';
				}else if(pdl==1){
					pdHtml = '<span class="mj-gantt-task-production" style="margin-left:5px;">'+(pd[0].production?pd[0].production:'0')+'</span>'+(pd[0].scrap?('<span class="mj-gantt-task-scrap">-'+pd[0].scrap+'</span>'):'')+'<span class="mj-gantt-task-production-planned">/'+task.production+'</span>';
				}else{					
					pdHtml = '<table cellspacing="1" cellpadding="0" valign="top" style="margin-left:5px;">';
					for(var i=0,l=pd.length;i<l;i++){
						pdHtml += '<tr><td class="mj-gantt-task-code-title">'+pd[i].leafCode+'</td><td class="mj-gantt-task-production" align="right">&nbsp;'+(pd[i].production?pd[i].production:'0')+'</td>';
						pdHtml += '<td class="mj-gantt-task-scrap" align="right">&nbsp;'+(pd[i].scrap?('-'+pd[i].scrap):'')+'</td>';
						if(i==0)
							pdHtml += '<td rowspan="'+pdl+'" class="mj-gantt-task-production-planned">&nbsp;/&nbsp;'+task.production+'</td>';
						pdHtml += '</tr>';
					}
					pdHtml += '</table>';
				}
				var _html = [
				'<table cellpadding="0" cellspacing="0">',
					'<tr><td colspan="6"><span class="mj-gantt-task-no">'+task.id+':&nbsp;</span><span class="mj-gantt-task-name">'+task.name+'</span></td></tr>',
					'<tr class="mj-gantt-task-time">',
						'<td class="mj-gantt-task-time-title">Başlangıç</td>',
						'<td width="5px" align="center" class="mj-gantt-task-time-title">&nbsp;:&nbsp;</td>',
						'<td align="center">'+task.startDate.formatDate('d/m/Y H:i')+'</td>',
						'<td width="5px" align="center" class="mj-gantt-task-time-title">&nbsp;'+((task.done&&task.done.startDate)?'-':'')+'&nbsp;</td>',
						'<td class="mj-gantt-task-time-absolute" align="center">'+(task.done&&task.done.startDate?task.done.startDate.formatDate('d/m/Y H:i'):'&nbsp;')+'</td>',
						'<td rowspan="3" valign="middle" align="center" class="mj-gantt-task-table">'+pdHtml+'</td>',
					'</tr>',
					'<tr class="mj-gantt-task-time">',
						'<td class="mj-gantt-task-time-title">Bitiş</td>',
						'<td width="5px" align="center" class="mj-gantt-task-time-title">&nbsp;:&nbsp;</td>',
						'<td align="center">'+fd.formatDate('d/m/Y H:i')+'</td>',
						'<td width="5px" align="center" class="mj-gantt-task-time-title">&nbsp;'+((task.done && task.done.finishDate)||estimatedFinishDate?'-':'')+'&nbsp;</td>',
						'<td class="mj-gantt-task-time-'+(task.done && task.done.finishDate ? 'absolute' : 'estimated')+'" align="center">'+(task.done && task.done.finishDate?task.done.finishDate.formatDate('d/m/Y H:i'):(estimatedFinishDate?estimatedFinishDate.formatDate('d/m/Y H:i'):'&nbsp;'))+'</td>',
					'</tr>',
					'<tr class="mj-gantt-task-time">',
						'<td colspan="2">&nbsp;</td>',
						'<td class="mj-gantt-task-time-total" align="center">'+mj.timeShow(task.times.finishDate-task.startDate.getTime(), true)+'</td>',
						'<td width="5px" align="center" class="mj-gantt-task-time-title">&nbsp;'+(((task.done&&task.done.finishDate)||estimatedFinishDate) ? '-' : '')+'&nbsp;</td>',
						'<td align="center" class="mj-gantt-task-time-total-'+(task.done&&task.done.finishDate ? 'absolute' : 'estimated')+'">&nbsp;'+(((task.done&&task.done.finishDate)||estimatedFinishDate) ? mj.timeShow((task.done && task.done.finishDate ? task.done.finishDate.getTime() : task._finishTimePrediction)-task.done.startDate.getTime(), true) : '&nbsp;')+'</td>',
					'</tr>',
				'</table>'];
				infoPane.empty();
				mj.NE(infoPane,{html:_html.join('')});
				infoPane.fadeIn(250);
				clearTimeout(window.activeTimer);
			}
		},350);
		if(autoHide)
			setTimeout(function(){
				if(window.activeTimer)
					clearTimeout(window.activeTimer);
				infoPane.fadeOut(400);
			},3000);
	},
	startLiveUpdate : function(){
		var t = this;
		if(!t.liveUpdate){
			t.liveUpdate = true;
			if(!t.currentTimeLine)
				t.drawCurrentTimeLine();
				t.currentTimeLine.css('display','block');
			t.buttons.playPauseBtn.icon.addClass('mj-pause');
			t.buttons.playPauseBtn.icon.removeClass('mj-play');
			t._liveUpdateTimer = setTimeout(function(){
					t.updateTaskValues();
			}, t.updateTaskInterval);
			t.gotoNow();
		}
	},
	stopLiveUpdate : function(){
		var t = this;
		if(t.liveUpdate){
			t.liveUpdate = false;
			if(t.currentTimeLine)
				t.currentTimeLine.css('display','none');
			t.buttons.playPauseBtn.icon.addClass('mj-play');
			t.buttons.playPauseBtn.icon.removeClass('mj-pause');
			clearTimeout(t._liveUpdateTimer);
		}
	},
	submit : function(params, showMask){
		var t = this;
		if(showMask)
			t.waitMaskShow();
		mj.applyIf(params, {event:'saveGantt', success:function(d){t.ajaxSuccess.call((params && params.scope)||t, d);}, failure:function(d){t.ajaxFailure.call((params && params.scope)||t, d);}});
		var config = {url:t.ajaxForm.url};
		if(params.url){
			config.url = params.url;
			params.url = false;
		}
		if(params.success){
			config.success = params.success;
			params.success = false;
		}
		if(params.failure){
			config.failure = params.failure;
			params.failure = false;
		}
		config.params = params;
		t.ajaxForm.submit(config);
	},
	switchLiveUpdate : function(){
		var t = this;
		if(t.liveUpdate)
			t.stopLiveUpdate();
		else
			t.startLiveUpdate();
	},
	tsCheck : function(a3){
		var t=this,m=t.canvasItemsDraw.kasa,k=m.items,l=k.length,tsf = k.filter(function(val){return val.d==false;}),tst = k.filter(function(val){return val.d==true;});
		$('div.mj-checkbox:first',a3).removeClass('mj-checkbox-checked');
		if(tsf instanceof Array&&tst instanceof Array)
			if(tsf.length>0&&tst.length>0){
				m.ts = false;
				$('div.mj-checkbox:first',a3).addClass('mj-checkbox-checked').addClass('mj-item-disabled');
			}else if(tsf.length>0&&tst.length==0){
				if(tsf.length==l){
					m.ts=true;
					m.a=false;
					$('div.mj-checkbox:first',a3).removeClass('mj-item-disabled');
				}
			}else if(tsf.length==0&&tst.length>0){
				if(tst.length==l){
					m.ts=true;
					m.a=true;
					$('div.mj-checkbox:first',a3).addClass('mj-checkbox-checked').removeClass('mj-item-disabled');
				}
			}
	},
	unMaskStations : function(){
		var t = this;
		for(var i in t.station)
			if(typeof t.station[i]!='function'){
				var s = t.station[i];
				if(s.masked){
					s.masked = false;
					s.maskEl.hide();
				}
			}
	},
	unpinTask : function(task){
		task.pinned = false;
		task.el.css('border','1px solid #000;');
		this.setModified(task);
	},
	updateTask : function(){
		var t=this,form=t.forms.tForm, task = form.editingTask, fv= form.getValue(), oldStation = task.station, newStation = fv.station;
		if(oldStation!=newStation){
			if(task.planned)
				t.moveTaskToStation(task, newStation);
			task.stations = [];
			task.stations.push(newStation);
		}
		with(task){
			name = t.forms.tForm._dieTriggerField.getElValue();
			dieId = fv.name;
			leafId = fv.leafId;
			station = fv.station;
			setup = fv.setup*60;
			tpp = fv.tpp;
			production = fv.production;
			operator = fv.operator;
			inBox = fv.inBox;
			sampleProduction = fv.sampleProduction;
		};
		if(!task.done)
			task.done = {};
		if((task.done.actualOperatorCount && parseInt(task.done.actualOperatorCount) != parseInt(fv.actualOperator))||(!task.done.actualOperatorCount && parseInt(fv.actualOperator)>0))
			task.done.actualOperatorCount = fv.actualOperator;
		if(fv.doneStartDate1 && fv.doneStartDate2){
			task.done.setupStartDate = new Date((new Date(fv.doneStartDate1*1000)).formatDate('m/d/Y')+' '+fv.doneStartDate2);
			task.done.startDate = task.done.setupStartDate;
		}
		if(fv.doneSetupFinishDate1 && fv.doneSetupFinishDate2)
			task.done.setupFinishDate = new Date((new Date(fv.doneSetupFinishDate1*1000)).formatDate('m/d/Y')+' '+fv.doneSetupFinishDate2);
		if(fv.doneFinishDate1 && fv.doneFinishDate2)
			task.done.finishDate = new Date((new Date(fv.doneFinishDate1*1000)).formatDate('m/d/Y')+' '+fv.doneFinishDate2);
		if(!!task.done.finished != !!fv.finished)
			task.done.finished = fv.finished;

		if(task._pdForm){
			var fv = task._pdForm.getValue();
			for(var x in fv){
				var i = fv[x];
				if(x.substr(0,x.indexOf('_'))=='leafProduction'){
					var leafId = x.substr(x.indexOf('_')+1);
					var pdId = task.productionDetails.getIndex('leafId', leafId);
					task.productionDetails[pdId].production = fv['leafProduction_'+leafId];
					task.productionDetails[pdId].scrap = fv['leafScrap_'+leafId];
					var pVal = parseInt(task.productionDetails[pdId].production + task.productionDetails[pdId].scrap);
					if((task.done.production && parseInt(task.done.production) != pVal)||(!task.done.production && pVal>0))
						task.done.production = pVal;
				}
			}
		}
		var doneExists = false;
		for(var x in task.done)
			if(typeof task.done[x]!='function'){
				doneExists = true;
				break;
			}
		if(!doneExists)
			task.done = false;
		t.calculateTask(task);
		t.calculateTaskSizes(task);
		t.setTaskValue(task);
		t.setModified(task);
		if(task.planned)
			t.checkStationLastTime(task._station);
		var _max = -1;
		for(var i=0,l=t.tasks.length;i<l;i++){
			task = t.tasks[i];
			if(task.times.duration>_max)
				_max = task.times.duration;
		}
		t._maxDuration = _max;
		for(var i=0,l=t.tasks.length;i<l;i++){
			task = t.tasks[i];
			t.calculateTaskSizes(task);
			var ts = task.sizes;
			task.gridEl.width(ts.gridElWidth);
			task.gridSetupEl.width(ts.gridSetupElWidth);
			task.gridProductionEl.css({width:ts.gridProductionElWidth,left:ts.gridSetupElWidth});
		}
	},
	updateTaskValues : function(){
		if(this != arguments.callee._oScope){
			return arguments.callee.apply(arguments.callee._oScope, arguments);
		};
		var t = this;
		mj.dontShowLoader = true;
		t.submit({
			event : 'updateTaskValues',
			scope : t,
			curTime : parseInt(t.curTimeMs/1000),
			lastUpdate : parseInt(t.lastUpdate/1000),
			success : t.updateTaskValuesCb,
			failure : t.updateTaskValuesCb
		});
	},
	updateTaskValuesCb : function(data){
		if(this != arguments.callee._oScope){
			return arguments.callee.apply(arguments.callee._oScope, arguments);
		};
		var t = this;
		if(data.msg)
			t.showQuickMsg(data.msg);
		if(data.success){
			t.lastUpdate = parseInt(data.lastUpdate);
			for(var i=0,l=data.tasks.length;i<l;i++){
				var nTask = data.tasks[i], task = t.getTask(nTask.id);
				if(!task.done)
					task.done = {};
				task.modifyTime = t.lastUpdate;
				task.productionDetails = nTask.productionDetails;
				mj.apply(task.done, nTask.done);
				mj.apply(task.stops, nTask.stops);
				t.drawTaskDone(task);
			}
			var updFn = function(){
				if(this != arguments.callee._oScope){
					return arguments.callee.apply(arguments.callee._oScope, arguments);
				};
				t.updateTaskValues();
			};
			updFn._oScope = t;
			if(t.liveUpdate)
				t._liveUpdateTimer = setTimeout(updFn, t.updateTaskInterval);
		}else
			t.stopLiveUpdate();
		mj.dontShowLoader = false;
	},
	waitMaskShow : function(){
		this.waitMaskActive=true;
		this.waitMask[0].style.display='block';
	},
	waitMaskHide : function(){
		this.waitMaskActive=false;
		this.waitMask[0].style.display='none';
	},
	zoom : function(x){
		var t=this;
		t.waitMaskShow();
		setTimeout(function(){
			var cb = t.domEls.chartEls.chartBody;
			var time = t.getTimeFromPx(cb[0].scrollLeft + (t._chartBodyWidth/2));
			t.timeIntervalIndex = x ? (t.timeIntervalIndex + x) : 5;
			t.time = t.timeRangeMap[t.timeIntervalIndex];
			t.timeInterval = t.timeRange[t.timeIntervalIndex];
			t.updateTaskInterval = parseInt(t.time.ms/50);
			t.clearChartComponents();
			t.fillChartTimeline();
			t.drawOffTime();
			t.initGanttData();
			t.fillVardiya();
			for(var i=0,len=t.tasks.length;i<len;i++){
				var task = t.tasks[i];
				t.locateTask(task);
				t.drawTaskDone(task);
			}

			t.drawCurrentTimeLine();

			t.drawResources();
			t.gotoTime(time);
			t.waitMaskHide();
		},10);
	},
	zoomIn : function(){
		if(!this.time.min)
			this.zoom(-1);
	},
	zoomOut : function(){
		if(!this.time.max)
			this.zoom(1);
	},
	zoomReset : function(){
		this.zoom();
	},
	init : function(){
		var t = this;
		t.colorGenerator = new mj.randomColors();
		t.id = t.id || mj.genId(t.prefix || 'mj-gantt-');
		t.offTime = t.offTime || [];
		t.station = t.station || {};
		t.firstDate = t.firstDate || new Date();
		t.buttons = {};
		t.domEls = {};
		t.history = [];
		t.lng = mj.lng.titles.modules.gantt;
		t.render();
	}
};
mj.extend(mj.gantt, mj.component);
mj.gantt2 = function(config){
	mj.gantt2.superclass.constructor.call(this, config);
};
mj.gantt2.prototype = {
	checkDependTask : false,
	render : function(){
		var t = this, d = t.domEls, id = t.id, n = mj.NE, fcw = t.firstColumnWidth, _w=t.renderTo.width(), _h = t.renderTo.height();
		t.setLastDate(t.lastDate.getTime());
		t._labelsOn = t.displayLabels;
		t._window = window.handle.win;
		t.waitMask = $(n(t.renderTo,{
			cls:'mj-page-wait-mask mj-opacity-8',
			style:'display:none;width:'+_w+'px;height:'+_h+'px;',
			html:'<table width="100%" height="100%"><tr><td align="center" valign="middle"><img src="'+mj.glb.imagePath+'ajax-loader.gif"/><br/><br/><span class="mj-page-wait-title">Lütfen Bekleyin...</span></td></tr></table>'
		}));
		t._window.addRelated(t.waitMask);
		d.quickMsgEls = {'cnt':$(n(t.renderTo,{
			cls:'mj-gantt-quick-msg',
			style:'width:'+_w+'px;top:-20px',
			html:'<table width="100%" height="20px" cellpadding="0" cellspacing="0" style="position:absolute;top:0;"><tr><td align="center" valign="top"><table cellpadding="0" cellspacing="0"><tr><td style="width:20px;background:transparent url('+mj.glb.imagePath+'gantt-info.png) no-repeat 0 0">'+mj.insertSpacer(20,20)+'</td><td style="background:transparent url('+mj.glb.imagePath+'gantt-info.png) repeat-x 0 -40px"><span>...</span></td><td style="width:20px;background:transparent url('+mj.glb.imagePath+'gantt-info.png) no-repeat 0 -20px">'+mj.insertSpacer(20,20)+'</td></tr></table></td></tr></table>'
		}))};
		d.quickMsgEls.content = $('span', d.quickMsgEls.cnt);
		t.waitMaskShow();
		setTimeout(function(){
			t.windows = {};
			t.forms = {};
			t.grids = {};
			t.layouts = {};
			t.canvasItemsDraw = {
				vardiya : {
					p : {d:true,l:true},
					g : {d:true,l:true}
				},
				personel : {
					p : {d:true,l:false},
					g : {d:true,l:false}
				},
				kasa : {
					a : true,
					ts : false,
					items :t.stores.kasaStore.data//kasa tipleri var ise ilk açılışta alınarak doldurulacak
				}
			};
			t.series = {};
			var scrollerSize = 16;
			t._chartClientWidth = t.width;
			var _items = [];
			// Müşteri filtresi eklemek için kullanılabilir. silme!
			// if(t.details.customer)
				// _items.push({
					// region : 'north',
					// initial : 50,
					// min : 50,
					// max : 100,
					// split : true,
					// collapsible : true,
					// collapsed : true
				// });
			_items.push({
				region : 'west',
				initial : 270,
				min : 260,
				max : 650,
				split : true,
				collapsible : true
			});
			t.layouts.main = new mj.layout({
				renderTo :n(t.renderTo,{tag:'div',id:'layout-cnt'}),
				layout : 'border',
				items : _items
			});
			t.tasks = t.stores.grid.data;
			if(t.details.ref)
				t.referans = t.stores.referans.data;
			if(t.details.customer)
				t.customer = t.stores.customer.data;
			
			t.layouts.west = new mj.layout({
				renderTo : n(t.layouts.main.getBody('west')),
				layout : 'border',
				items : [
					{
						region : 'south',
						initial : 83,
						min : 83,
						max : 100,
						split : true,
						collapsible : true,
						collapsed : true
					}
				]
			});
			
			t.layouts.westCenter = new mj.layout({
				renderTo : n(t.layouts.west.getBody('center')),
				layout : 'border',
				items : [
					{
						region : 'south',
						initial : 150,
						min : 50,
						max : 250,
						split : true,
						collapsible : true,
						collapsed : false
					}
				]
			});
			$(t.layouts.westCenter.getBody('south')).css('overflow', 'auto');
			
			t.resourceDiv = t.layouts.westCenter.getBody('south');
			// t.infoMsgDiv = $(n(t.layouts.westCenter.getBody('south'),{style:'font-family:arial,tahoma,helvetica,sans-serif;font-size:11px;'}));
			// n(t.layouts.westCenter.getBody('south'), {'style':'clear:both;'});
			// t.resourceDiv = $(n(t.layouts.westCenter.getBody('south')));
			
			// t.infoMsgView = new mj.view({				
				// renderTo : n(t.infoMsgDiv),
				// store : new mj.store({url : t.url,params : {event : 'getGanttMessages'}}),
				// tpl : new mj.template(
					// ['<div class="thumb-wrap" id="{id}" style="cursor:pointer;color:#702717;"><div class="thumb">{message}</div></div>']
				// ),
				// selector : 'div.thumb-wrap'
			// });
			// t.infoMsgView.store.load();
			
			t.treePanel = new mj.panel({
				renderTo :t.layouts.westCenter.getBody('center'),
				border : true,
				attachTb : true,
				buttons : [
					
				],
				// width : 930,
				// height : 250,
				collapsible : true 
			});
			t._taskTreeCnt = $(t.treePanel.getBody());
			t.taskTree = new mj.tree({
				renderTo : t._taskTreeCnt,
				store : new mj.store({
					data : t.stores.tree,
					renderers:{
						startDate:mj.renderer.date('d/m/Y'),
						production:mj.renderer.right
					}
				}),
				icon : true,
				cm : [
						{header: "Referans", dataIndex: 'name', width: 200},
						{header: "Süre", dataIndex: 'duration', width: 120, renderer: function(val, task){ return t.renderTaskGridEls.call(t, val, task);}},
						{header: "Açıklama", dataIndex: 'description', width: 150},
						{header: "Miktar", dataIndex: 'production', width: 70},
						{header: "Teslim Tarihi", dataIndex: 'startDate', width: 100}
					]
			});
			t.taskTree.on('addnode', function(data){
				t._renderTaskGridEls.call(t, data);
			});
			t.taskTree.contextMenu = new mj.contextmenu({
				renderTo : mj.NE(),
				parent : t._taskTreeCnt,
				_dontBindParent : true,
				menuScope : t,
				width : 170,
				items : [
					{title:'Ürün Ağacını Görüntüle'/*,iconCls:'mj-menu-exit-icon'*/,handler : function(){
						var node = t.taskTree.contextNode;
						if(node && node.leafId){
							if(node.parent)
								node = node.parent;
							application.loadRecord('pTree', node.code, parseInt(node.leafId));
						}
					}}
				]
			});
			t._taskTreeCnt.bind('mousedown',function(e){
				t.taskTree.contextNode = false;
			});
			t.taskTree.on('contextmenu', function(tree, node){
				t.taskTree.contextNode = node;
			});
			t._taskTreeCnt.bind('contextmenu',function(e){
				if(t.taskTree.contextNode){
					var cM = t.taskTree.contextMenu;
					cM.trigger('show',cM, e.pageX, e.pageY);
					cM.showAt(e.pageX, e.pageY);
					e.preventDefault();
					e.stopPropagation();
				}
			});
			t.taskTree.on('nodeclick', function(tree,node){
				//data phpden requirementList eventi id:node.ptid,sira:node.sira parametrelieri ile çağırılacak
				if(node.leaf)
					mj.load(t.resourceDiv, {
						url : t.ajaxForm.url,
						params : {
							event : 'requirementList',
							id : node.ptid,
							sira : node.sira
						}
					});
			});
			/*
			var _cm = [
				{header: "id", dataIndex: 'id', width: 30},
				{header: "Süre", dataIndex: 'duration', width: 120,renderer:function(val,task,cell){return t.renderTaskGridEls(val,task,cell,t);}},
				{header: "Operasyon", dataIndex: 'name', width: 70}
			];
			if(t.details.ref)
				_cm.push({header: "Referans", dataIndex: 'referans', width: 70,renderer:function(val){var ref=t.getReferans(val);return ref.name;}});
			if(t.details.customer)
				_cm.push({header: "Müşteri", dataIndex: 'customerId', width: 70,renderer:function(val){var cust=t.getCustomer(val);return cust.code;}});
			_cm.push({header: "Op#", dataIndex: 'operator',width: 60});
			_cm.push({header: "İst.", dataIndex: 'station', renderer:function(val){var st=t.getStationData(val);return st.name;}, width: 60});
			_cm.push({header: "Başlangıç", dataIndex: 'startDate', width: 100,renderer : function(val){return (val instanceof Date)?val.formatDate('d/m/Y H:i'):''}});
			_cm.push({header: "Bitiş", dataIndex: 'finishDate', width: 100,renderer : function(val){return (val instanceof Date)?val.formatDate('d/m/Y H:i'):'';}});
			if(t.details.checkDependTasks)
				_cm.push({header: "Bağlı Görev", dataIndex: 'predecessor', width: 100});
			*/
			t.curTime = new Date(t.curTimeMs);
			//t.curTimeMs = t.curTime.getTime();
			
			/*
			t.grids.gorev = new mj.grid({
				renderTo : t.gridPanel.getBody(),
				store : t.stores.grid,
				pbar : new mj.pager({
					pos:'bottom',
					limit:25,
					elements : {
						first : false,
						prev : false,
						next : false,
						last : false,
						refresh : true,
						pages : false
					},
					sc:t,
					refresh : function(){
						this.sc.refreshed = true;
						this.store.clearFilter();
						this.store.load();
						t.filterInputs.op1.value = '';
						if(t.details.ref)
							t.filterInputs.ref1.value = '';
						if(t.details.customer)
							t.filterInputs.cust1.value = '';
						t.filterInputs.ist1.value = '';
						t.filterInputs.tar1.value = '';
					}
				}),
				fitToParent : true,
				cm : _cm
			});
			t._window.addRelated(t.grids.gorev);
			t.grids.gorev.on('rowclick', function(){
				t.setActiveRegion('grid');
			});
			t.grids.gorev.store.on('load',function(){
				if(typeof t.refreshed != 'undefined')
					delete t.refreshed;
				t.drawCanvas();
				for(var i=0,l=t.tasks.length;i<l;i++){
					var task = t.tasks[i];
					if($.browser.msie){
						task.gridSetupEl[0].style.background='#ffc';
						if(task.color)
							task.gridProductionEl[0].style.background=task.color;
					}else{
						task.gridSetupEl.css('background','#ffc');
						if(task.color)
							task.gridProductionEl.css('background',task.color);
					}
				}
			});
			t.grids.gorev.on('afterload', function(){
				t.gridloading = false;
				t.drawResources();
			});
			t.grids.gorev.pbar.tbar.addSplitter();
			t.buttons.filterBtn = t.grids.gorev.pbar.tbar.addButton({id:'btnFilter',iconCls : 'mj-filter',alt : 'Filtrele',sc:t, handler:t.filterTasks});
			t.grids.gorev.pbar.tbar.addSplitter();
			t.buttons.addBtn = t.grids.gorev.pbar.tbar.addButton({id:'btnAdd',iconCls : 'mj-add',alt : 'Ekle',scope:t, handler:t.newTask});
			t.buttons.deleteBtn = t.grids.gorev.pbar.tbar.addButton({id:'btnDelete',iconCls : 'mj-delete',alt : 'Sil',scope:t, handler:t.deleteTask});
			t.grids.gorev.pbar.tbar.addSplitter();
			t.buttons.compileBtn = t.grids.gorev.pbar.tbar.addButton({id:'btnCompile',iconCls : 'mj-compile',alt : 'Verileri Çek',scope:t, handler:t.importTasks});
			t.buttons.parametersBtn = t.grids.gorev.pbar.tbar.addButton({id:'btnParameters',iconCls : 'mj-components',alt : 'Planlama Parametreleri',scope:t, handler:t.editParameters});
			*/
			var treeTBar = t.treePanel.tbar;
			t.buttons.filterBtn = treeTBar.addButton({id:'btnFilter',iconCls : 'mj-filter',alt : 'Filtrele',sc:t, handler:t.filterTasks});
			treeTBar.addSplitter();
			t.buttons.addBtn = treeTBar.addButton({id:'btnAdd',iconCls : 'mj-add',alt : 'Ekle',scope:t, handler:t.newTask});
			t.buttons.deleteBtn = treeTBar.addButton({id:'btnDelete',iconCls : 'mj-delete',alt : 'Sil',scope:t, handler:t.deleteTask});
			treeTBar.addSplitter();
			t.buttons.compileBtn = treeTBar.addButton({id:'btnCompile',iconCls : 'mj-compile',alt : 'Verileri Çek',scope:t, handler:t.importTasks});
			t.buttons.parametersBtn = treeTBar.addButton({id:'btnParameters',iconCls : 'mj-components',alt : 'Planlama Parametreleri',scope:t, handler:t.editParameters});
			
			t.buttons.warningsBtn = treeTBar.addButton({id:'btnWarnings',iconCls : 'mj-warning',alt : 'Uyarılar',scope:t, handler:t.loadWarnings});
			
			d.gridFilter = n(t.layouts.west.getBody('south'));
			$(t.layouts.west.getBody('south')).css('background','#EDF3FB');
			t._bindInputKeys = function(input){
				$(input).bind('keydown', {t:t}, function(e){
					if(e.keyCode==13){
						t.sc = t;
						t.filterTasks.call(t);
					}
				});
				$(input).bind('focus', {t:t}, function(e){
					t.filterInputs.isActive = true;
					t.filterInputs.activeInput = input;
					t.setActiveRegion('filter');
					t.isInInput = true;
				});
				$(input).bind('blur', {t:t}, function(e){
					t.filterInputs.isActive = false;
					t.isInInput = false;
				});
			};
			t.filterInputs = {};
			var l1 = n(d.gridFilter,{cls:'row',style:'position:absolute;left:0px;top:0px;'});
				n(l1,{style:'font-size:8pt;float:left;',html:'Operasyon:',cls:'mj-unselectable'});
				t.filterInputs.op1=n(l1,{tag:'input',style:'margin-left:42px;',id:'op-1'});
				t._bindInputKeys(t.filterInputs.op1);
			var top=0;
			if(t.details.ref){
				var l2 = n(d.gridFilter,{cls:'row',style:'position:absolute;left:0px;top:'+(top+=20)+'px;'});
				n(l2,{style:'font-size:8pt;float:left;',html:'Referans:',cls:'mj-unselectable'});
				t.filterInputs.ref1=n(l2,{tag:'input',style:'margin-left:53px;',id:'ref-1'});
				t._bindInputKeys(t.filterInputs.ref1);
			}
			var l3 = n(d.gridFilter,{cls:'row',style:'position:absolute;left:0px;top:'+(top+=20)+'px;'});
				n(l3,{style:'font-size:8pt;float:left;',html:'İstasyon:',cls:'mj-unselectable'});
				t.filterInputs.ist1=n(l3,{tag:'input',style:'margin-left:55px;',id:'ist-1'});
				t._bindInputKeys(t.filterInputs.ist1);
			var l4 = n(d.gridFilter,{cls:'row',style:'position:absolute;left:0px;top:'+(top+=20)+'px;'});
				n(l4,{style:'font-size:8pt;float:left;',html:'Tarih:',cls:'mj-unselectable'});
				t.filterInputs.tar1=n(l4,{tag:'input',style:'margin-left:75px;',id:'tar-1'});
				t._bindInputKeys(t.filterInputs.tar1);
			if(t.details.customer){
				var l5 = n(d.gridFilter,{cls:'row',style:'position:absolute;left:0px;top:'+(top+=20)+'px;'});
				n(l5,{style:'font-size:8pt;float:left;',html:'Müşteri:',cls:'mj-unselectable'});
				t.filterInputs.cust1=n(l5,{tag:'input',style:'margin-left:63px;',id:'ref-1'});
				t._bindInputKeys(t.filterInputs.cust1);
			}
			$('div.row',d.gridFilter).css({'line-height':'18px','margin':'2px 0px 0px 2px'});
			$('input',d.gridFilter).css({'font-size':'8pt','float':'left','width':'80px','height':'14px','border':'1px solid #A0ADB4'});
			var _cnt = $(t.layouts.main.getBody('center'));
			t.chartWidth = _cnt.width();
			t.height = _cnt.height();
			
			t.chartHeight = t.resCollapsed ? t.height - 7 : (t.height - t.resHeight);
			
			var resHeight = t.resHeight-8;
			t.layouts.chart = new mj.layout({
				renderTo : n(_cnt),
				layout : 'border',
				items : [
					{
						region : 'south',
						initial : resHeight,
						min : resHeight,
						max : resHeight,
						split : true,
						collapsible : true,
						collapsed : t.resCollapsed
					}
				]
			});
			t.layouts.chart.on('toggle', function(l,r,ce){
				if(!ce)
					t.drawResources();
			});
			_cnt = t.layouts.chart.getBody('center');
			d.chartCnt = $(n(_cnt,{id:id+'-chart-container mj-resize-handle', cls:'mj-gantt-chart-container',style:'width:'+(t.chartWidth)+'px;height:'+(t.chartHeight)+'px;'}));
			mj.bindResize(_cnt, t.doResize, t);
			var ce = d.chartEls = {};
			var hRH = 23;
			ce.corner = $(n(d.chartCnt, {style:'width:'+fcw+'px;height:'+(3*hRH)+'px;float:left;background:#edf3fb;border-right:1px solid #ccc;'}));
			var btnCnt = n(ce.corner, {style:'margin-left:23px;margin-top:14px;'});
			t.buttons.saveBtn = new mj.speedButton({renderTo:btnCnt, id:'btnSave',iconCls : 'mj-save',alt : 'Kaydet',scope:t, handler:t.save,disabled : true});
			t.buttons.snapshotBtn = new mj.speedButton({renderTo:btnCnt, id:'btnSnapshot',iconCls : 'mj-snapshot',alt : 'Geçerli Plan Görünümünü Kaydet',scope:t, handler:t.saveSnapshot});
			t.buttons.playPauseBtn = new mj.speedButton({renderTo:btnCnt, id:'btnPlayPause',iconCls : t.liveUpdate ? 'mj-pause' : 'mj-play',alt : 'Canlı İzleme Modu',scope:t, handler:t.switchLiveUpdate});
			n(btnCnt,{cls:'clear',html:mj.insertSpacer(1,1)});
			t.buttons.zoomInBtn = new mj.speedButton({renderTo:btnCnt, iconCls:'mj-zoom-in',alt : 'Yakınlaş',scope:t, handler:t.zoomIn});
			t.buttons.zoomOutBtn = new mj.speedButton({renderTo:btnCnt, iconCls:'mj-zoom-out',alt:'Uzaklaş',scope:t, handler:t.zoomOut});
			t.buttons.zoomResetBtn = new mj.speedButton({renderTo:btnCnt, iconCls:'mj-zoom',alt:'Sıfırla',scope:t, handler:t.zoomReset});
			
			ce.header = $(n(d.chartCnt, {id:id+'-headers', cls:'mj-gantt-headers',style:'width:'+(t.chartWidth-fcw-scrollerSize-1)+'px;height:'+(3*hRH)+'px;float:left;overflow:hidden;'}));
			n(d.chartCnt,{style:'width:'+scrollerSize+'px;float:left;height:'+(3*hRH)+'px;background:#edf3fb;',html:mj.insertSpacer(scrollerSize, 3*hRH)});
			ce.headers = {
				line1 : $(n(ce.header, {style:'width:'+t._chartClientWidth+'px;height:'+hRH+'px;',cls:'mj-gantt-header1'})),
				line2 : $(n(ce.header, {style:'width:'+t._chartClientWidth+'px;height:'+hRH+'px;',cls:'mj-gantt-header2'})),
				line3 : $(n(ce.header, {style:'width:'+t._chartClientWidth+'px;height:'+hRH+'px;',cls:'mj-gantt-header3'}))
			};
			t._chartBodyWidth = t.chartWidth-fcw-1;
			t._chartBodyHeight = t.chartHeight-(3*hRH)-1;
			ce.stations = $(n(d.chartCnt, {style:'width:'+fcw+'px;height:'+t._chartBodyHeight+'px;float:left;background:#edf3fb;border:1px solid #ccc;border-left:0;border-bottom:0;overflow:hidden'}));
			ce.stationsCnt = $(n(ce.stations, {id:id+'-stations', style:'width:'+fcw+'px;height:'+(t.chartHeight-(3*hRH)-scrollerSize-1)+'px;overflow:hidden'}));
			ce.chartBody = $(n(d.chartCnt, {id:id+'-chart-body', cls:'mj-gantt-grab', style:'width:'+(t._chartBodyWidth)+'px;height:'+t._chartBodyHeight+'px;float:left;background:#fff;overflow:scroll;border-top:1px solid #ccc;position:relative;'}));
			ce.chartBodyScroll = $(n(ce.chartBody, {id:id+'-chart-body-scroll', style:'float:left;position:relative;width:'+t._chartClientWidth+'px;'}));
			ce.chartRowsBody = $(n(ce.chartBodyScroll));
			
			ce.infoPane = $(mj.NE(t.layouts.main.getBody('center'), {cls:'mj-gantt-task-info',style:'opacity:0.9;width:'+(t.chartWidth-fcw-scrollerSize-3)+'px;height:'+(3*hRH)+'px;background:#f4f9a6;position:absolute;top:0;left:'+(fcw+1)+'px;font-size:11px;padding-left:2px;display:none'}));

			d.resCnt = $(n(t.layouts.chart.getBody('south'),{id:id+'-res-container', cls:'mj-gantt-res-container',style:'overflow:hidden;width:'+(t.chartWidth)+'px;height:'+(resHeight)+'px;'}));
			var re = d.resEls = {
				header : $(n(d.resCnt, {id:id+'-res-header',style:'width:'+fcw+'px;height:'+resHeight+'px;float:left;background:#ddd;border-right:1px solid #ccc;'})),
				cnt : $(n(d.resCnt, {id:id+'-res-cnt',style:'width:'+(t.chartWidth-fcw-1)+'px;height:'+resHeight+'px;float:left;background:#ddd;'}))
			};
			re.cntScroller = $(n(re.cnt,{style:'width:'+(t.chartWidth-fcw-scrollerSize-1)+'px;height:'+resHeight+'px;float:left;overflow:hidden'}));
			n(re.cnt,{style:'width:'+scrollerSize+'px;background:#ddd;float:left;height:'+resHeight+'px;',html:mj.insertSpacer(scrollerSize, resHeight)});
			re.scroller = d.canvasCnt = $(n(re.cntScroller, {id:id+'-res-cnt-scroller',style:'width:'+(t._chartClientWidth)+'px;height:'+resHeight+'px;float:left;',html:'<canvas width="' + t._chartClientWidth + '" height="' + resHeight + '" style="width:'+t._chartClientWidth+'px;height:'+resHeight+'px;"></canvas>'}));
			d.canvasInfo = $(n(re.cntScroller,{tag:'div',id:'canvas-info-panel',cls:'mj-invisible mj-gantt-tip',style:'left:'+fcw+'px;'}));
			re.cntScroller.bind('mouseout', function(){
				d.canvasInfo.addClass('mj-invisible');
			});
			if(!$.browser.msie){
				re.scroller.bind('mousedown',function(e){
					if(e.which==1){
						re._dragStarted={x:e.layerX,y:e.layerY};
						re.scroller[0].style.cursor='url('+mj.glb.imagePath+'pt/closedhand.cur'+'),default;';
					}
				});
				re.scroller.bind('mouseup',function(e){
					re._dragStarted=false;
					re.scroller[0].style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
				});
				re.scroller.bind('mouseout',function(e){
					re._dragStarted=false;
					re.scroller[0].style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
				});
				re.scroller[0].style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
				re.scroller.bind('mousemove',function(e){
					if(re._dragStarted){
						var _x = re._dragStarted.x-e.layerX, _y = re._dragStarted.y-e.layerY;
						re.cntScroller[0].scrollLeft += _x;
						ce.chartBody[0].scrollLeft += _x;
						ce.header[0].scrollLeft += _x;
					}
				});
				
				ce.chartBody.bind('mousedown',function(e){
					var isXul = false;
					if(e.originalTarget){
						try{
							isXul = false;
							if(e.originalTarget.localName=='thumb')
								isXul = true;
						}catch(e){
							isXul = true;
						}
					}
					if(!isXul)
						if(e.which==1&&$(e.target).hasClass('mj-gantt-grab')){
							ce._dragStarted={x:e.layerX,y:e.layerY};
							ce.chartBody[0].style.cursor='url('+mj.glb.imagePath+'pt/closedhand.cur'+'),default;';
						}
				});
				ce.chartBody.bind('mouseup',function(e){
					if(e.which==1&&$(e.target).hasClass('mj-gantt-grab')){
						ce._dragStarted=false;
						ce.chartBody[0].style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
					}
				});
				ce.chartBody.bind('mouseout',function(e){
					if(e.which==1&&$(e.target).hasClass('mj-gantt-grab')){
						ce._dragStarted=false;
						ce.chartBody[0].style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
					}
				});
				ce.chartBody[0].style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
				ce.chartBody.bind('mousemove',function(e){
					if(ce._dragStarted){
						var _x = ce._dragStarted.x-e.layerX, _y = ce._dragStarted.y-e.layerY;
						ce.chartBody[0].scrollLeft += _x;
						ce.chartBody[0].scrollTop += _y;
					}
				});
			}
			if(t.drawResourcesPane){
				d.canvasCnt.bind('mousemove',t,function(e){
					var scope = e.data,p={x:e.layerX,y:e.layerY},iDiv=scope.domEls.canvasInfo;
					var vs = function(h,v){return v/h;};
					var ch = scope.ctx.canvas.offsetHeight;
					var bul = function(item){
						var y = item.max>0?(ch+20 - (item.h/vs(ch,item.max))):item.y
						return item.x < p.x && item.x+item.w>p.x && y < p.y && y+(item.h/vs(ch,item.max))>p.y;
					};
					var current = scope.canvasItemsDraw.points.filter(bul,false,0), l=current.length;
					if(l>0){
						var _cDetails =[];
						for(var i=0;i<l;i++)
							_cDetails.push('<span style="color:'+('rgb('+current[i].fs.substr(5,current[i].fs.lastIndexOf(',')-5)+')')+'">'+current[i].type+'&nbsp;'+current[i].h+'</span>');
						iDiv.removeClass('mj-invisible').html(_cDetails.join('<br>'));
					}else
						iDiv.addClass('mj-invisible');
				});
				d.canvas = $('canvas',d.canvasCnt).get(0);
				if ($.browser.msie)
					d.canvas = window.G_vmlCanvasManager.initElement(d.canvas);
				t.ctx = d.canvas.getContext("2d");
			}
			ce.taskPreviewPane = $(mj.NE(re.cnt, {cls:'mj-gantt-task-preview',style:'width:'+(t.chartWidth-fcw-scrollerSize-6)+'px;height:'+(resHeight-5)+'px;left:'+(fcw+1)+'px;'}));
			/*
			$(t.grids.gorev.cnt[0].lastChild.firstChild).hover(function(){
				if(!t.layouts.chart.regions.south.collapsed)
					ce.taskPreviewPane.show();
			},function(){
				if(!t.layouts.chart.regions.south.collapsed)
					ce.taskPreviewPane.hide();
			});
			*/
			t.tasks = t.stores.grid.data;

			t.lastColorIndex = 0;
			t.windows.detay = $(n(_cnt,{cls:'mj-gantt-task-detail', style:'display:none;width:'+t.chartWidth+'px;height:'+t.height+'px;z-index:100'}));
			
			t.windows.detay.isActive = false;
			t.setActiveRegion('body');
			
			t.windows.detay._els = {center:$(n(t.windows.detay,{cls:'mj-gantt-task-detail-center',style:'width:'+t.chartWidth+'px;height:'+(t.height-30)+'px;'})), south:$(n(t.windows.detay,{cls:'mj-gantt-task-detail-south',style:'width:'+t.chartWidth+'px;'}))};
			var _btnCnt = n(t.windows.detay._els.south, {style:'float:right;padding:1px;'});
			t.windows.detay._buttons = {
				'vazgec':new mj.button({renderTo:n(_btnCnt), title:'Vazgeç', iconCls:'mj-menu-close-icon', handler:function(){
					if(t.activeRegion != 'message'){
						if(t.forms.tForm.modified){
							t.setActiveRegion('message');
							mj.shortcuts.on('e', function(){
								mj.message.activeMessageWin.close();
								t.hideDetayWindow();
								t.focusFakeInput();
							});
							mj.shortcuts.on('h', function(){
								t.setActiveRegion('detaywindow');
								mj.message.activeMessageWin.close();
							});
							mj.shortcuts.on('k', function(){
								mj.message.activeMessageWin.close();
								t.windows.detay._buttons.kaydet.handler.call(t);
							});
							mj.message.defaults.buttonTitles.SAVEANDEXIT = 'Kaydet ve Çık';
							mj.message({
								title:'Uyarı',
								modal : true,
								msg:'Yaptığınız değişiklikler kaydedilmeden çıkılsın mı?',
								buttons:['NO','YES','SAVEANDEXIT'],
								cb:function(el,btn){
									if(btn=='YES'){
										t.hideDetayWindow();
										t.focusFakeInput();
									}else if(btn=='SAVEANDEXIT'){
										mj.message.activeMessageWin.close();
										t.windows.detay._buttons.kaydet.handler.call(t);
									}else
										t.setActiveRegion('detaywindow');
									el.window.close();
								}
							});
							mj.message.activeMessageWin.on('beforeclose', function(){
								mj.shortcuts.mon('e');
								mj.shortcuts.mon('h');
								mj.shortcuts.mon('k');
							});
						}else{
							t.hideDetayWindow();
							t.focusFakeInput();
						}
					}
				}}),
				'kaydet':new mj.button({renderTo:n(_btnCnt), title:'Kaydet', iconCls:'mj-accept', handler:function(){
					if(t.forms.tForm.modified){
						if(t.forms.tForm.recMode == 'edit')
							t.updateTask();
						else
							t.createTask();
					}
					t.hideDetayWindow();
					t.focusFakeInput();
				}})
			};
			t.stores['dieGroup'] = new mj.store({url : t.url,params : {event : 'getdieGroup', table : 'dieGroup'}});
			t.forms.tForm = new mj.form({
				renderTo : t.windows.detay._els.center,
				items : [
					new mj.form.fieldSet({
						id : 'fsGorev',
						title : 'Görev Detayları',
						items : [
							// new mj.form.textField({
								// title : 'Görev',
								// dataIndex : 'name',
								// labelWidth : '110px',
								// readOnly : true,
								// width : 150
							// }),
							///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							new mj.form.triggerField({
								triggerClass:'trigger-field',
								title : 'Görev',
								dataIndex : 'name',
								labelWidth : '110px',
								width : 150,
								handler : function(){
									if(!t.forms.tForm.dataFilterTrigger){
										t.forms.tForm.dataFilterTrigger = new mj.dataFilterTrigger({
											filterEvent : 'getDataproductTreeList',
											url : t.url,
											table : 'producttree',
											width : 650,
											fields : [
												{header: "Id", dataIndex: 'id', width: 50,hide:true, table:'leaf'},
												{header: "Kod", dataIndex: 'code', width: 220,filter:'between',table:'leaf'},
												{header: "Ad", dataIndex: 'name', width: 220,filter:'between',table:'leaf'},
												{header: "Föy No", dataIndex: '_id', width: 220,filter:'between',table:'producttree',type:'int'},
												{header: "Açıklama", dataIndex: 'description', width: 220}
											],
											handler : function(a,b){
												if(b){
													if(!t.forms.tForm.dataFilterTrigger.tabs['tree'].taskTree){
														t.forms.tForm.dataFilterTrigger.tabs['tree'].taskTree = new mj.tree({
															renderTo : t.forms.tForm.dataFilterTrigger.tabs['tree'].getBody(),
															cm : [
																{header:'Referans', dataIndex:'text',width:330},
																{header:'Reçete Notu', dataIndex:'receteNotu',width:300}
															],
															store : new mj.store({
																url : t.url,
																params : {event : 'showTreeData'}
															}),
															icon : true
														});
														t.forms.tForm.dataFilterTrigger.tabs['tree'].taskTree.on('load',function(){
															this.expandAll();
														});
														t.forms.tForm.dataFilterTrigger.tabs['tree'].taskTree.on('nodedblclick',function(tree,data){
															if(data.leaf){
																a.clearFilter();
																var v = t.forms.tForm.dataFilterTrigger.win;
																var form = t.forms.tForm;
																form.setValue({
																	setup : parseInt(data.setupTime/60),
																	tpp : parseFloat(data.timePerUnit),
																	customer : parseInt(data.customerId),
																	station : parseInt(data.stationId),
																	operator : parseInt(data.operatorCount)
																});
																form._dieTriggerField.setValue(parseInt(data.dieId), true);
																form._dieTriggerField.setValue(data.text);
																form._leafId.setValue(data.firstLeafId);
																form._productionDetails = eval(data.productionDetails);
																form.newTask = {
																	productionDetails : form._productionDetails, 
																	name:data.text, stations : eval(data.stations), 
																	dieId:parseInt(data.dieId), 
																	sira:parseInt(data._sira), 
																	productTreeId:parseInt(data.ptid), 
																	description:data.receteNotu,
																	ptname:data.ptname,
																	ptdescription:data.ptdescription,
																	ptid:data.ptid
																};
																t.createProductionDetailsForm(form.newTask);
																t.forms.tForm.dataFilterTrigger.filterMode = true;
																v.buttons[2].setTitle(mj.lng.glb.records);
																v.close();
															}
														});
													}
													t.forms.tForm.dataFilterTrigger.tabs['tree'].taskTree.store.params.code = b.code;
													t.forms.tForm.dataFilterTrigger.tabs['tree'].taskTree.load();
													t.forms.tForm.dataFilterTrigger.tabs['tree'].activate();
												}
												return false;
											}
										});
										t.forms.tForm.dataFilterTrigger.tabPanel.addTab({
											title: 'Ürün Ağacı',
											iconCls:'tabs',
											closable:false
										}, true, 2);
										t.forms.tForm.dataFilterTrigger.tabs['tree'] = t.forms.tForm.dataFilterTrigger.tabPanel.tabs[2];
									}
									t.forms.tForm.dataFilterTrigger.show();
									t.forms.tForm.dataFilterTrigger.tabs['filter'].activate();
								}
							}),
							new mj.form.numberField({
								title : 'Operasyon',
								dataIndex : 'leafId',
								labelWidth : '110px',
								width : 150,
								defaultZero : false,
								hidden : true
							}),
							///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
							new mj.form.combo({
								title : 'İstasyon',
								dataIndex : 'station',
								mode : 'local',
								store : t.stores.station,//t.stores.activeStation,
								width : 150,
								displayField : 'name',
								labelWidth : '110px'
							}),
							new mj.form.combo({
								title : 'Müşteri',
								dataIndex : 'customer',
								mode : 'local',
								clearOnTriggerClick : true,
								store : t.stores.customer,//t.stores.activeStation,
								width : 150,
								displayField : 'code',
								labelWidth : '110px'
							}),
							// new mj.form.numberField({
								// title : 'Öteleme',
								// dataIndex : 'lag',
								// labelWidth : '110px',
								// width : 150,
								// decimalPrecision:0,
								// decimalPrecisionReal:0,
								// suffix:'',
								// defaultZero : false,
								// allowDecimals:false					
							// }),
							new mj.form.numberField({
								title : 'Ayar Süresi(dk)',
								dataIndex : 'setup',
								labelWidth : '110px',
								width : 150,
								defaultZero : false
							}),
							new mj.form.numberField({
								title : 'Br. Ürt. Sür.(sn)',
								dataIndex : 'tpp',
								labelWidth : '110px',
								width : 150,
								money : true,
								suffix : '',
								decimalPrecision : 3,
								defaultZero : false	
							}),
							new mj.form.numberField({
								title : 'Üretim Sayısı',
								dataIndex : 'production',
								labelWidth : '110px',
								width : 150,
								defaultZero : false
							}),
							new mj.form.numberField({
								title : 'Operatör Sayısı',
								dataIndex : 'operator',
								labelWidth : '110px',
								width : 150,
								defaultZero : false	
							}),
							new mj.form.checkBox({
								title : 'Deneme Üretimi',
								labelWidth : '110px',
								dataIndex : 'sampleProduction'
							})
						]
					}),
					new mj.form.fieldSet({
						id : 'fsGorevGerceklesen',
						title : 'Gerçekleşen Değerler',
						items : [
							new mj.form.numberField({
								title : 'Operatör Sayısı',
								dataIndex : 'actualOperator',
								labelWidth : '110px',
								width : 80,
								defaultZero : false
							})
							,new mj.form.dateField({
								title : 'Ayar Başlangıç',
								epoch : true,
								labelWidth : '110px',
								dataIndex : 'doneStartDate1',
								itemStyle : '',
								width : 80
							})
							,new mj.form.timeField({
								title : '-',
								labelWidth : '10px',
								right : true,
								itemStyle : 'width:70px;',
								dataIndex : 'doneStartDate2',
								width : 50
							})
							,new mj.form.dateField({
								title : 'Ayar Bitiş',
								epoch : true,
								labelWidth : '110px',
								dataIndex : 'doneSetupFinishDate1',
								width : 80
							})
							,new mj.form.timeField({
								title : '-',
								labelWidth : '10px',
								right : true,
								itemStyle : 'width:70px;',
								dataIndex : 'doneSetupFinishDate2',
								width : 50
							})
							,new mj.form.dateField({
								title : 'Üretim Bitiş',
								epoch : true,
								labelWidth : '110px',
								dataIndex : 'doneFinishDate1',
								width : 80
							})
							,new mj.form.timeField({
								title : '-',
								labelWidth : '10px',
								right : true,
								itemStyle : 'width:70px;',
								dataIndex : 'doneFinishDate2',
								width : 50
							})
							,new mj.form.checkBox({
								title : 'Üretim Sonlandı',
								labelWidth : '110px',
								dataIndex : 'finished'
							})
						]
					}),
					new mj.form.fieldSet({
						id : 'fsMiktar',
						title : 'Üretim Miktarları'
					})
				]
			});
			t.forms.tForm._dieTriggerField = t.forms.tForm.items[0].items[0];
			t.forms.tForm._leafId = t.forms.tForm.items[0].items[1];
			
			t._window.addRelated(t.forms.tForm);
			var form = t.forms.tForm, edtSetup = form.getField(3), edtTpp = form.getField(4), edtProduction = form.getField(5);
			n(form.fieldSets[2].fieldSetEl, {html : '<div style="float:left;width:120px;height:15px;">'+mj.insertSpacer(120,15)+'</div><div style="float:left;width:50px;height:15px;">Üretim</div><div style="float:left;width:18px;height:15px;">'+mj.insertSpacer(18,15)+'</div><div style="float:left;width:120px;height:15px;">Iskarta</div><div style="clear">&nbsp;</div>'});
			t._productionCountCnt = $(n(form.fieldSets[2].fieldSetEl,{style:'clear:both'}));
			var invalidFn = function(edt, msg){
				mj.message({
					title : 'Bilgi',
					msg : msg,
					modal : true
				});
			};
			edtSetup.on('invalid', invalidFn);
			edtTpp.on('invalid', invalidFn);
			edtProduction.on('invalid', invalidFn);
			t.cM = new mj.contextmenu({
				renderTo : n(),
				parent : t.domEls.chartEls.chartBody,
				canHide : true,
				style : 'vertical',
				width : 150,
				items : [
					{title:'Geri Al',iconCls:'mj-menu-delete-icon',scope:t,handler:function(){
						if(typeof this.undoStation == 'function')
							this.undoStation();
					} },'|',
					{title:'Yakınlaştır',iconCls:'mj-zoom-in',scope:t,handler:t.zoomIn},
					{title:'Uzaklaştır',iconCls:'mj-zoom-out',scope:t,handler:t.zoomOut}
				]
			});
			t._window.addRelated(t.cM);
			t.getStation();
			t.fillStation();
			t.fillChartTimeline();
			t.fillOpMeter();
			t.initGanttData();
			t.getOffTime();
			t.drawOffTime();
			t.drawCurrentTimeLine();
			
			t.stores.grid.on('load', function(){
				if(!t.stores.grid._isFiltering){
					t.gridloading = true;
					if(t._importing){
						for(var i=0,l=t.station.length;i<l;i++){
							t.station.task = [];
							station.lastTime.setTime(g.firstDate.getTime());
						}
						for(var i=0,l=t.tasks.length;i<l;i++){
							var task = t.tasks[i];
							if(task.el)
								task.el.remove();
							if(task.titleEl)
								task.titleEl.remove();
						}
						t.tasks = t.stores.grid.data;
						t._importing = false;
					}
					if(typeof t.refreshed == 'undefined'){
						var _max = -1;
						for(var i=0,l=t.stores.grid.data.length;i<l;i++){
							var task = t.stores.grid.data[i];
							task.id = parseInt(task.id);
							if(typeof task.startDate.getTime!='function'){
								task.startDate = new Date(parseInt(task.startDate));
								task.times =  false;
								task.drag =  false;
								task.planned = !!parseInt(task.planned);
								task._reLocate = true;
							}
							if(task.done && typeof task.done.startDate.getTime!='function'){
								task.done.startDate = new Date(parseInt(task.done.startDate));
								task.done.doneSetupStartDate = new Date(parseInt(task.done.doneSetupStartDate));
								task.done.doneSetupFinishDate = new Date(parseInt(task.done.doneSetupFinishDate));
								task.done.doneFinishDate = new Date(parseInt(task.done.doneFinishDate));
							}
							task.modifyTime = t.curTimeMs;
							if(task.station)
								task._station = t.getStationObject(parseInt(task.station));
							if(!task.pending)
								task.pending = [];
							if(task.predecessor){
								var preTask = t.getTask(parseInt(task.predecessor));
								if(!preTask.pending)
									preTask.pending = [];
								preTask.pending.push(task);
							}
							task.loading =  true;
							task.pinned = !!(parseInt(task.pinned));
							t.calculateTask(task);
							task.loading =  false;
							if(task.times.duration>_max)
								_max = task.times.duration;
						}
						t._maxDuration = _max;
						for(var i=0,l=t.stores.grid.data.length;i<l;i++){
							task = t.stores.grid.data[i];
							t.calculateTaskSizes(task);
						}
					}
					t.taskTree.load();
				}
			});
			t.stores.grid.load();
			
			t.hiddenElements = n(ce.header, {style:'position:absolute;top:-10000px;left:-100000px; display:none'});
			t.fakeInput = n(t.hiddenElements, {tag:'input'});
			t.ajaxForm = new mj.form({renderTo:n(t.hiddenElements), url : t.url});
			t._window.addRelated(t.ajaxForm);
			t.focusFakeInput();

			t._ganttTrigger = function(){
				if(this != arguments.callee._oScope){
					return arguments.callee.apply(arguments.callee._oScope, arguments);
				};
				var triggerFn = function(){
					if(this != arguments.callee._oScope){
						return arguments.callee.apply(arguments.callee._oScope, arguments);
					};
					t._ganttTrigger();
				};
				triggerFn._oScope = t;
				var timeResolution = parseInt(t.time.ms/t.timeIntervalWidth);//1000;
				timeResolution = timeResolution < t.minResolution ? t.minResolution : timeResolution;
				timeResolution = timeResolution > t.maxResolution ? t.maxResolution : timeResolution;
				t.updateTaskInterval = timeResolution;
				t._timer=setTimeout(triggerFn,timeResolution);
				var _t = t.curTimeMs += timeResolution;
				t.curTime = new Date(_t);
				//t.curTime = new Date();
				var _t = t.curTimeMs = t.curTime.getTime();
				t.drawCurrentTimeLine.call(t);
				for(var i in t.station)
					if(typeof t.station[i] != 'function' && t.station[i].lastTime.getTime()<_t)
						t.station[i].lastTime.setTime(_t);
				if(t.liveUpdate)
					for(var i in t.tasks)
						//if(typeof t.tasks[i] != 'function' && ((t.tasks[i].modifyTime>_t || t.tasks[i].drawZoomLevel!=t.timeIntervalIndex) || !t.tasks[i].drawTime || (!t.tasks[i].done.setupFinishDate && t.tasks[i].drawTime<_t)))
						if(typeof t.tasks[i] != 'function' && t.tasks[i].done)
							t.drawTaskDone(t.tasks[i]);
			};
			t._ganttTrigger._oScope = t;
			t._ganttTrigger();
			t.updateTaskValues._oScope = t;
			t.updateTaskValuesCb._oScope = t;
			if(t.liveUpdate)
				t.startLiveUpdate();
			t.gotoNow();
			/*
			t.grids.gorev.load();
			*/
			ce.chartBody.scroll(function(e){
				ce.header[0].scrollLeft = e.target.scrollLeft;
				ce.stationsCnt[0].scrollTop = e.target.scrollTop;
				re.cntScroller[0].scrollLeft = e.target.scrollLeft;
			});
			t.bindShortcuts();
			var w = t._window;
			w.on('beforeclose', function(){
				if(t.modified && t.modified.length>0){
					mj.message({
						title:'Uyarı',
						modal : true,
						msg:'Yaptığınız değişiklikler kaydedilmeden çıkılsın mı?',
						buttons:['NO','YES'],
						cb:function(el,btn){
							if(btn=='YES'){
								t.modified = false;
								t.dropEls = false;
								t.stopLiveUpdate();
								w.close();
							}
							el.window.close();
						}
					});
					return false;
				}
				t.dropEls = false;
				t.stopLiveUpdate();
			});
			t.gotoNow();
			t.waitMaskHide();
		},10);
	},
	bindShortcuts : function(){
		var t = this, sOn = mj.shortcuts.on;
		sOn('esc', function(){
			if(t.activeRegion=='message'){
				mj.message.activeMessageWin.close();
				t.focusFakeInput();
			}else if(t.windows.detay.isActive)
				t.windows.detay._buttons.vazgec.handler.call(t);
			else if(t.filterInputs.isActive){
				t.focusFakeInput();
				t.grids.gorev.selectRow(t.grids.gorev, 0);
				t.setActiveRegion('grid');
			}
		});
		sOn('f5', function(){
			t.taskTree.store.clearFilter();
			t.taskTree.store.load();
		});
		sOn('ctrl+f', function(){
			var l1 = t.layouts.west, r1 =l1.regions['south'], l2 = t.layouts.main, r2 =l2.regions['west'];
			if(r2.collapsed)
				l2._toggleRegion('west',false);
			if(r1.collapsed)
				l1._toggleRegion('south',false);
			t.filterInputs.op1.focus();
		});
		sOn('ctrl+q', function(){
			if(!t.time.min)
				t.zoom(-1);
		});
		sOn('ctrl+w', function(){
			if(!t.time.max)
				t.zoom(1);
		});
		sOn('f2', function(){
			if(t.activeRegion=='detaywindow'&&!mj.message.activeMessageWin){
				t.windows.detay._buttons.kaydet.handler.call(t);
			}
		});
		sOn('ctrl+l', function(){
			t.labelsShowHide();
		});

		// window.onbeforeunload = function() {
			// if(t.modified && t.modified.length>0)
				// return "Yaptığınız değişiklikleri kaydetmeden çıkmak istediğinize emin misiniz?";
		// };
		// mj.on('unload', function(){
			// if(t.modified && t.modified.length>0)
				// return "Yaptığınız değişiklikleri kaydetmeden çıkmak istediğinize emin misiniz?";
		// });
	},
	calculateTaskSizes : function(task){
		var t = this, tt = task.times, ts = task.sizes = {}, maxWidth = t.taskTree.cm[1].width-13, _scale = maxWidth/t._maxDuration;
		ts.gridElWidth = parseInt(_scale*tt.duration);
		ts.gridSetupElWidth = parseInt(_scale*tt.setup);
		ts.gridProductionElWidth = ts.gridElWidth - ts.gridSetupElWidth;
		var _timeScale = t.timeIntervalWidth/t.time.ms;
		ts.elWidth = parseInt(_timeScale * tt.actualDuration)-1;
		ts.setupElWidth = parseInt(_timeScale * tt.actualSetup)-1;
		ts.lagWidth = parseInt(_timeScale * tt.actualLag);
		ts.productionElWidth = ts.elWidth - (ts.setupElWidth - ts.lagWidth);
	},
	createProductionDetailsForm : function(task){
		var t = this, form = t.forms.tForm;
		var cnt = t._productionCountCnt, productionDetails = task.productionDetails, l = productionDetails.length;
		form.fieldSets[2].fieldSetEl.height(40+(l*23));
		cnt.empty();
		var formItems = [];
		for(var i=0;i<l;i++){
			var pd = productionDetails[i];
			formItems.push(
				new mj.form.numberField({
					title : pd.leafCode,
					dataIndex : 'leafProduction_'+pd.id,
					width : 50,
					labelWidth : '200px',
					emptyValue : 0,
					defaultZero : true
				})
			);
			formItems.push(
				new mj.form.numberField({
					title : ' - ',
					dataIndex : 'leafScrap_'+pd.id,
					right : true,
					width : 50,
					labelWidth : '10px',
					emptyValue : 0,
					defaultZero : true
				})
			);
		}
		task._pdForm = new mj.form({
			renderTo : cnt,
			items : formItems
		});
		t._window.addRelated(task._pdForm);
	},
	createTask : function(){
		var t = this, form = t.forms.tForm, fv = form.getValue();
		fv.startDate = t.curTimeMs;
		fv.productionDetails = form.newTask.productionDetails;
		fv.name = form.newTask.name;
		fv.description = form.newTask.description;
		fv.dieId = form.newTask.dieId;
		fv.sira = form.newTask.sira;
		fv.productTreeId = form.newTask.productTreeId;
		fvJSON = fv.toJSONString();
		t.submit({
			event : 'createTask',
			task : fvJSON,
			success : function(data){
				newTask = mj.apply({ id : parseInt(data.taskId) }, fv);
				newTask = mj.apply(newTask, form.newTask);
				newTask.text = newTask.name;
				newTask.customerId = newTask.customer;
				newTask.startDate = new Date(parseInt(newTask.startDate));
				newTask.modifyTime = t.curTimeMs;
				if(newTask.station){
					newTask._station = t.getStationObject(newTask.station);
					if(newTask.stations.indexOf(newTask.station)==-1)
						newTask.stations.push(newTask.station);
				}
				newTask.pending = [];
				newTask.duration = null;
				newTask.pinned = false;
				newTask.planned = false;
				newTask.times = false;
				newTask.setup = newTask.setup * 60;
				
				t.calculateTask(newTask);
				if(newTask.times.duration>t._maxDuration)
					t._maxDuration = newTask.times.duration;
				t.calculateTaskSizes(newTask);
				newTask.startDate = newTask.times.startDate/1000;
				t.stores.grid.data.push(newTask);
				if(t.stores.grid.oData)
					t.stores.grid.oData.push(newTask);
				var dItem = t.taskTree.store;
				var tsd = dItem.data, pData;
				var midx = tsd ? tsd.getIndex('text',newTask.ptname) : -1;
				if(midx>-1){
					dItem = tsd[midx];
					dItem.data.push(newTask);
				}else{
					if(!dItem.data)
						dItem.data = [];
					dItem.data.push({
						name : newTask.ptname,
						text : newTask.ptname,
						description : newTask.ptdescription,
						customerId : newTask.customerId,
						data:[newTask]
					});
				}
				t.taskTree.load();
				t.waitMaskHide();
			}
		}, true);
	},
	deleteTask : function(){
		var t = this, sr=t.taskTree.selectedNode;
		if(sr&&sr.id){
			mj.message({
				title:'Onay',
				modal : true,
				msg:'Seçili görevi silmek istediğinizden emin misiniz?',
				buttons:['NO','YES'],
				cb:function(el,btn){
					el.window.close();
					if(btn=='YES'){
						var srChildren = false;
						if(sr.data && sr.data.length>0){
							srChildren = [];
							for(var i=0,l=sr.data.length;i<l;i++){
								var src = sr.data[i].gridTask;
								if(src.el)
									t.removeTask(src);
								srChildren.push(src['id']);
							}
							srChildren = srChildren.join(',');
						}else{
							if(sr.gridTask.el)
								t.removeTask(sr.gridTask);
						}
						t.submit({
							event : 'deleteTask',
							task : sr.id,
							children : srChildren,
							success : function(data){
								if(srChildren){
									for(var i=0,l=sr.data.length; i<l; i++){
										t.stores.grid.data.remove(sr.data[0].gridTask);
										sr.data.remove(sr.data[0]);
									}
									t.taskTree.store.data.remove(sr);
								}else{
									var pData = sr.parent;
									pData.data.remove(sr);
									t.stores.grid.data.remove(sr.gridTask);
									if(pData.data.length==0)
										t.taskTree.store.data.remove(pData);
								}
								t.stores.grid.load();
								t.waitMaskHide();
							}
						}, true);
					}
				}
			});
		}
	},
	drawTaskToStation : function(task,station){
		var t=this;
		task.el = $(task.gridEl).clone().appendTo(station.chartEl);
		t.bindInfoPane(task);
		task.setupEl = task.el.children('div:first');
		task.productionEl = task.setupEl.next();
		if(!task.color)
			t.getColor(task);
		task.gridSetupEl.css('background','#ffc');
		task.gridProductionEl.css('background',task.color);
		if(task.pinned)
			task.el.css('border','1px solid #f00;');
		t.setTaskErrorState(task, !!task.error);
		task.el.css({"position":"absolute","top":t.barTop + "px"});
		task.el.addClass('mj-gantt-task-el');
		task.el.attr('name','task-'+task.id);
		task.el.children('div').attr('name','task-'+task.id);

		task.setupEl.css({ background: "#ffc" });

		task.productionEl.css({ background: task.color });
		//task.productionEl.append('<span style="padding:1px;font-size:10px;color:#fff;font-weight:bold;">'+task.name+'</span>');
		
		task.chartDrag = new mj.drag({
			el:task.el[0],
			parent : station.chartEl,
			appendParent:true, 			
			dragType : 'h',
			proxyOpacity : .7
		});
		task.el.bind('mouseup', function(){
			task.el.css('opacity', 1);
		});
		var _calculateMinMax = function(task, onlyPredecessors){
			var _prev = t.getPreviousTask(task);
			if(!onlyPredecessors){
				var minTime = _prev ? _prev.times.finishDate+(t.time.ms/50) : t.curTime.getTime();
				t.getTaskStartDate(task, task._station);
				if(task._minTime)
					minTime = task._minTime>minTime ? task._minTime : minTime;
			}else
				minTime = task._minTime;
			var _maxStart=false,_maxFinish=false;
			for(var i=0, l = task.pending.length;i<l;i++){
				var pendingTask = task.pending[i], _startLimit = 0, _finishLimit = 0;
				if(pendingTask.planned){
					if(pendingTask.preType=='s')
						_startLimit = pendingTask.times.startDate - (pendingTask.preTime*t.durationMsMultiplier);
					else if (pendingTask.preType=='f')
						_finishLimit = pendingTask.times.startDate - (pendingTask.preTime*t.durationMsMultiplier);
					_maxStart = (_maxStart && _maxStart < _startLimit) ? _maxStart : _startLimit;
					_maxFinish = (_maxFinish && _maxFinish < _finishLimit) ? _maxFinish : _finishLimit;
				}
			}
			return {_maxStart : _maxStart, _maxFinish : _maxFinish, minTime : t.shiftStartForOffTime(minTime)};
		};
		task.chartDrag.on('beforedrag', function(e){
			return !task.pinned && !task.done;
		});
		task.chartDrag.on('dragstart',function(drag, e){
			t._draggingTask = task;
			task.chartDrag.minWidth = false;
			task.chartDrag.maxWidth = false;
			if(e.ctrlKey&&!e.shiftKey){
				task.dragType = 'move';//üzerinden atlama
				var _minmax = task._minmax = _calculateMinMax(task, true);
				task.chartDrag._maxStart = _minmax._maxStart;
				task.chartDrag._maxFinish = _minmax._maxFinish;
			}else if(e.shiftKey&&!e.ctrlKey){
				task.dragType = 'shift';//toplu kaydırma
				var _minmax = task._minmax = _calculateMinMax(task);
				task.chartDrag._maxStart = _minmax._maxStart;
				task.chartDrag._maxFinish = _minmax._maxFinish;
			}else{
				task.dragType = 'default';//sol sağ sınırlara kadar gezdir
				var _minmax = _calculateMinMax(task);
				task.chartDrag._maxStart = _minmax._maxStart;
				task.chartDrag._maxFinish = _minmax._maxFinish;
				task.chartDrag.minWidth = t.getPxFromTime(_minmax.minTime);
			}
			t.dragOpacityDec(task.station);
			task._dragFirstDate = t.firstDate.getTime();
			task._dragMsFactor = t.time.ms/t.timeIntervalWidth;
			task._dragPx = function(px){
				var ms = px*task._dragMsFactor, mod = ms % t.durationMsMultiplier;
				return task._dragFirstDate+(ms-mod);
			};
		});
		var _getMax = function(task, x, pWidth, cPos, onlyPredecessors){
			var drag = task.chartDrag;
			task.startDate.setTime(cPos);
			t.calculateTask(task);
			pWidth = task.dragType=='move' ? 3 : t.getPx(task.times.actualDuration);
			drag.proxy.width(pWidth);
			var _next = t.getNextTask(task), _max = 0;
			if(_next && !onlyPredecessors)
				_max = _next.times.startDate-task.times.actualDuration-1000;
			_max = t.shiftStartForOffTimeBack(_max+task.times.actualDuration)-task.times.actualDuration;
			if(task.chartDrag._maxStart){
				var _max2 = task.chartDrag._maxStart;
				_max = (_max && _max<_max2) ? _max : _max2;
			}
			if(task.chartDrag._maxFinish){
				var _max2 = task.chartDrag._maxFinish-task.times.actualDuration;
				_max = (_max && _max<_max2) ? _max : _max2;
			}
			return _max;
		};
		task.chartDrag.on('dragmove',function(drag, x, y){
			var pWidth = 0, ce = t.domEls.chartEls;
			switch(task.dragType){
				case 'move' : 
					var cPos = task._dragPx(x), _max = _getMax(task, x, pWidth, cPos, true), _minmax = task._minmax;
					if(_minmax.minTime)
						task.chartDrag.minWidth = t.getPxFromTime(_minmax.minTime);
					if(_max)
						task.chartDrag.maxWidth = t.getPxFromTime(_max);
					break;
				case 'shift' : 
					var cPos = task._dragPx(x), _max = _getMax(task, x, pWidth, cPos);
					var _minmax = task._minmax;
					if(_max && cPos>_max){
						task._minmax = _minmax = _calculateMinMax(task);
						task.chartDrag._maxStart = _minmax._maxStart;
						task.chartDrag._maxFinish = _minmax._maxFinish;
						return t.shiftTasksForward(task, cPos-_max+parseInt(t.time.ms/50));
					}else if(_minmax.minTime && cPos<_minmax.minTime){
						task._minmax = _minmax = _calculateMinMax(task);
						task.chartDrag._maxStart = _minmax._maxStart;
						task.chartDrag._maxFinish = _minmax._maxFinish;
						return t.shiftTasksBack(task, _minmax.minTime-cPos);
					}
					break;
				default : 
					var cPos = task._dragPx(x), _max = _getMax(task, x, pWidth, cPos);
					if(_max)
						task.chartDrag.maxWidth = t.getPxFromTime(_max);
					break;
			}
			var nd = new Date(cPos), infoPane = t.domEls.chartEls.infoPane;
			infoPane.empty();
			var _html = [
				'<table cellpadding="0" cellspacing="0" width="100%"><tr><td align="center" valign="middle">'+
				nd.formatDate('d/m/Y H:i')+
				'</td></tr></table>'
			];
			mj.NE(infoPane,{html:_html.join('')});
			infoPane.show();
		});
		var v=this;
		task.chartDrag.on('dragstop',function(e){
			t.domEls.chartEls.infoPane.hide();
			t._draggingTask = false;
			t.dragOpacityInc(task.station);
			var station = task._station;
			t.arrangeTask(e,this,station,t);
			if(task.dragType=='move'){
				var sd = task.times.startDate, station = task._station, tasks = station.task;
				for(var i=0,l=tasks.length;i<l;i++){
					var cto = t.checkTaskOver(task, tasks[i]);
					if(task!=tasks[i] && cto){
						// task.startDate.setTime(tasks[i].times.startDate);
						// t.calculateTask(task);
						// t.calculateTaskSizes(task);
						// t.setTaskLeftWidth(task,task.times.actualDuration);	
						t.insertTask(task, tasks[i], station);
						break;
					}
				}
				tasks._sort('startDate');
				for(var i=0,l=tasks.length;i<l;i++)
					tasks[i].order = i;
			}else if(task.dragType=='station'){
				// with(task.chartDrag){
					// parent = mj.bd;
					// appendParent = false;
					// moving = false;
					// dragType = 'h';
				// }
				// task.el.css({'top':e.pageY-e.layerY,'left':e.pageX-e.layerX});
			}
			t.checkStationLastTime(station);
			t.setModified(task);
			return false;
		},task);
		task.el.bind('dblclick',{scope:t,task:task},t.getTaskForm);
		task.el.bind('mouseup',function(){
			t.dragOpacityInc.call(t, task.station);
		});
		t.bindTaskContextMenu(task);
	},
	filterTasks : function(){
		var t = this.sc, data = t.taskTree.store,f=false, op1=t.filterInputs.op1, ref1=t.filterInputs.ref1,ist1=t.filterInputs.ist1,tar1=t.filterInputs.tar1,cust1=t.filterInputs.cust1;
		t.refreshed = true;
		if(op1.value=='' && (t.details.ref || (t.details.ref && ref1.value=='')) && ist1.value=='' && tar1.value=='' && (t.details.customer || (t.details.customer && cust1.value==''))){
			data.clearFilter();
			data.load();
		}else{
			if(op1.value!=''){
				data.filter('text',op1.value,f,true);
				f=true;
			}
			if(t.details.ref && ref1.value!=''){
				var v = t.referans.filter(function(val){
					return val.name.toString().toLowerCase().substring(0,ref1.value.length)===ref1.value.toLowerCase();
				},true);
				data.filter('name',(v instanceof Array&&v[0])?v[0].id:'',f);
				f=true;
			}
			if(ist1.value!=''){
				data.filter('station',ist1.value,f);
				f=true;
			}
			if(tar1.value!=''){
				var tmp = tar1.value.split('/');
				if(tmp.length==3)
					data.filter('startDate',tar1.value,f);
			}
			if(t.details.customer && cust1.value!=''){
				var v = t.customer.filter(function(val){
					return val.code.toString().toLowerCase().substring(0,cust1.value.length)===cust1.value.toLowerCase();
				},true);
				data.filter('customerId',(v instanceof Array&&v[0])?v[0].id:'',f);
				f=true;
			}
		}
		if(data.data.length==1 && data.data[0].el){
			t.gotoTaskEl.call(t, data.data[0]);
		}
	},
	getGridTask : function(id){
		var t = this;
		t.stores.grid.filter('id', id);
		return t.stores.grid.data[0];
	},
	getColor : function(task){
		var t = this, pId = parseInt(task.gridEl.parents('ul:first').prev()[0].id.replace('m', ''));
		if(!t._masterColors)
			t._masterColors = {};
		if(!t._masterColors[pId]){
			var c = t.colorGenerator.generate(true);
			t.colorGenerator.darken(100);
			t._masterColors[pId] = c;
		}
		var nodeId = t.taskTree.getNodeById(task.id).nodeId;
		task.colorIndex = parseInt(nodeId.substr(nodeId.lastIndexOf('/')+1));
		mj.apply(t.colorGenerator, t._masterColors[pId]);
		return task.color = t.colorGenerator.getSimilar(task.colorIndex);
	},
	getTaskForm : function(e){
		var t = e.data.scope, task = e.data.task, form = t.forms.tForm, win = t.windows.detay;
		form.recMode = 'edit';
		if(!win.isActive || (win.isActive && form.editingTask != task)){
			form.startLoad();
			form.clear();
			t.forms.tForm._dieTriggerField.readOnly = !!(task._code);
			t.forms.tForm._dieTriggerField.disabled = !!(task._code);

			if(task.done && task.done.startDate && !task.done.finished){
				form.fieldSets[1].fieldSetEl.hide();
				form.fieldSets[2].fieldSetEl.hide();
			}else{
				form.fieldSets[1].fieldSetEl.show();
				form.fieldSets[2].fieldSetEl.show();
				t.createProductionDetailsForm(task);
				var l = task.productionDetails.length;
				for(var i=0;i<l;i++){
					var pd = task.productionDetails[i];
					var val = eval("task._pdForm.setValue({'leafProduction_"+pd.id+"': pd.production, 'leafScrap_"+pd.id+"': pd.scrap})");
				}
				if(task.done && task.done.setupStartDate)
					with(task.done)
						form.setValue({
							actualOperator : actualOperatorCount,
							doneStartDate1 : setupStartDate ? (new Date(setupStartDate.formatDate('m/d/Y'))).getTime()/1000 : 0,
							doneStartDate2 : setupStartDate ? setupStartDate.formatDate('H:i') : '',
							doneSetupFinishDate1 : setupFinishDate ? (new Date(setupFinishDate.formatDate('m/d/Y'))).getTime()/1000 : 0,
							doneSetupFinishDate2 : setupFinishDate ? setupFinishDate.formatDate('H:i') : '',
							doneFinishDate1 : finishDate ? (new Date(finishDate.formatDate('m/d/Y'))).getTime()/1000 : 0,
							doneFinishDate2 : finishDate ? finishDate.formatDate('H:i') : '',
							finished : finished
						});
			}
			if(task.planned){
				var _maxStart=false,_maxFinish=false;
				for(var i=0, l = task.pending.length;i<l;i++){
					var pendingTask = task.pending[i], _startLimit = 0, _finishLimit = 0;
					if(pendingTask.planned){
						if (pendingTask.preType=='f')
							_finishLimit = pendingTask.times.startDate - (pendingTask.preTime*t.durationMsMultiplier);
						_maxFinish = (_maxFinish && _maxFinish < _finishLimit) ? _maxFinish : _finishLimit;
					}
				}
				var _next = t.getNextTask(task);
				if(_next)
					_maxFinish = (_maxFinish && _maxFinish < _next.times.startDate) ? _maxFinish : _next.times.startDate;
				task._maxFinish = _maxFinish;
				if(_maxFinish){
					var _maxDuration = _maxFinish-task.times.startDate, edtSetup = form.getField(3), edtTpp = form.getField(4), edtProduction = form.getField(5), totalTime = _maxFinish-(task.done&&task.done.startDate?task.done.startDate:task.times.startDate);
					var sd = task.times.startDate, fd = _maxFinish, addMs = 0;
					for(var i=0,len=t.offTimeTick.length;i<len;i++){
						var off = t.offTimeTick[i];
						if(sd<=off.start&&fd>=off.finish)
							_maxDuration -= off.finish - off.start;
						else if(fd<off.start)
							break;
					}
					edtSetup.validate = edtTpp.validate = edtProduction.validate = function(val){
						switch(this.dataIndex){
							case 'setup' :
								var fTpp = form.getValue('tpp'), fProduction = form.getValue('production');
								fTpp = fTpp.tpp;
								fProduction = fProduction.production;
								var _maxSetup = parseInt((_maxDuration - (fTpp * fProduction * 1000)) / 1000);
								if(parseInt(val) > _maxSetup){
									this.markInvalid('Bu görev için ayar süresini en fazla '+_maxSetup+' sn tanımlayabilirsiniz!');
									this.focus();
									this.setValue(_maxSetup);
									return false;
								}else
									this.clearInvalid();
								break;
							case 'tpp' :
								var fSetup = form.getValue('setup'), fProduction = form.getValue('production');
								fSetup = fSetup.setup;
								fProduction = fProduction.production;
								var _maxTpp = parseInt((_maxDuration - (fSetup*1000)) / (fProduction * 1000));
								if(parseInt(val) > _maxTpp ){
									this.markInvalid('Bu görev için birim üretim süresini en fazla '+_maxTpp +' sn tanımlayabilirsiniz!');
									this.focus();
									this.setValue(_maxTpp);
									return false;
								}else
									this.clearInvalid();
								break;
							case 'production' :
								var fSetup = form.getValue('setup'), fTpp = form.getValue('tpp');
								fSetup = fSetup.setup;
								fTpp = fTpp.tpp;
								var _maxProduction = parseInt((_maxDuration - (fSetup*1000)) / (fTpp * 1000));
								if(parseInt(val) > _maxProduction ){
									this.markInvalid('Bu görev için üretim miktarını en fazla '+_maxProduction +' tanımlayabilirsiniz!');
									this.focus();
									this.setValue(_maxProduction);
									return false;
								}else
									this.clearInvalid();
								break;
						}
						return true;
					};
				}
			}
			with(task)
				form.setValue({
					customer : customerId,
					dieId : dieId,
					leafId : leafId,
					name : name,
					station : station,
					setup : parseInt(setup/60),
					tpp : tpp,
					production : production,
					operator : operator,
					sampleProduction : sampleProduction
				});
			form.finishLoad();
			form.editingTask = task;
			win.show();
			form.cnt.height(win._els.center.height());
			win.isActive = true;
			t.setActiveRegion('detaywindow');
		}
	},
	loadWarnings : function(){
		var t = this;
		mj.load(t.resourceDiv, {
			url : t.ajaxForm.url,
			params : {
				event : 'getGanttMessages'
			}
		});
	},
	removeTask : function(task){
		var t=this,station = t.station[task.stationId];
		var start = task.order-1;
		var nt=t.getDependTasks(task);
		var st='';
		for(var i=0,len=nt.length;i<len;i++){
			if(nt[i].planned)
				st = st=='' ?nt[i].id:st+','+nt[i].id;
		}
		if(st!=''){
			new mj.message({
				title:'Uyarı',
				modal : true,
				msg:'Silmeden önce bu işe bağlı <b>' + st + '</b> nolu işler silinmelidir!',
				buttons:['OK'],
				cb:function(el,btn){
					el.window.close();
				}
			});
		}else{
			if(task.planned && task.planned != '0')
				t.removeTaskFromStation(task);
			// station.task.remove(task);
			// var _o=-1;
			// for(var i=0,l=task._station.task.length;i<l;i++)
				// task._station.task[i].order=_o++;
			t.setTaskValue(task);
			if(task.planned && task.planned != '0')
				t.saveStation(station);
			/*
			new mj.message({
				title:'Uyarı',
				modal : true,
				msg:'İstasyon Görevleri tekrar düzenlensin mi?',
				buttons:['NO','YES'],
				cb:function(el,btn){
					if(btn=='YES')
						t.rearrangeStation(station,start);
					el.window.close();
				}
			});
			*/
		}
		t.setModified(task);
	},
	renderTaskGridEls : function(val, task){
		if(task && task.id){
			var t = this;
			task.gridTask = t.getGridTask(task.id);
			return '<div class="mj-gantt-task-grid-el mj-opacity-7 mj-gantt-task-grid-el-'+task.id+'" style="z-index:1;position:relative;background:#fff;height:'+t.barHeight+'px;width:'+task.gridTask.sizes.gridElWidth+'px;border:1px solid #000;"></div>';
		}	
	},
	save : function(autoSave){
		var t = this;
		if(t.modified){
			var _save = function(){
				var modifiedTasks = [];
				for(var i=0,l=t.modified.length;i<l;i++){
					var task = t.modified[i], updObj;
					with(task){
						updObj = {
							id : id,
							dieId : dieId,
							leafId : leafId,
							name : name,
							description : description,
							operator : operator,
							station : station,
							setup : setup,
							tpp : tpp,
							production : production,
							inBox : inBox,
							planned : planned,
							pinned : pinned ? 1 : 0,
							sampleProduction : sampleProduction ? 1 : 0,
							startDate : parseInt(times.startDate/1000),
							finishDate : parseInt(times.finishDate/1000),
							productionDuration : parseInt(times.productionDuration/1000),
							duration : parseInt(times.duration/1000),
							actualLag : parseInt(times.actualLag/1000),
							setupStartDate : parseInt(times.setupStartDate/1000),
							actualSetup : parseInt(times.actualSetup/1000),
							productionStartDate : parseInt(times.productionStartDate/1000),
							actualProductionDuration : parseInt(times.actualProductionDuration/1000),
							productionFinishDate : parseInt(times.productionFinishDate/1000),
							actualDuration : parseInt(times.actualDuration/1000)
						};
						if(task.done){
							if(done.startDate)
								updObj.doneStartDate = done.startDate.getTime()/1000;
							if(done.setupStartDate)
								updObj.doneSetupStartDate = done.setupStartDate.getTime()/1000;
							if(done.setupFinishDate)
								updObj.doneSetupFinishDate = done.setupFinishDate.getTime()/1000;
							if(done.finishDate)
								updObj.doneFinishDate = done.finishDate.getTime()/1000;
							if(done.finished)
								updObj.finished = done.finished;
							if(done.actualOperatorCount)
								updObj.actualOperatorCount = done.actualOperatorCount;
							if(done.production)
								updObj.doneProduction = done.production;
						}
						var pd = [];
						for(var i2=0,l2=task.productionDetails.length;i2<l2;i2++){
							var pdi = task.productionDetails[i2];
							pd.push({id:pdi.id,production:pdi.production,scrap:pdi.scrap});
						}
						updObj.productionDetails = pd;
					}
					modifiedTasks.push(updObj);
				}
				modifiedTasks = modifiedTasks.toJSONString();
				t.submit({
					event : 'saveGantt',
					tasks : modifiedTasks,
					success : function(data){
						if(data.msg)
							t.showQuickMsg(data.msg);
						if(data.success)
							t.modified = false;
						t.waitMaskHide();
					}
				}, true);
			};
			if(autoSave==true)
				_save();
			else
				mj.message({
					title:'Onay',
					modal : true,
					msg:'Değişiklikleri kaydetmek istediğinizden emin misiniz?',
					buttons:['NO','YES'],
					cb:function(el,btn){
						el.window.close();
						if(btn=='YES')
							_save();		
					}
				});
		}
	},
	setTaskDrag : function(task){
		var t=this,task;
			task.drag = new mj.drag({
				el:task.gridEl,
				parent : mj.bd,
				position:'absolute',
				appendParent:true, 
				moving:false
			});
			task.drag.on('beforedrag', function(e){
				if(task.planned || t.activeRegion=='message' || t.activeRegion=='detaywindow' || (t.checkDependTask && !task.plannable))
					return false;
				if(task.predecessor){
					var _pT = t.getTask(task.predecessor);
					if(_pT && !_pT.planned){
						t.showQuickMsg('Öncelikle '+task.predecessor+' numaralı işi planlamalısınız!');
						return false;
					}
				}
				if(task.station){
					task.drag.dropEls = [];
					if(typeof task.stations=="string")
						task.stations = eval(task.stations);
					for(var i=0,l=task.stations.length;i<l;i++)
						if(t.getStationObject(task.stations[i]))
							task.drag.dropEls.push(t.getStationObject(task.stations[i]).chartEl);
					if(task.drag.dropEls.length==1){
						var cbody = t.domEls.chartEls.chartBody, of = task._station.chartEl.offset({relativeTo:cbody});
						cbody.animate({scrollTop : of.top},250);
					}
					t.maskStations(task.stations);
				}
				if(task.drag.dropEls.length==0){
					t.showQuickMsg(mj.lng.glb.accessDenied);
					return false;
				}else
					return true;
			});
			task.drag.on('dragstop',function(e,target){
				if(target){
					var station = $(target).attr('name').replace('station-','');
					station = t.station[station];
					t.assignTaskToStation(this,station,t);
					t.setModified(task);
				}
				t.unMaskStations.call(t);
			},task);	
			if (task.planned)
				task.drag.pause = true;	
	},
	setTaskErrorState : function(task, val){
		task._error = val;
		task.el.css('border',val ? '1px dashed #f00;' : '1px solid black;');
	},
	setTaskValue : function(task){
		// var t=this,g = t.grids.gorev ;
		// if(g.rows.length>0){
			// var rowIndex = mj.getIndex(g.rows,'data',task);
			// for(var i=0,len=g.cm.length;i<len;i++){
				// var c = g.cm[i];
				// if(c.dataIndex!='duration'&&rowIndex!=-1)
					// g.setCellValue(rowIndex,mj.getIndex(g.rows[rowIndex].cols,'dataIndex',c.dataIndex),task[c.dataIndex],c.renderer);
			// }
			// t.locateTask(task);
			// t.drawTaskDone(task);
		// }
		// t.checkTaskStatus(task);
		// t.drawResources();
	},
	updateTask : function(){
		var t=this,form=t.forms.tForm, task = form.editingTask, fv= form.getValue(), oldStation = task.station, newStation = fv.station;
		if(oldStation!=newStation){
			if(task.planned)
				t.moveTaskToStation(task, newStation);
			task.stations = [];
			task.stations.push(newStation);
		}
		with(task){
			name = t.forms.tForm._dieTriggerField.getElValue();
			dieId = fv.name;
			leafId = fv.leafId;
			station = fv.station;
			setup = fv.setup*60;
			tpp = fv.tpp;
			production = fv.production;
			operator = fv.operator;
			inBox = fv.inBox;
			sampleProduction = fv.sampleProduction;
		};
		if(!task.done)
			task.done = {};
		if((task.done.actualOperatorCount && parseInt(task.done.actualOperatorCount) != parseInt(fv.actualOperator))||(!task.done.actualOperatorCount && parseInt(fv.actualOperator)>0))
			task.done.actualOperatorCount = fv.actualOperator;
		if(fv.doneStartDate1 && fv.doneStartDate2){
			task.done.setupStartDate = new Date((new Date(fv.doneStartDate1*1000)).formatDate('m/d/Y')+' '+fv.doneStartDate2);
			task.done.startDate = task.done.setupStartDate;
		}
		if(fv.doneSetupFinishDate1 && fv.doneSetupFinishDate2)
			task.done.setupFinishDate = new Date((new Date(fv.doneSetupFinishDate1*1000)).formatDate('m/d/Y')+' '+fv.doneSetupFinishDate2);
		if(fv.doneFinishDate1 && fv.doneFinishDate2)
			task.done.finishDate = new Date((new Date(fv.doneFinishDate1*1000)).formatDate('m/d/Y')+' '+fv.doneFinishDate2);
		if(!!task.done.finished != !!fv.finished)
			task.done.finished = fv.finished;

		if(task._pdForm){
			var fv = task._pdForm.getValue();
			for(var x in fv){
				var i = fv[x];
				if(x.substr(0,x.indexOf('_'))=='leafProduction'){
					var leafId = x.substr(x.indexOf('_')+1);
					var pdId = task.productionDetails.getIndex('id', leafId);
					task.productionDetails[pdId].production = fv['leafProduction_'+pdId];
					task.productionDetails[pdId].scrap = fv['leafScrap_'+pdId];
					var pVal = parseInt(task.productionDetails[pdId].production + task.productionDetails[pdId].scrap);
					if((task.done.production && parseInt(task.done.production) != pVal)||(!task.done.production && pVal>0))
						task.done.production = pVal;
				}
			}
		}
		var doneExists = false;
		for(var x in task.done)
			if(typeof task.done[x]!='function'){
				doneExists = true;
				break;
			}
		if(!doneExists)
			task.done = false;
		t.calculateTask(task);
		t.calculateTaskSizes(task);
		t.setTaskValue(task);
		t.setModified(task);
		if(task.planned)
			t.checkStationLastTime(task._station);
		var _max = -1;
		for(var i=0,l=t.tasks.length;i<l;i++){
			task = t.tasks[i];
			if(task.times.duration>_max)
				_max = task.times.duration;
		}
		t._maxDuration = _max;
		for(var i=0,l=t.tasks.length;i<l;i++){
			task = t.tasks[i];
			t.calculateTaskSizes(task);
			var ts = task.sizes;
			task.gridEl.width(ts.gridElWidth);
			task.gridSetupEl.width(ts.gridSetupElWidth);
			task.gridProductionEl.css({width:ts.gridProductionElWidth,left:ts.gridSetupElWidth});
		}
	},
	_renderTaskGridEls : function(data){
		var t = this;
		var task = t.getGridTask(parseInt(data.id));
		if(task && task.id){
			//console.log(data.id);
			task.gridEl = $('.mj-gantt-task-grid-el-'+task.id, t._taskTreeCnt);
			task.gridEl.bind('dblclick',{scope:t,task:task},t.getTaskForm);
			var p = t.domEls.chartEls.taskPreviewPane;
			$(task.gridEl[0].parentNode.parentNode.parentNode).hover(function(){
				var _t = task.gridEl.clone().appendTo(p).css('margin-top',parseInt((t.resHeight-t.barHeight)/2));
				p.append('<span>'+task.production+' adet '+task.name+' : '+' Toplam '+task.operator+' kişi, '+mj.timeShow(task.times.duration,true)+'</span>');
				_t.width(task.sizes.elWidth+task.sizes.setupElWidth+1);
				$(_t[0].childNodes[0]).width(task.sizes.setupElWidth);
				$(_t[0].childNodes[1]).css('left',task.sizes.setupElWidth+1).width(task.sizes.elWidth);
			},function(){
				p.empty();
			});
			task.gridSetupEl = $(mj.NE(task.gridEl,{cls:'mj-gantt-task-grid-setup-el mj-opacity-7',style:'position:absolute;background:#8c8;height:'+t.barHeight+'px;width:'+task.sizes.gridSetupElWidth+'px;border-right:1px solid #000;'}));
			task.gridProductionEl = $(mj.NE(task.gridEl,{cls:'mj-gantt-task-grid-production-el mj-opacity-7 mj-gantt-task-grid-unplanned-el',style:'position:absolute;height:'+t.barHeight+'px;width:'+task.sizes.gridProductionElWidth+'px;left:'+task.sizes.gridSetupElWidth+'px;'}));
			task.gridEl.bind('click', {t:t, task:task}, t.gridElClick);
			task.gridEl.bind('mouseup', function(){
				t.unMaskStations.call(t);
			});
			t.setTaskDrag(task);
			task.loading = true;
			if(typeof t.refreshed == 'undefined')
				if(parseInt(task.planned))
					t.assignTaskToStation(task,t.station[task.station],t);
			task.loading = false;
			if(task.planned && task._reLocate){
				t.assignTaskToStation(task, task._station, t);
				t.locateTask(task);
				t.drawTaskDone(task);
				task._reLocate = false;
			}
		}
	}
};
mj.extend(mj.gantt2, mj.gantt);
mj.snapShot = function(config){
	mj.snapShot.superclass.constructor.call(this, config);
};
mj.snapShot.prototype = {
	componentClass : 'mj.snapShot',
	_firstDateSetted : false,
	_lastDateSetted : false,
	_minPredictionCount : 10,
	barHeight : 15,
	barTop : 2,
	buttons : false,
	cellHeight : 22,
	canvasColor : '#fff',
	canvasItemsDraw : false,
	chartWidth : false,
	displayLabels : false,
	doneBarHeight : 5,
	doneBarTop : 7,
	drawResourcesPane : false,
	durationUnit : 'second',
	forms : false,
	stores : false,
	firstColumnWidth : 120,
	firstDate : false,
	grids : false,
	id : false,
	lastDate : false,
	layouts : false,
	minResolution : 5000,
	maxResolution : 5000,
	oddEven : false,
	offTime : false,
	prefix : false,
	resCollapsed : true,
	resHeight : 160,
	series : false,
	station : false,
	timeInterval : '6hour',
	timeIntervalWidth : 50,
	windows : false,
	width : 1000,
	details : {
		ref : false
	},
	timeRangeMap : [{
			ms : 60000,
			f : 'H:i',
			name : 'minute',
			up : '5minute',
			top : 'quarterHour',
			title : '1 dakika'
		},{
			ms : 300000,
			f : 'H:i',
			name : '5minute',
			up : 'quarterHour',
			top : 'halfHour',
			title : '5 dakika'
		},{
			ms : 600000,
			f : 'H:i',
			name : '10minute',
			up : 'halfHour',
			top : 'hour',
			title : '10 dakika'
		},{
			ms : 900000,
			f : 'H:i',
			name : 'quarterHour',
			up : 'hour',
			top : '3hour',
			title : '15 dakika',
			min : true
		},{
			ms : 1800000,
			f : 'H:i',
			name : 'halfHour',
			up : '2hour',
			top : '4hour',
			title : '30 dakika'
		},{
			ms : 3600000,
			f : 'H:i',
			name : 'hour',
			up : '3hour',
			top : '6hour',
			title : '1 saat'
		},{
			ms : 7200000,
			f : 'H:i',
			name : '2hour',
			up : '4hour',
			top : '8hour',
			title : '2 saat'
		},{
			ms : 10800000,
			f : 'H:i',
			name : '3hour',
			up : '6hour',
			top : '12hour',
			title : '3 saat'
		},{
			ms : 14400000,
			f : 'H:i',
			name : '4hour',
			up : '8hour',
			top : '12hour',
			title : '4 saat'
		},{
			ms : 21600000,
			f : 'H:i',
			name : '6hour',
			up : '12hour',
			top : 'day',
			title : '6 saat'
		},{
			ms : 28800000,
			f : 'H:i',
			name : '8hour',
			up : 'day',
			top : '2day',
			title : '8 saat'
		},{
			ms : 43200000,
			f : 'H:i',
			name : '12hour',
			up : 'day',
			top : '2day',
			title : '12 saat'
		},{
			ms : 86400000,
			f : 'd/m',
			name : 'day',
			up : '2day',
			top : 'week',
			title : '1 gün'
		},{
			ms : 172800000,
			f : 'd/m',
			name : '2day',
			up : 'week',
			top : '4week',
			title : '2 gün',
			max : true
		},{
			ms : 604800000,
			f : 'd/m',
			name : 'week',
			title : '1 hafta'
		},{
			ms : 2419200000,
			f : 'd/m',
			name : '4week',
			title : '4 hafta'
	}],
	timeRange : ['minute', '5minute', '10minute', 'quarterHour', 'halfHour', 'hour', '2hour', '3hour', '4hour', '6hour', '8hour', '12hour', 'day', '2day', 'week', '4week'],
	render : function(){
		var t = this, d = t.domEls, id = t.id, n = mj.NE, fcw = t.firstColumnWidth, _w=t.renderTo.width(), _h = t.renderTo.height();
		t._labelsOn = t.displayLabels;
		t.waitMask = $(n(t.renderTo,{
			cls:'mj-page-wait-mask mj-opacity-8',
			style:'display:none;width:'+_w+'px;height:'+_h+'px;',
			html:'<table width="100%" height="100%"><tr><td align="center" valign="middle"><img src="'+mj.glb.imagePath+'ajax-loader.gif"/><br/><br/><span class="mj-page-wait-title">Lütfen Bekleyin...</span></td></tr></table>'
		}));
		t._window.addRelated(t.waitMask);
		d.quickMsgEls = {'cnt':$(n(t.renderTo,{
			cls:'mj-gantt-quick-msg',
			style:'width:'+_w+'px;top:-20px',
			html:'<table width="100%" height="20px" cellpadding="0" cellspacing="0" style="position:absolute;top:0;"><tr><td align="center" valign="top"><table cellpadding="0" cellspacing="0"><tr><td style="width:20px;background:transparent url('+mj.glb.imagePath+'gantt-info.png) no-repeat 0 0">'+mj.insertSpacer(20,20)+'</td><td style="background:transparent url('+mj.glb.imagePath+'gantt-info.png) repeat-x 0 -40px"><span>...</span></td><td style="width:20px;background:transparent url('+mj.glb.imagePath+'gantt-info.png) no-repeat 0 -20px">'+mj.insertSpacer(20,20)+'</td></tr></table></td></tr></table>'
		}))};
		d.quickMsgEls.content = $('span', d.quickMsgEls.cnt);
		t.waitMaskShow();
		setTimeout(function(){
			t.windows = {};
			t.forms = {};
			t.grids = {};
			t.layouts = {};
			t.series = {};
			var scrollerSize = 16;
			t._chartClientWidth = t.width;
			var _items = [];
			t.layouts.main = new mj.layout({
				renderTo :n(t.renderTo,{tag:'div',id:'layout-cnt'}),
				layout : 'border',
				items : _items
			});
			t.tasks = t.stores.tasks.data;
			if(t.details.ref)
				t.referans = t.stores.referans.data;
			
			t.stores.tasks.on('load', function(){
				if(typeof t.refreshed == 'undefined'){
					var _max = -1;
					for(var i=0,l=t.stores.tasks.data.length;i<l;i++){
						var task = t.stores.tasks.data[i];
						task.loading =  false;
					}
					for(var i=0,l=t.stores.tasks.data.length;i<l;i++){
						var task = t.stores.tasks.data[i];
						task.startDate = new Date(parseInt(task.startDate+"000"));
						task.setupFinishDate = parseInt(task.setupFinishDate+"000");
						task.finishDate = parseInt(task.finishDate+"000");
						task.operatorCount = parseInt(task.operatorCount);
						task.station = parseInt(task.station);
						task.production = parseInt(task.production);
						task.productionDetails = eval(task.productionDetails);
						if(task.doneStartDate){
							task.done = {
								startDate : new Date(parseInt(task.doneStartDate+"000")),
								setupStartDate : new Date(parseInt(task.doneStartDate+"000")),
								setupFinishDate : new Date(parseInt(task.doneSetupFinishDate+"000")),
								qualityCall : parseInt(task.qualityCall+"000"),
								qualityCame : parseInt(task.qualityCame+"000"),
								qualityDone : parseInt(task.qualityDone+"000"),
								finishDate : new Date(parseInt(task.doneFinishDate+"000"))
							};
							task.done.finished = !!(parseInt(task.doneFinishDate));
						}
						t.calculateTaskSizes(task);
						if(task.station){
							task._station = t.getStationObject(task.station);
							t.drawTaskToStation(task, task._station);
						}
					}
				}
			});
			t.stores.tasks.on('load',function(){
				// if(typeof t.refreshed != 'undefined')
					// delete t.refreshed;
				// t.drawCanvas();
				// for(var i=0,l=t.tasks.length;i<l;i++){
					// var task = t.tasks[i];
					// if($.browser.msie){
						// task.gridSetupEl[0].style.background='#ffc';
						// if(task.color)
							// task.gridProductionEl[0].style.background=task.color;
					// }else{
						// task.gridSetupEl.css('background','#ffc');
						// if(task.color)
							// task.gridProductionEl.css('background',task.color);
					// }
				// }
			});
			t._bindInputKeys = function(input){
				$(input).bind('keydown', {t:t}, function(e){
					if(e.keyCode==13){
						t.sc = t;
						t.filterTasks.call(t);
					}
				});
				$(input).bind('focus', {t:t}, function(e){
					t.filterInputs.isActive = true;
					t.filterInputs.activeInput = input;
					t.setActiveRegion('filter');
					t.isInInput = true;
				});
				$(input).bind('blur', {t:t}, function(e){
					t.filterInputs.isActive = false;
					t.isInInput = false;
				});
			};
			var _cnt = $(t.layouts.main.getBody('center'));
			t.chartWidth = _cnt.width();
			t.height = _cnt.height();
			
			t.chartHeight = t.height;
			
			
			d.chartCnt = $(n(_cnt,{id:id+'-chart-container mj-resize-handle', cls:'mj-gantt-chart-container',style:'width:'+(t.chartWidth)+'px;height:'+(t.chartHeight)+'px;'}));
			mj.bindResize(_cnt, t.doResize, t);
			var ce = d.chartEls = {};
			var hRH = 23;
			ce.corner = $(n(d.chartCnt, {style:'width:'+fcw+'px;height:'+(3*hRH)+'px;float:left;background:#edf3fb;border-right:1px solid #ccc;'}));
			var btnCnt = n(ce.corner, {style:'margin-left:23px;margin-top:14px;'});
			t.buttons.zoomInBtn = new mj.speedButton({renderTo:btnCnt, iconCls:'mj-zoom-in',alt : 'Yakınlaş',scope:t, handler:t.zoomIn});
			t.buttons.zoomOutBtn = new mj.speedButton({renderTo:btnCnt, iconCls:'mj-zoom-out',alt:'Uzaklaş',scope:t, handler:t.zoomOut});
			t.buttons.zoomResetBtn = new mj.speedButton({renderTo:btnCnt, iconCls:'mj-zoom',alt:'Sıfırla',scope:t, handler:t.zoomReset});
			
			ce.header = $(n(d.chartCnt, {id:id+'-headers', cls:'mj-gantt-headers',style:'width:'+(t.chartWidth-fcw-scrollerSize-1)+'px;height:'+(3*hRH)+'px;float:left;overflow:hidden;'}));
			n(d.chartCnt,{style:'width:'+scrollerSize+'px;float:left;height:'+(3*hRH)+'px;background:#edf3fb;',html:mj.insertSpacer(scrollerSize, 3*hRH)});
			ce.headers = {
				line1 : $(n(ce.header, {style:'width:'+t._chartClientWidth+'px;height:'+hRH+'px;',cls:'mj-gantt-header1'})),
				line2 : $(n(ce.header, {style:'width:'+t._chartClientWidth+'px;height:'+hRH+'px;',cls:'mj-gantt-header2'})),
				line3 : $(n(ce.header, {style:'width:'+t._chartClientWidth+'px;height:'+hRH+'px;',cls:'mj-gantt-header3'}))
			};
			t._chartBodyWidth = t.chartWidth-fcw-1;
			t._chartBodyHeight = t.chartHeight-(3*hRH)-1;
			ce.stations = $(n(d.chartCnt, {style:'width:'+fcw+'px;height:'+t._chartBodyHeight+'px;float:left;background:#edf3fb;border:1px solid #ccc;border-left:0;border-bottom:0;overflow:hidden'}));
			ce.stationsCnt = $(n(ce.stations, {id:id+'-stations', style:'width:'+fcw+'px;height:'+(t.chartHeight-(3*hRH)-scrollerSize-1)+'px;overflow:hidden'}));
			ce.chartBody = $(n(d.chartCnt, {id:id+'-chart-body', cls:'mj-gantt-grab', style:'width:'+(t._chartBodyWidth)+'px;height:'+t._chartBodyHeight+'px;float:left;background:#fff;overflow:scroll;border-top:1px solid #ccc;position:relative;'}));
			ce.chartBodyScroll = $(n(ce.chartBody, {id:id+'-chart-body-scroll', style:'float:left;position:relative;width:'+t._chartClientWidth+'px;'}));
			ce.chartRowsBody = $(n(ce.chartBodyScroll));
			
			ce.infoPane = $(mj.NE(t.layouts.main.getBody('center'), {cls:'mj-gantt-task-info',style:'opacity:0.9;width:'+(t.chartWidth-fcw-scrollerSize-3)+'px;height:'+(3*hRH)+'px;background:#f4f9a6;position:absolute;top:0;left:'+(fcw+1)+'px;font-size:11px;padding-left:2px;display:none'}));
			if(!$.browser.msie){
				ce.chartBody.bind('mousedown',function(e){
					if(e.which==1&&$(e.target).hasClass('mj-gantt-grab')){
						ce._dragStarted={x:e.layerX,y:e.layerY};
						ce.chartBody[0].style.cursor='url('+mj.glb.imagePath+'pt/closedhand.cur'+'),default;';
					}
				});
				ce.chartBody.bind('mouseup',function(e){
					if(e.which==1&&$(e.target).hasClass('mj-gantt-grab')){
						ce._dragStarted=false;
						ce.chartBody[0].style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
					}
				});
				ce.chartBody.bind('mouseout',function(e){
					if(e.which==1&&$(e.target).hasClass('mj-gantt-grab')){
						ce._dragStarted=false;
						ce.chartBody[0].style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
					}
				});
				ce.chartBody[0].style.cursor='url('+mj.glb.imagePath+'pt/openhand.cur'+'),default;';
				ce.chartBody.bind('mousemove',function(e){
					if(ce._dragStarted){
						var _x = ce._dragStarted.x-e.layerX, _y = ce._dragStarted.y-e.layerY;
						ce.chartBody[0].scrollLeft += _x;
						ce.chartBody[0].scrollTop += _y;
					}
				});
			}

			t.tasks = t.stores.tasks.data;

			t.lastColorIndex = 0;
			t.windows.detay = $(n(_cnt,{cls:'mj-gantt-task-detail', style:'display:none;width:'+t.chartWidth+'px;height:'+t.height+'px;z-index:100'}));
			
			t.windows.detay.isActive = false;
			t.setActiveRegion('body');
			
			t.windows.detay._els = {center:$(n(t.windows.detay,{cls:'mj-gantt-task-detail-center',style:'width:'+t.chartWidth+'px;height:'+(t.height-30)+'px;'})), south:$(n(t.windows.detay,{cls:'mj-gantt-task-detail-south',style:'width:'+t.chartWidth+'px;'}))};
			var _btnCnt = n(t.windows.detay._els.south, {style:'float:right;padding:1px;'});
			t.windows.detay._buttons = {
				'vazgec':new mj.button({renderTo:n(_btnCnt), title:'Vazgeç', iconCls:'mj-menu-close-icon', handler:function(){
					if(t.activeRegion != 'message'){
						if(t.forms.tForm.modified){
							t.setActiveRegion('message');
							mj.shortcuts.on('e', function(){
								mj.message.activeMessageWin.close();
								t.hideDetayWindow();
								t.focusFakeInput();
							});
							mj.shortcuts.on('h', function(){
								t.setActiveRegion('detaywindow');
								mj.message.activeMessageWin.close();
							});
							mj.shortcuts.on('k', function(){
								mj.message.activeMessageWin.close();
								t.windows.detay._buttons.kaydet.handler.call(t);
							});
							mj.message.defaults.buttonTitles.SAVEANDEXIT = 'Kaydet ve Çık';
							mj.message({
								title:'Uyarı',
								modal : true,
								msg:'Yaptığınız değişiklikler kaydedilmeden çıkılsın mı?',
								buttons:['NO','YES','SAVEANDEXIT'],
								cb:function(el,btn){
									if(btn=='YES'){
										t.hideDetayWindow();
										t.focusFakeInput();
									}else if(btn=='SAVEANDEXIT'){
										mj.message.activeMessageWin.close();
										t.windows.detay._buttons.kaydet.handler.call(t);
									}else
										t.setActiveRegion('detaywindow');
									el.window.close();
								}
							});
							mj.message.activeMessageWin.on('beforeclose', function(){
								mj.shortcuts.mon('e');
								mj.shortcuts.mon('h');
								mj.shortcuts.mon('k');
							});
						}else{
							t.hideDetayWindow();
							t.focusFakeInput();
						}
					}
				}}),
				'kaydet':new mj.button({renderTo:n(_btnCnt), title:'Kaydet', iconCls:'mj-accept', handler:function(){
					if(t.forms.tForm.modified){
						if(t.forms.tForm.recMode == 'edit')
							t.updateTask();
						else
							t.createTask();
					}
					t.hideDetayWindow();
					t.focusFakeInput();
				}})
			};
			t.stores['dieGroup'] = new mj.store({url : t.url,params : {event : 'getdieGroup', table : 'dieGroup'}});
			t.getStation();
			t.fillStation();
			t.fillChartTimeline();
			t.initSnapShotData();
			t.getOffTime();
			t.drawOffTime();
			t.hiddenElements = n(ce.header, {style:'position:absolute;top:-10000px;left:-100000px; display:none'});
			t.fakeInput = n(t.hiddenElements, {tag:'input'});
			t.ajaxForm = new mj.form({renderTo:n(t.hiddenElements), url : t.url});
			t._window.addRelated(t.ajaxForm);
			t.focusFakeInput();

			t.stores.tasks.load();
			ce.chartBody.scroll(function(e){
				ce.header[0].scrollLeft = e.target.scrollLeft;
				ce.stationsCnt[0].scrollTop = e.target.scrollTop;
			});
			t.bindShortcuts();
			var w = t._window;
			w.on('beforeclose', function(){
				if(t.modified && t.modified.length>0){
					mj.message({
						title:'Uyarı',
						modal : true,
						msg:'Yaptığınız değişiklikler kaydedilmeden çıkılsın mı?',
						buttons:['NO','YES'],
						cb:function(el,btn){
							if(btn=='YES'){
								t.modified = false;
								window.dropEls = false;
								w.close();
							}
							el.window.close();
						}
					});
					return false;
				}
				window.dropEls = false;
			});
			t.waitMaskHide();
		},10);
	},
	addOffTimeTick : function(sd,durMs){
		var t=this;
		var addMs=durMs;
		var fd = sd + durMs;
		for(var i=0,len=t.offTimeTick.length;i<len;i++){
			var off = t.offTimeTick[i];
			if((sd<=off.start&&fd>=off.finish)||(fd>=off.start&&fd<=off.finish)){
				addMs += off.finish - off.start;
				fd+=off.finish - off.start;
			}else if(fd<off.start)
				break;
		}
		return addMs;
	},
	addOffTimeTickReverse : function(fd,durMs){
		var t=this;
		var addMs=durMs;
		var sd = fd - durMs;
		for(var i=0,len=t.offTimeTick.length;i<len;i++){
			var off = t.offTimeTick[i];
			if(fd<off.start)
				break;
		}
		if(i<len)
			for(var j=i;j>=0;j--){
				var off = t.offTimeTick[j];
				if((sd<=off.start&&fd>=off.finish)||(fd>=off.start&&fd<=off.finish)){
					addMs += off.finish - off.start;
					sd-=off.finish - off.start;
				}else if(sd>off.finish)
					break;
			}
		return addMs;
	},
	arrangeTask : function(e,task,station,t){
		var left = e.proxy[0].offsetLeft;
		var time=t.checkStationTask(task,station,t.getTimeFromPx(left));
		if(time){
			e.proxy.css('left',t.getPxFromTime(time));
			task.startDate.setTime(time);
			t.calculateTaskSizes(task);
			t.setTaskLeftWidth(task,task.times.actualDuration);	
			if (task.times.finishDate>station.lastTime.getTime()){
				station.lastTime.setTime(task.times.finishDate);
			}
			t.setTaskValue(task);
		}else
			e.proxy.css('left',t.getPxFromTime(task.startDate.getTime()));
		var nt = t.getDependTasks(task);	
		for(var i=0,len=nt.length;i<len;i++){
			var ct = nt[i];
			if(ct.planned){
				var time=t.checkStationTask(ct,t.station[ct.station],ct.startDate.getTime());
				if(time)
					$(ct.el).css('left',t.getPxFromTime(time));
			}
		}
	},
	bindInfoPane : function(task){
		var t = this, infoPane = t.domEls.chartEls.infoPane;
		task.el.bind('mouseout', function(){
			if(window.activeTimer)
				clearTimeout(window.activeTimer);
			infoPane.fadeOut(250);
		});
		task.el.bind('mouseover', {task:task}, function(e){
			var task = e.data.task;
			t.showTaskQuickInfo(task);
		});
	},
	bindShortcuts : function(){
		var t = this, sOn = mj.shortcuts.on;
		sOn('esc', function(){
			if(t.activeRegion=='message'){
				mj.message.activeMessageWin.close();
				t.focusFakeInput();
			}else if(t.windows.detay.isActive)
				t.windows.detay._buttons.vazgec.handler.call(t);
			else if(t.filterInputs.isActive){
				t.focusFakeInput();
				t.grids.gorev.selectRow(t.grids.gorev, 0);
				t.setActiveRegion('grid');
			}
		});
		sOn('ctrl+q', function(){
			if(!t.time.min)
				t.zoom(-1);
		});
		sOn('ctrl+w', function(){
			if(!t.time.max)
				t.zoom(1);
		});
		sOn('ctrl+l', function(){
			t.labelsShowHide();
		});
	},
	calculateTask : function(task){
		if(!task.times || !task.loading){
			var t = this, tt = task.times = {
				startDate : task.startDate.getTime(),
				finishDate : task.finishDate
			};
			tt.productionDuration = task.finishDate - task.setupFinishDate;
			tt.duration = task.finishDate - task.startDate;
			tt.setupDuration = task.setupFinishDate - task.startDate;
			tt.setupStartDate = tt.startDate;
			tt.productionStartDate = task.setupFinishDate;
			tt.productionFinishDate = task.finishDate;
		}
	},
	calculateTaskSizes : function(task){
		if(!task.times)
			this.calculateTask(task);
		var t = this, tt = task.times, ts = task.sizes = {};
		var _timeScale = t.timeIntervalWidth/t.time.ms;
		ts.elWidth = parseInt(_timeScale * tt.duration)-1;
		ts.setupElWidth = parseInt(_timeScale * tt.setupDuration)-1;
		ts.lagWidth = 0;
		ts.productionElWidth = ts.elWidth - (ts.setupElWidth - ts.lagWidth);
	},
	clearChartComponents : function(){
		var t = this, de = t.domEls, ce = de.chartEls, he = ce.headers;
		he.line1.empty();
		he.line2.empty();
		he.line3.empty();
		for(var i=0,len=t.offTimeTick.length;i<len;i++)
			if(t.offTimeTick[i].el){
				$(t.offTimeTick[i].el).remove();
				t.offTimeTick[i].el = false;
			}
	},
	doResize : function(){
		var t = this, _cnt = $(t.layouts.main.getBody('center')), _clientRect = t.layouts.main.renderTo, w = _cnt.width(), h = _cnt.height(), cw = _clientRect.width(), ch = _clientRect.height();
		t.setChartWidth(w, cw);
		t.setChartHeight(h, ch);
	},
	drawTaskDone : function(task){
		var t=this, n=mj.NE, doneElExists = false;
		if(task.planned){
			if(task.el && task.done && task.done.finished){
				if(task.doneEls)
					t.redrawTaskDone(task);
				else{
					var station=task._station, de = task.doneEls = {
						doneEl : task.el.clone().appendTo(station.chartEl)
					};
					de.doneEl.css({"position":"absolute",/* "opacity":"1", */"z-index":"10","top":t.doneBarTop+"px","height":t.doneBarHeight+"px"});
					de.doneSetupEl = de.doneEl.children('div:first');
					de.doneProductionEl = de.doneSetupEl.next();
					// de.doneEl.removeClass('mj-opacity-7');
					// de.doneSetupEl.removeClass('mj-opacity-7');
					// de.doneProductionEl.removeClass('mj-opacity-7');
					de.doneSetupEl.css({'height':t.doneBarHeight, 'background-color':'#ffff6b'});
					de.doneProductionEl.css({'height':t.doneBarHeight, 'background-color':'#fff'});
					de.doneActualSetupEl = $(n(de.doneEl,{style:'height:'+t.doneBarHeight+'px;background-color:#c2c229;position:absolute'}));
					de.doneActualProductionEl = $(n(de.doneProductionEl,{style:'height:'+t.doneBarHeight+'px;background-color:'+task.color+';'}));
					de.doneEl.bind('dblclick',{scope:t,task:task},t.getTaskForm);
					de.doneEl.bind('mouseout', function(){
						if(window.activeTimer)
							clearTimeout(window.activeTimer);
						t.domEls.chartEls.infoPane.hide();
					});
					de.doneEl.bind('mouseover', {task:task}, function(e){
						var task = e.data.task;
						t.showTaskQuickInfo(task);
					});
					de.stopCnt = $(n(de.doneEl));
					t.redrawTaskDone(task);
				}
				doneElExists = true;
			}
			if(doneElExists){
				task.titleCnt = task.doneEls.doneEl;
				task._titleAbsolute = false;
			}else{
				var l = task.left ? task.left : t.getPxFromTime(task.times.startDate);
				task.titleCnt = $(n(task._station.chartEl,{style:'position:absolute;left:'+l+'px;top:8px;z-index:10;'}));
				task._titleAbsolute = true;
			}
			if(task.titleEl)
				task.titleEl.remove();
			if(t.displayLabels){
				var titleLeft = 5, titleTop = -5, tn = task.name;
				task.titleEl = $(n(task.titleCnt,{cls:'mj-unselectable', style:'white-space:nowrap;font-size:11px;font-weight:bold;color:#1d1d1d;display:'+(t._labelsOn?'block':'none'),html : '<div style="height: 17px; top: -4px; left: 6px; position: absolute;">'+tn+'</div><div style="height: 17px; top: -4px; left: 4px; position: absolute;">'+tn+'</div><div style="height: 17px; top: -6px; left: 6px; position: absolute;">'+tn+'</div><div style="height: 17px; top: -6px; left: 4px; position: absolute;">'+tn+'</div><div style="height: 17px; top: -5px; left: 5px; position: absolute;color:white;">'+tn+'</div>'}));
			}
		}
	},
	drawTaskToStation : function(task,station){
		var t=this;
		var cell = station.chartEl;
		task.planned = true;
		task.el = $(mj.NE(cell,{cls:'mj-gantt-task-grid-el mj-opacity-7',style:'z-index:1;position:relative;background:#fff;height:'+t.barHeight+'px;width:'+task.sizes.elWidth +'px;border:1px solid #000;'}));
		task.setupEl = $(mj.NE(task.el,{cls:'mj-gantt-task-grid-setup-el mj-opacity-7',style:'position:absolute;background:#8c8;height:'+t.barHeight+'px;width:'+task.sizes.setupElWidth+'px;border-right:1px solid #000;'}));
		task.productionEl = $(mj.NE(task.el,{cls:'mj-gantt-task-grid-production-el mj-opacity-7 mj-gantt-task-grid-unplanned-el',style:'position:absolute;height:'+t.barHeight+'px;width:'+task.sizes.productionElWidth+'px;left:'+task.sizes.setupElWidth+'px;'}));
		t.bindInfoPane(task);
		// task.setupEl = task.el.children('div:first');
		// task.productionEl = task.setupEl.next();
		if(!task.color)
			t.getColor(task);
		if(task.pinned)
			task.el.css('border','1px solid #f00;');
		task.el.css({"cursor":"default","position":"absolute","top":t.barTop + "px"});
		task.el.addClass('mj-gantt-task-el');
		task.el.attr('name','task-'+task.id);
		task.el.children('div').attr('name','task-'+task.id);

		task.setupEl.css({ background: "#ffc" });

		task.productionEl.css({ background: task.color });
		
		t.setTaskLeftWidth(task);
		t.drawTaskDone(task);
	},
	drawOffTime : function(){
		var t=this;
		var height = t.stores.station.data.length*t.cellHeight;
		for(var i=0,len=t.offTimeTick.length;i<len;i++){
			var tick = t.offTimeTick[i];
			var left = t.getPxFromTime(tick.start);
			var width = t.getPx(tick.finish-tick.start);	
			var sdate = new Date(tick.start);
			var fdate = new Date(tick.finish);
			if((sdate<t.firstDate && fdate>t.firstDate &&fdate<t.lastDate)||(sdate>t.firstDate && fdate<t.lastDate)||(sdate>t.firstDate && sdate<t.lastDate &&fdate>t.lastDate)){
				if(!tick.el)
					tick.el=mj.NE(t.domEls.chartEls.chartBody, {cls:'mj-gantt-grab mj-gantt-off-time', style:'left:'+(left)+'px;width:'+(width)+'px;height:'+(height)+'px;',title:tick.name+sdate.formatDate(' [H:i-')+fdate.formatDate('H:i]')});
				else
					$(tick.el).css('left',left+'px').css('width',width+'px');
			}
		}
	},
	fillChartTimeline : function(){
		var maxDivCount = 336;
		var t=this, hEls = t.domEls.chartEls.headers, oddEven = t.oddEven;
		var height = t.stores.station.data.length*t.cellHeight;
		t.chartBodyHeight = height;
		t.firstDate.setHours(0,0,0,0);
		t.time = t.timeRangeMap[t.timeRange.indexOf(t.timeInterval)];
		t.timeTop = t.timeRangeMap[t.timeRange.indexOf(t.time.top)];
		t.timeUp = t.timeRangeMap[t.timeRange.indexOf(t.time.up)];
		var minInterval = t.time.ms;
		
		if(!t._lastDateSetted){
			t.lastDate = new Date(t.firstDate.getTime() + (minInterval * maxDivCount));
			if(((t.lastDate.getTime()-t.firstDate.getTime())/minInterval)>=maxDivCount)
				t.lastDate.setTime(t.firstDate.getTime() + (minInterval * maxDivCount));
			t.lastDate.setTime(t.lastDate.getTime() + 86400000);
			t.lastDate.setHours(0, 0, 0, 0);
		}
		t.setTimeLineWidth(t.timeIntervalWidth*((t.lastDate-t.firstDate)/minInterval));
		
		hEls.line3.attr('title', t.time.title);
		
		t.upperTimeInterval = t.timeUp.ms;
		hEls.line2.attr('title', t.timeUp.title);
		
		t.topTimeInterval = t.timeTop.ms;
		hEls.line1.attr('title', t.timeTop.title);
		
		t.timeLine = [];
		t.domEls.chartEls.chartBodyScroll.css('background', 'transparent url('+mj.glb.snapShotPath+'?w='+t.timeIntervalWidth+')');
		var _t = t.firstDate.getTime(), curDate = new Date(_t), upDate = new Date(_t), topDate = new Date(_t);
		var bg='#fff';
		var downK = t.time.ms/minInterval, upK = t.timeUp.ms/minInterval, topK = t.timeTop.ms / minInterval, totalStep = (t.lastDate.getTime()-t.firstDate.getTime())/minInterval, j = 0;
		var downTitles = '', upTitles = '', topTitles = '';
		t.time.k = downK;
		t.timeUp.k = upK;
		t.timeTop.k = topK;
		var _getCell = function(timeScope, cDate, pos){
			return {width : t.timeIntervalWidth*timeScope.k-4, title : '<span title="'+cDate.formatDate('d/m/Y H:i')+'">'+cDate.formatDate(timeScope.f)+'</span>'};
		};
		while (curDate<t.lastDate){
			if(j%topK == 0){
				var oeCls = oddEven ? (parseInt(j/topK) % 2 ? '-o' : '' ) : '';
				var cell = _getCell(t.timeTop, curDate);
				topTitles += '<div class="mj-gantt-header1'+oeCls+' mj-unselectable" style="float:left;border-right:1px solid #aaa;width:'+ cell.width +'px;padding-top:7px;padding-left:3px;height:16px;">'+cell.title+'</div>';
			}
			if(j%upK == 0){
				var oeCls = oddEven ? (parseInt(j/upK) % 2 ? '-o' : '' ) : '';
				var cell = _getCell(t.timeUp, curDate);
				upTitles += '<div class="mj-gantt-header2'+oeCls+' mj-unselectable" style="float:left;border-right:1px solid #aaa;width:'+ cell.width +'px;padding-top:7px;padding-left:3px;height:16px;">'+cell.title+'</div>';
			}
			if(j%downK == 0){
				var oeCls = oddEven ? (parseInt(j/downK) % 2 ? '-o' : '' ) : '';
				var cell = _getCell(t.time, curDate);
				downTitles += '<div class="mj-gantt-header3'+oeCls+' mj-unselectable" style="float:left;border-right:1px solid #aaa;width:'+ cell.width +'px;padding-top:7px;padding-left:3px;height:16px;">'+cell.title+'</div>';
			}
			curDate.setTime(curDate.getTime()+minInterval);
			++j;
		}
		hEls.line1[0].innerHTML = topTitles;
		hEls.line2[0].innerHTML = upTitles;
		hEls.line3[0].innerHTML = downTitles;
	},
	fillStation : function(){
		var t=this, ce = t.domEls.chartEls;
		var sts = t.stores.station.data;
		var height = sts.length*t.cellHeight;
		t.domEls.chartEls.chartBodyScroll.height(height);
		ce.stationsCnt.empty();
		ce.chartStationBody = mj.NE(ce.stationsCnt, {cls:'mj-unselectable', style:'float:left;background:#ddd;border-right:1px solid #aaa;width:'+ (t.firstColumnWidth) +'px;height:'+(height)+'px;'});
		if(ce.chartRowsBody)
			ce.chartRowsBody.remove();
		ce.chartRowsBody = $(mj.NE(ce.chartBodyScroll, {style:'position:relative;'}));
		window.dropEls = [];
		for (var i=0,len=sts.length;i<len;i++){
			var st = sts[i], _st = t.station[st.id];
			_st.el = mj.NE(ce.chartStationBody, {html : st.name,cls:'mj-gantt-station-title',style:'text-align:left;padding-left:2px;float:left;border-bottom:1px solid #D3D3D3;width:'+ (t.firstColumnWidth) +'px;height:'+(t.cellHeight-4)+'px;padding-top:3px;'});
			_st.chartEl =  $(mj.NE(ce.chartRowsBody, {name:'station-'+st.id,cls:'mj-gantt-grab',style:'position:absolute;top:'+((i*t.cellHeight))+'px;background:transparent;border-bottom:1px solid #D3D3D3;width:'+t._chartClientWidth+'px;height:'+(t.cellHeight-1)+'px;'}));
			dropEls.push(_st.chartEl);
			$(_st.el).bind('dblclick',{station:st.id,scope:t},t.getStationTask);
			
			// _st.chartEl.bind('mouseover', {station:_st, scope:t}, function(e){
				// e.data.scope.labelsShowHide(e.data.station);
			// });
			// _st.chartEl.bind('mouseout', {station:_st, scope:t}, function(e){
				// e.data.scope.labelsShowHide(e.data.station);
			// });
		}		
	},
	focusFakeInput : function(){
		this.fakeInput.focus();
		this.setActiveRegion('body');
	},
	// getCustomer : function(i){
		// var _i = mj.getIndex(this.stores.customer.data,'id',i);
		// if(_i>-1)
			// return this.stores.customer.data[_i];
		// else
			// return {id:0,code:'-'};
	// },	
	getColor : function (task){
		return task.color = this.colorGenerator.generate();
	},
	getOffTime : function(){
		var t=this;
		var tempTick = [];
		var fd=t.firstDate.getTime(),ld=t.lastDate.getTime();
		
		for(var i=0,len=t.offTime.length;i<len;i++){
			var x = t.offTime[i];
			switch(x.scope){
				case 'day':
					for(var j=0;j<x.items.length;j++){
						var obj = x.items[j], ts = obj.s*1000,te = obj.e*1000;
						if ((ts>=fd&&ts<ld)||(te>fd&&te<=ld)){
							var start=(ts>fd?ts:fd),finish=(te>ld?ld:te);
							tempTick.push({name:obj.name,start:start,finish:finish});
						}
					}
					break;
				case 'weekday':
					var cdate = new Date(fd);
					var offTime = [];
					for(var j=0;j<x.items.length;j++){
						var obj = x.items[j];
						if(!obj.s)
							var start = 0;
						else{
							var m = /(\d*):(\d*)/.exec(obj.s);
							var start = (m[1]*(60*60*1000))+(m[2]*(60*1000));
						}
						if(!obj.e)
							var finish = 86400000;
						else{
							var m = /(\d*):(\d*)/.exec(obj.e);
							var finish = (m[1]*(60*60*1000))+(m[2]*(60*1000));
						}
						offTime.push({name:obj.name,d:obj.d,s:start,f:finish,gecerlilikBaslangici:obj.gecerlilikBaslangici,gecerlilikBitimi:obj.gecerlilikBitimi});
					}
					ti=24*60*60*1000;
					cdate.setHours(0,0,0,0);
					while (cdate.getTime()<ld){
						var curday = cdate.getTime();
						for(var j=0;j<offTime.length;j++){
							var obj = offTime[j];
							if(obj.d==((cdate.getDay()+1)%7)){
								var ts = curday+obj.s,te = curday+obj.f;
								if (((ts>=fd&&ts<ld)||(te>fd&&te<=ld)) && ((ts>=obj.gecerlilikBaslangici&&ts<obj.gecerlilikBitimi)||(te>obj.gecerlilikBaslangici&&te<=obj.gecerlilikBitimi))){
									var start=(ts>fd?ts:fd),finish=(te>ld?ld:te);
									start=(start>obj.gecerlilikBaslangici?start:obj.gecerlilikBaslangici);
									finish=(finish>obj.gecerlilikBitimi?obj.gecerlilikBitimi:finish);
									tempTick.push({name:obj.name,start:start,finish:finish});
								}
							}
						}
						cdate.setTime(cdate.getTime()+ti);
					}
					break;
				case 'hour':
					var cdate = new Date(fd>obj.gecerlilikBaslangici ? fd : obj.gecerlilikBaslangici);
					var ti=60*60*1000;
					while (cdate.getTime()<ld){
						var _i = x.items.indexOf(cdate.getHours());
						if(_i>-1){
							var obj = x.items[_i];
							var ts = cdate.getTime(),mod=ts%ti,ts=ts-mod,te = ts + ti;
							if((ts>=obj.gecerlilikBaslangici&&ts<obj.gecerlilikBitimi)||(te>obj.gecerlilikBaslangici&&te<=obj.gecerlilikBitimi)){
								var start=(ts>fd?ts:fd),finish=(te>ld?ld:te);
								start=(start>obj.gecerlilikBaslangici?start:obj.gecerlilikBaslangici);
								finish=(finish>obj.gecerlilikBitimi?obj.gecerlilikBitimi:finish);
								tempTick.push({name:x.name,start:start,finish:finish});
							}
						}
						cdate.setTime(cdate.getTime()+ti);
					}
					break;	
				case 'time':
					var cdate = new Date(fd);
					var offTime = [];
					for(var j=0;j<x.items.length;j++){
						var obj = x.items[j];
						if(obj.f=='G:i'){
							var m = /(\d*):(\d*)/.exec(obj.s);
							var start = (m[1]*(60*60*1000))+(m[2]*(60*1000));
							var m = /(\d*):(\d*)/.exec(obj.e);
							var finish = (m[1]*(60*60*1000))+(m[2]*(60*1000));
							offTime.push({name:obj.name,s:start,f:finish,gecerlilikBaslangici:obj.gecerlilikBaslangici,gecerlilikBitimi:obj.gecerlilikBitimi});
						}else
							break;
					}
					ti=24*60*60*1000;
					cdate.setHours(0,0,0,0);
					while (cdate.getTime()<ld){
						var curday = cdate.getTime();
						for(var j=0;j<offTime.length;j++){
							var obj = offTime[j];
							var ts = curday+obj.s,te = curday+obj.f;
							if(te<=ts)
								te += ti;
							if (((ts>=fd&&ts<ld)||(te>fd&&te<=ld)) && ((ts>=obj.gecerlilikBaslangici&&ts<obj.gecerlilikBitimi)||(te>obj.gecerlilikBaslangici&&te<=obj.gecerlilikBitimi))){
								var start=(ts>fd?ts:fd),finish=(te>ld?ld:te);
								start=(start>obj.gecerlilikBaslangici?start:obj.gecerlilikBaslangici);
								finish=(finish>obj.gecerlilikBitimi?obj.gecerlilikBitimi:finish);
								tempTick.push({name:obj.name,start:start,finish:finish});
							}
						}
						cdate.setTime(cdate.getTime()+ti);
					}
					break;
			}			
		}		
		t.offTimeTick =[];
		if(tempTick.length>0){
			tempTick.sort(function(a,b){
				return a.start-b.start;
			});
			var i=0;
			while(i<tempTick.length){
				var curTick = tempTick[i];
				if(i+1<tempTick.length&&curTick.finish>=tempTick[i+1].start){
					if(curTick.finish<tempTick[i+1].finish)
						curTick.finish = tempTick[i+1].finish;
					tempTick.splice(i+1,1);
				}else
					i++;
			}
			t.overTime.load();
			for(var j=0,l=t.overTime.recordCount;j<l;j++){
				t.overTime.data[j].startdate=t.overTime.data[j].startdate*1000;
				t.overTime.data[j].finishdate=t.overTime.data[j].finishdate*1000;
			}
			var i=0;
			while(i<tempTick.length){
				var tt = tempTick[i];
				var dontInc = false;
				for(var j=0,l=t.overTime.recordCount;j<l;j++){
					var ot = t.overTime.data[j];
					if(tt.start<=ot.startdate && tt.finish>=ot.startdate && tt.finish<=ot.finishdate){
						tt.finish=ot.startdate-1;
					}else if(tt.start>=ot.startdate && tt.finish<=ot.finishdate){
						tempTick.splice(i,1);
						dontInc = true;
						break;
					}else if(tt.start>=ot.startdate && tt.start<=ot.finishdate && tt.finish>=ot.finishdate){
						tt.start=ot.finishdate+1;
					}
				}
				if(!dontInc)
					i++;
			}
			t.offTimeTick = tempTick;
		}
	},
	getPx : function(timeMs){
		return parseInt((timeMs*this.timeIntervalWidth)/this.time.ms);
	},
	getPxFromTime : function(time,d){
		if(!(d instanceof Date))
			d = this.firstDate;	
		if(time instanceof Date)
			var fark = (time.getTime()-d.getTime());
		else
			var fark = (time-d.getTime());
		return parseInt((fark*this.timeIntervalWidth)/this.time.ms);
	},	
	getReferans : function(i){
		var _i = mj.getIndex(this.stores.referans.data,'id',i);
		if(_i>-1)
			return this.stores.referans.data[_i];
		else
			return {id:0,name:'-'};
	},
	getStation : function(){
		var t=this,sts = t.stores.station.data;
		for (var i=0,len=sts.length;i<len;i++){
			t.station[sts[i].id]={
				id:sts[i].id, 
				order : i,
				task : [],
				lastTime : new Date(t.firstDate.getTime())
			};
		}
	},
	getStationData : function(val){
		var _i = mj.getIndex(this.stores.station.data,'id',val);
		if(_i>-1)
			return this.stores.station.data[_i];
		else
			return {id:0,name:'-'};
	},
	getStationObject : function(val){
		var _i = mj.getIndex(this.station,'id',val);
		if(_i>-1)
			return this.station[_i];
	},
	getTask : function(i){
		return this.tasks[mj.getIndex(this.tasks,'id',i)];
	},
	getTimeFromPx : function(px,d){
		if(!(d instanceof Date))
			d = this.firstDate;
		var ms = (px*this.time.ms)/(this.timeIntervalWidth), mod = ms % this.durationMsMultiplier;
		return d.getTime()+(ms-mod);
	},	
	gotoTaskEl : function(task){
		if(task.el){
			var t = this, _firstElO = t.station[t.stores.station.data[0].id].chartEl.offset(), _o = task.el.offset();
			t.domEls.chartEls.chartBody.animate({scrollTop : _o.top-_firstElO.top, scrollLeft:task.el[0].offsetLeft},1000, function(){
				window.mj._snapShotGridElBorderBlinkCount = 5;
				window.mj._snapShotGridElBorderBlinkColors = ['red', 'yellow'];
				window.mj._snapShotGridElBorderBlinkTrigger = function(){
					if(window.mj._snapShotGridElBorderBlinkCount-- >0){
						t._snapShotGridElBorderBlinkTimer=setTimeout(function(){mj._snapShotGridElBorderBlinkTrigger.call(t);},100);
						task.el.css('borderColor', mj._snapShotGridElBorderBlinkColors[mj._snapShotGridElBorderBlinkCount % 2]);
					}else
						task.el.css('borderColor', '#000');
				};
				window.mj._snapShotGridElBorderBlinkTrigger();
				t.showTaskQuickInfo(task, true);
			});
		}
	},
	gotoTime : function(time){
		var t = this;
		t.domEls.chartEls.chartBody.animate({scrollLeft:t.getPxFromTime(time)-parseInt(t._chartBodyWidth/2)},1000);
	},
	initSnapShotData : function(){
		var t=this;
		t.timeIntervalIndex = t.timeRange.indexOf(t.timeInterval);
		t.durationMsMultiplier = t.durationUnit=='minute'?60*1000:1000;
		t.time = t.timeRangeMap[t.timeRange.indexOf(t.timeInterval)];
		t.timeTop = t.timeRangeMap[t.timeRange.indexOf(t.time.top)];
		t.timeUp = t.timeRangeMap[t.timeRange.indexOf(t.time.up)];
		t.heightPerOp = 3;
		t.heightPerBox = 1;
		t.pastStation=[];
	},
	labelsShowHide : function(station){
		var t = this, _tasks = station ? station.task : t.tasks, task;
		if(t.displayLabels){
			t._labelsOn = !t._labelsOn;
			for(var i=0,l=_tasks.length;i<l;i++){
				task = _tasks[i];
				if(task.titleEl)
					task.titleEl.css('display', t._labelsOn ? 'block' : 'none');
			}
		}
	},
	locateTask : function(task){
		var t=this;
		t.calculateTaskSizes(task);
		var ts=task.sizes, tt=task.times;
		var left = task.left = t.getPxFromTime(tt.startDate);
		t.setTaskLabelLeft(task, left);
		if(task.el){
			task.el.css({"left":left + "px","width": (ts.elWidth)+'px'});
			task.setupEl.width(ts.setupElWidth);
			task.productionEl.css({width:ts.productionElWidth,left:ts.setupElWidth+ts.lagWidth});
		}
		t.drawTaskDone(task);
	},
	redrawTaskDone : function(task){
		if(task.done){
			var dbg = {};
			var t = this, de = task.doneEls, 
			setupLeft = t.getPxFromTime(task.done.setupStartDate), 
			actualSetupFinishDate = (task.done.setupFinishDate ? task.done.setupFinishDate.getTime() : task.done.setupStartDate.getTime()+task.times.actualSetup), 
			totalSetupWidth = t.getPx(actualSetupFinishDate-task.done.setupStartDate.getTime()),
			actualSetupWidth = t.getPx((task.done.setupFinishDate ? task.done.setupFinishDate.getTime() : t.curTimeMs)-task.done.setupStartDate.getTime());
			totalSetupWidth = Math.max(totalSetupWidth, actualSetupWidth);
			de.doneSetupEl.width(totalSetupWidth);
			de.doneActualSetupEl.width(actualSetupWidth);
			dbg.actualSetupFinishDate = actualSetupFinishDate;
			var productionDuration = 0;
			var stopCnt = de.stopCnt, n = mj.NE, stopDuration = 0,titleEl=de.titleEl;
			stopCnt.empty();
			var qcall = task.done.qualityCall, setupStart = task.done.setupStartDate.getTime();
			if(qcall){
				var qcame = task.done.qualityCame ? task.done.qualityCame : t.curTimeMs;
				var qdone = task.done.qualityDone;
				var dur = qcame-qcall, w = t.getPx(dur), l = t.getPx(qcall-setupStart);
				n(stopCnt,{style:'cursor:default;width:'+w+'px;height:5px;top:-1px;left:'+l+'px;background:#fbc11f;border:1px solid #4d3b07;position:absolute;',html:mj.insertSpacer(w,5),title:'Kalite Personeli Bekleme'});
				stopDuration += dur;
				dbg['qcame-qcall'] = dur;
				if(qdone){
					var dur = qdone-qcame, w = t.getPx(dur), l = t.getPx(qcame-setupStart);
					stopDuration += dur;
					dbg['qdone-qcame'] = dur;
					n(stopCnt,{style:'cursor:default;width:'+w+'px;height:5px;top:-1px;left:'+l+'px;background:#df641e;border:1px solid #451e07;position:absolute;',html:mj.insertSpacer(w,5),title:'Kalite Onayı'});
				}
			}
			if(task.stops){
				for(var ii=0,l=task.stops.length;ii<l;ii++){
					var st = task.stops[ii];
					if(st && typeof st!='function'){
						if(!task.done.finished){
							var sd = parseInt(st.time), fd = sd + parseInt(st.fark);
							stopDuration += parseInt(st.fark)*1000;
							dbg['st'+ii] = parseInt(st.fark)*1000;
							for(var i=0,len=t.offTimeTick.length;i<len;i++){
								var off = t.offTimeTick[i];
								if(sd<=off.start&&fd>=off.finish){
									stopDuration -= off.finish - off.start;
								}else if(sd<=off.start && fd>=off.start && fd<=off.finish){
									stopDuration -= fd - off.start;
								}else if(sd>=off.start&&fd<=off.finish){
									stopDuration -= fd - sd;
								}else if(sd<=off.start)
									break;
							}
						}
						var time = st.time*1000, fark = st.fark*1000;
						if(fark>=parseInt(t.time.ms/50)){
							var w = t.getPx(fark)-2, l = t.getPx(time-setupStart), d = new Date(time);
							w = w>0 ? w : 1;
							if(st.duruskod)
								var fd = new Date(time+fark);
							d=st.duruskod ? (d.formatDate('d.m H:i')+" - "+fd.formatDate('d.m H:i')+" arasında '"+st.description+"' sebebiyle "+mj.timeShow(fark,true)+" duruldu.") : (d.formatDate('d.m H:i')+"'den itibaren duruş devam ediyor.( "+mj.timeShow(fark,true)+")");
							st.el = n(stopCnt,{style:'cursor:default;width:'+w+'px;height:'+(t.doneBarHeight+2)+'px;top:-2px;left:'+l+'px;background:'+st.colorRGB+';border:1px solid black;position:absolute;',html:mj.insertSpacer(w,7),title:d});
						}
					}
				}
			}
			if(task.done.finishDate){
				productionDuration = task.done.finishDate.getTime() - actualSetupFinishDate;
			}else if(task.done.production){
				var pCount = task.productionDetails.length>0 ? -1 : task.done.production;
				if(task.productionDetails && task.productionDetails.length>0)
					for(var i=0,l=task.productionDetails.length;i<l;i++){
						var pd = task.productionDetails[i], total = parseInt(pd.production) + parseInt(pd.scrap);
						if(total>pCount)
							pCount = total;
					}
				var passed = t.curTimeMs-actualSetupFinishDate;
				dbg.curTimeMs=t.curTimeMs;
				dbg.passed=passed;
				// if(task.done.qualityDone)
					// stopDuration += task.done.qualityDone - task.done.qualityCall;
				// else if(task.done.qualityCame)
					// stopDuration += task.done.qualityCame - task.done.qualityCall;
				passed -= stopDuration;
				dbg.stopDuration=stopDuration;
				
				task._calculatedTpp = pCount<t._minPredictionCount ? task.tpp * 1000 : passed / pCount;
				productionDuration = task._calculatedTpp * (task.production - pCount);// + stopDuration;
// console.log(task.name+' = '+task._calculatedTpp+' ('+task.tpp+')');
// console.dir(dbg);
				productionDuration = t.addOffTimeTick(t.curTimeMs, productionDuration);
				productionDuration += t.curTimeMs-actualSetupFinishDate;
			}else
				productionDuration = task.times.productionDuration;
			// if(!task.done.finished)
				// productionDuration = t.addOffTimeTick(task.done.setupFinishDate ? task.done.setupFinishDate.getTime() : t.curTimeMs, productionDuration);
			productionWidth = t.getPx(productionDuration);
			
			if(task.done.setupFinishDate)
				de.doneActualProductionEl.css({'width':t.getPx((task.done.finishDate ? task.done.finishDate.getTime() : t.curTimeMs) - actualSetupFinishDate), 'display':'block'});
			else
				de.doneActualProductionEl.css('display', 'none');
			de.doneProductionEl.css({'width':productionWidth, 'left':totalSetupWidth});
			de.doneEl.css({'left':setupLeft,'width':(totalSetupWidth+productionWidth)});
			task.drawTime = t.curTimeMs;
			task.drawZoomLevel = t.timeIntervalIndex;
			task._finishTimePrediction = (task.done.setupFinishDate ? task.done.setupFinishDate.getTime() : t.curTimeMs)+productionDuration;
			
		}
	},
	setActiveRegion : function(region){
		this.activeRegion = region;
	},
	setChartHeight : function(h, ch){
		var t = this, d = t.domEls, ce = d.chartEls;
		var scrollerSize = 16, hRH = 23;
		t.waitMask.height(ch);
		var ch = h;
		d.chartCnt.height(ch);
		ce.stations.height(ch-(3*hRH)-1);
		ce.stationsCnt.height(ch-(3*hRH)-scrollerSize-1);
		t._chartBodyHeight = ch-(3*hRH)-1;
		ce.chartBody.height(t._chartBodyHeight);
		t.windows.detay.height(h);
		t.windows.detay._els.center.height(h-30);
		if(t.waitMaskActive)
			t.waitMask.height(t.renderTo.height());
	},
	setChartWidth : function(w, cw){
		var t = this, d = t.domEls, ce = d.chartEls, fcw = t.firstColumnWidth;
		var scrollerSize = 16, hRH = 23;
		t.waitMask.width(cw);
		d.quickMsgEls.cnt.width(cw);
		ce.infoPane.width(w-fcw-scrollerSize-3);
		d.chartCnt.width(w);
		ce.header.width(w-fcw-scrollerSize-1);
		t._chartBodyWidth = w-fcw-1;
		ce.chartBody.width(t._chartBodyWidth);
		t.windows.detay.width(w);
		t.windows.detay._els.center.width(w);
		t.windows.detay._els.south.width(w);
		if(t.waitMaskActive)
			t.waitMask.width(t.renderTo.width());
	},
	setFirstDate : function(val){
		var t = this, d = new Date(val);
		d.setHours(0);
		d.setMinutes(0);
		d.setSeconds(0);
		d.setMilliseconds(0);
		t._firstDateSetted = true;
		t.firstDate = d;
	},
	setLastDate : function(val){
		var t = this, d = new Date(val);
		d.setHours(0);
		d.setMinutes(0);
		d.setSeconds(0);
		d.setMilliseconds(0);
		d.setDate(d.getDate()+1);
		t._lastDateSetted = true;
		t.lastDate = d;
	},
	setStartFinishDate : function(task,time){
		var t=this;
		task.startDate.setTime(time);
		task.finishDate.setTime(task.times.startDate + task.times.actualDuration);  
	},
	setTimeLineWidth : function(width){
		var t = this, d = t.domEls, ce = d.chartEls, ceh = ce.headers;
		ceh.line1.width(width);
		ceh.line2.width(width);
		ceh.line3.width(width);
		ce.chartBodyScroll.width(width);
		for(var i in t.station)
			if(typeof t.station[i] != 'function')
				t.station[i].chartEl.width(width);
	},
	setTaskLabelLeft : function(task, left){
		var t = this;
		if(task._titleAbsolute && task.titleEl)
			task.titleCnt.css('left', left);
	},
	setTaskLeftWidth : function(task){
		var t=this, tt = task.times, ts = task.sizes;
		var left = t.getPxFromTime(tt.startDate);
		if(task.el)
			task.el.css({"left":left + "px","width": (ts.elWidth)+'px'});
		t.setTaskLabelLeft(task, left);
		if(task.setupEl)
			$(task.setupEl).css('left',ts.lagWidth+'px').css('width',ts.setupElWidth+'px');
		if(ts.lagWidth>0)
			$(task.setupEl).css('border-left','1px solid #000');
		task.productionEl.css('left',(ts.lagWidth+ts.setupElWidth)+'px').css('width',ts.productionElWidth+'px');
	},
	showTaskQuickInfo : function(task, autoHide){
		var t = this, infoPane = t.domEls.chartEls.infoPane;
		if(window.activeTimer)
			clearTimeout(window.activeTimer);
		window.activeTimer = setTimeout(function(){
			if(window.activeTimer){
				if(task.done && !task.done.finishDate && task.done.startDate)
					var estimatedFinishDate = new Date(task._finishTimePrediction);
				else
					var estimatedFinishDate = false;
				var fd = new Date(task.times.finishDate);
				var pd = task.productionDetails, pdl = pd.length, pdHtml = '&nbsp;';
				if(pdl==0){
					pdHtml = '<span class="mj-gantt-task-production" style="margin-left:5px;">0</span><span class="mj-gantt-task-production-planned">/'+task.production+'</span>';
				}else if(pdl==1){
					pdHtml = '<span class="mj-gantt-task-production" style="margin-left:5px;">'+(pd[0].production?pd[0].production:'0')+'</span>'+(pd[0].scrap?('<span class="mj-gantt-task-scrap">-'+pd[0].scrap+'</span>'):'')+'<span class="mj-gantt-task-production-planned">/'+task.production+'</span>';
				}else{					
					pdHtml = '<table cellspacing="1" cellpadding="0" valign="top" style="margin-left:5px;">';
					for(var i=0,l=pd.length;i<l;i++){
						pdHtml += '<tr><td class="mj-gantt-task-code-title">'+pd[i].leafCode+'</td><td class="mj-gantt-task-production" align="right">&nbsp;'+(pd[i].production?pd[i].production:'0')+'</td>';
						pdHtml += '<td class="mj-gantt-task-scrap" align="right">&nbsp;'+(pd[i].scrap?('-'+pd[i].scrap):'')+'</td>';
						if(i==0)
							pdHtml += '<td rowspan="'+pdl+'" class="mj-gantt-task-production-planned">&nbsp;/&nbsp;'+task.production+'</td>';
						pdHtml += '</tr>';
					}
					pdHtml += '</table>';
				}
				var _html = [
				'<table cellpadding="0" cellspacing="0">',
					'<tr><td colspan="6"><span class="mj-gantt-task-no">'+task.id+':&nbsp;</span><span class="mj-gantt-task-name">'+task.name+'</span></td></tr>',
					'<tr class="mj-gantt-task-time">',
						'<td class="mj-gantt-task-time-title">Başlangıç</td>',
						'<td width="5px" align="center" class="mj-gantt-task-time-title">&nbsp;:&nbsp;</td>',
						'<td align="center">'+task.startDate.formatDate('d/m/Y H:i')+'</td>',
						'<td width="5px" align="center" class="mj-gantt-task-time-title">&nbsp;'+((task.done&&task.done.startDate)?'-':'')+'&nbsp;</td>',
						'<td class="mj-gantt-task-time-absolute" align="center">'+(task.done&&task.done.startDate?task.done.startDate.formatDate('d/m/Y H:i'):'&nbsp;')+'</td>',
						'<td rowspan="3" valign="middle" align="center" class="mj-gantt-task-table">'+pdHtml+'</td>',
					'</tr>',
					'<tr class="mj-gantt-task-time">',
						'<td class="mj-gantt-task-time-title">Bitiş</td>',
						'<td width="5px" align="center" class="mj-gantt-task-time-title">&nbsp;:&nbsp;</td>',
						'<td align="center">'+fd.formatDate('d/m/Y H:i')+'</td>',
						'<td width="5px" align="center" class="mj-gantt-task-time-title">&nbsp;'+((task.done && task.done.finishDate)||estimatedFinishDate?'-':'')+'&nbsp;</td>',
						'<td class="mj-gantt-task-time-'+(task.done && task.done.finishDate ? 'absolute' : 'estimated')+'" align="center">'+(task.done && task.done.finishDate?task.done.finishDate.formatDate('d/m/Y H:i'):(estimatedFinishDate?estimatedFinishDate.formatDate('d/m/Y H:i'):'&nbsp;'))+'</td>',
					'</tr>',
					'<tr class="mj-gantt-task-time">',
						'<td colspan="2">&nbsp;</td>',
						'<td class="mj-gantt-task-time-total" align="center">'+mj.timeShow(task.times.finishDate-task.startDate.getTime(), true)+'</td>',
						'<td width="5px" align="center" class="mj-gantt-task-time-title">&nbsp;'+(((task.done&&task.done.finishDate)||estimatedFinishDate) ? '-' : '')+'&nbsp;</td>',
						'<td align="center" class="mj-gantt-task-time-total-'+(task.done&&task.done.finishDate ? 'absolute' : 'estimated')+'">&nbsp;'+(((task.done&&task.done.finishDate)||estimatedFinishDate) ? mj.timeShow((task.done && task.done.finishDate ? task.done.finishDate.getTime() : task._finishTimePrediction)-task.done.startDate.getTime(), true) : '&nbsp;')+'</td>',
					'</tr>',
				'</table>'];
				infoPane.empty();
				mj.NE(infoPane,{html:_html.join('')});
				infoPane.fadeIn(250);
				clearTimeout(window.activeTimer);
			}
		},350);
		if(autoHide)
			setTimeout(function(){
				if(window.activeTimer)
					clearTimeout(window.activeTimer);
				infoPane.fadeOut(400);
			},3000);
	},
	
	waitMaskShow : function(){
		this.waitMaskActive=true;
		this.waitMask[0].style.display='block';
	},
	waitMaskHide : function(){
		this.waitMaskActive=false;
		this.waitMask[0].style.display='none';
	},
	zoom : function(x){
		var t=this;
		t.waitMaskShow();
		setTimeout(function(){
			var cb = t.domEls.chartEls.chartBody;
			var time = t.getTimeFromPx(cb[0].scrollLeft + (t._chartBodyWidth/2));
			t.timeIntervalIndex = x ? (t.timeIntervalIndex + x) : 5;
			t.time = t.timeRangeMap[t.timeIntervalIndex];
			t.timeInterval = t.timeRange[t.timeIntervalIndex];
			t.clearChartComponents();
			t.fillChartTimeline();
			t.drawOffTime();
			t.initSnapShotData();
			for(var i=0,len=t.tasks.length;i<len;i++){
				var task = t.tasks[i];
				t.locateTask(task);
			}

			t.gotoTime(time);
			t.waitMaskHide();
		},10);
	},
	zoomIn : function(){
		if(!this.time.min)
			this.zoom(-1);
	},
	zoomOut : function(){
		if(!this.time.max)
			this.zoom(1);
	},
	zoomReset : function(){
		this.zoom();
	},
	init : function(){
		var t = this;
		t.colorGenerator = new mj.randomColors();
		t.id = t.id || mj.genId(t.prefix || 'mj-gantt-');
		t.offTime = t.offTime || [];
		t.station = t.station || {};
		t.firstDate = t.firstDate || new Date();
		t.buttons = {};
		t.domEls = {};
		t.history = [];
		t.render();
	}
};
mj.extend(mj.snapShot, mj.component);
/********************************************************************
 * openWYSIWYG v1.46c Copyright (c) 2006 openWebWare.com 
 * Contact us at devs@openwebware.com
 * This copyright notice MUST stay intact for use.
 *
 * $Id: wysiwyg.js,v 1.10 2006/12/25 09:17:07 xhaggi Exp $
 *
 * An open source WYSIWYG editor for use in web based applications.
 * For full source code and docs, visit http://www.openwebware.com
 *
 * This library is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU Lesser General Public License as published 
 * by the Free Software Foundation; either version 2.1 of the License, or 
 * (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License along 
 * with this library; if not, write to the Free Software Foundation, Inc., 59 
 * Temple Place, Suite 330, Boston, MA 02111-1307 USA  
 ********************************************************************/
var WYSIWYG = {

	/**
	 * Settings class, holds all customizeable properties
	 */
	Settings: function() {
	
		// Images Directory
		this.ImagesDir = "images/";
		
		// Popups Directory
		this.PopupsDir = "popups/";
		
		// CSS Directory File
		//::this.CSSFile = "styles/wysiwyg.css";		
		
		// Default WYSIWYG width and height (use px or %)
		this.Width = "500px";
		this.Height = "200px";
		
		// Default stylesheet of the WYSIWYG editor window
		this.DefaultStyle = "font-family: Arial; font-size: 12px; background-color: #FFFFFF";
		
		// Stylesheet if editor is disabled
		this.DisabledStyle = "font-family: Arial; font-size: 12px; background-color: #EEEEEE";
				
		// Width + Height of the preview window
		this.PreviewWidth = 500;
		this.PreviewHeight = 400;
		
		// Confirmation message if you strip any HTML added by word
		this.RemoveFormatConfMessage = "Clean HTML inserted by MS Word ?";
		
		// Nofication if browser is not supported by openWYSIWYG, leave it blank for no message output.
		this.NoValidBrowserMessage = "openWYSIWYG does not support your browser.";
				
		// Anchor path to strip, leave it blank to ignore
		// or define auto to strip the path where the editor is placed 
		// (only IE)
		this.AnchorPathToStrip = "auto";
		
		// Image path to strip, leave it blank to ignore
		// or define auto to strip the path where the editor is placed 
		// (only IE)
		this.ImagePathToStrip = "auto";
		
		// Enable / Disable the custom context menu
		this.ContextMenu = true;
		
		// Enabled the status bar update. Within the status bar 
		// node tree of the actually selected element will build
		this.StatusBarEnabled = true;
		
		// If enabled than the capability of the IE inserting line breaks will be inverted.
		// Normal: ENTER = <p> , SHIFT + ENTER = <br>
		// Inverted: ENTER = <br>, SHIFT + ENTER = <p>
		this.InvertIELineBreaks = false;
		
		// Replace line breaks with <br> tags
		this.ReplaceLineBreaks = false;
		
		// Insert image implementation
		this.ImagePopupFile = "";
		this.ImagePopupWidth = 0;
		this.ImagePopupHeight = 0;
		
		// Holds the available buttons displayed 
		// on the toolbar of the editor
		this.Toolbar = new Array();
		this.Toolbar[0] = new Array(
			"font", 
			"fontsize",	
			"bold", 
			"italic", 
			"underline", 
			"strikethrough",
			"seperator", 
			"forecolor", 
			"backcolor", 
			"seperator", 
			"justifyleft", 
			"justifycenter", 
			"justifyright", 
			"seperator", 
			"unorderedlist", 
			"orderedlist",
			"outdent", 
			"indent"
		);
		this.Toolbar[1] = new Array(
			"subscript", 
			"superscript", 
			"seperator", 
			"cut", 
			"copy", 
			"paste",
			"removeformat",
			"seperator", 
			"undo", 
			"redo", 
			"seperator", 
			"inserttable", 
			"insertimage", 
			"createlink",
			"createlinkhelpdesigner",
			"seperator",  
			"preview", 
			"print",
			"seperator", 
			"viewSource", 
			"seperator"
			//, "help"
		);
			
		// List of available font types
	    this.Fonts = new Array(
			"Arial", 
			"Sans Serif", 
			"Tahoma", 
			"Verdana", 
			"Courier New", 
			"Georgia", 
			"Times New Roman", 
			"Impact", 
			"Comic Sans MS"
		);
		
		// List of available font sizes 
	    this.Fontsizes = new Array(
			"1", 
			"2", 
			"3", 
			"4", 
			"5", 
			"6", 
			"7"
		);
				
		// Add the given element to the defined toolbar
		// on the defined position
		this.addToolbarElement = function(element, toolbar, position) {
			if(element != "seperator") {this.removeToolbarElement(element);}
			if(this.Toolbar[toolbar-1] == null) {
				this.Toolbar[toolbar-1] = new Array();
			}
			this.Toolbar[toolbar-1].splice(position+1, 1, element);			
		};
		
		// Remove an element from the toolbar
		this.removeToolbarElement = function(element) {
			if(element == "seperator") {return;} // do not remove seperators
			for(var i=0;i<this.Toolbar.length;i++) {
				if(this.Toolbar[i]) {
					var toolbar = this.Toolbar[i];
					for(var j=0;j<toolbar.length;j++) {
						if(toolbar[j] != null && toolbar[j] == element) {
							this.Toolbar[i].splice(j,1);
						}
					}
				}
			}
		};
		
		// clear all or a given toolbar
		this.clearToolbar = function(toolbar) {
			if(typeof toolbar == "undefined") {
				this.Toolbar = new Array();
			}
			else {
				this.Toolbar[toolbar+1] = new Array();
			}
		};
		
	},
	
		
	/* ---------------------------------------------------------------------- *\
		!! Do not change something below or you know what you are doning !!
	\* ---------------------------------------------------------------------- */	

	// List of available block formats (not in use)
	//BlockFormats: new Array("Address", "Bulleted List", "Definition", "Definition Term", "Directory List", "Formatted", "Heading 1", "Heading 2", "Heading 3", "Heading 4", "Heading 5", "Heading 6", "Menu List", "Normal", "Numbered List"),

	// List of available actions and their respective ID and images
	ToolbarList: {
	//Name              buttonID               buttonTitle           	buttonImage               buttonImageRollover
	"bold":           ['Bold',                 'Bold',               	'bold.gif',               'bold_on.gif', '0 0', '-20px 0'],
	"italic":         ['Italic',               'Italic',             	'italics.gif',            'italics_on.gif', '-40px 0', '-60px 0'],
	"underline":      ['Underline',            'Underline',          	'underline.gif',          'underline_on.gif', '-80px 0', '-100px 0'],
	"strikethrough":  ['Strikethrough',        'Strikethrough',      	'strikethrough.gif',      'strikethrough_on.gif', '-120px 0', '-140px 0'],
	"seperator":      ['',                     '',                   	'seperator.gif',          'seperator.gif', '-160px 0', '-180px 0'],
	"subscript":      ['Subscript',            'Subscript',          	'subscript.gif',          'subscript_on.gif', '-200px 0', '-220px 0'],
	"superscript":    ['Superscript',          'Superscript',        	'superscript.gif',        'superscript_on.gif', '-240px 0', '-260px 0'],
	"justifyleft":    ['Justifyleft',          'Justifyleft',        	'justify_left.gif',       'justify_left_on.gif', '-280px 0', '-300px 0'],
	"justifycenter":  ['Justifycenter',        'Justifycenter',      	'justify_center.gif',     'justify_center_on.gif', '-320px 0', '-340px 0'],
	"justifyright":   ['Justifyright',         'Justifyright',       	'justify_right.gif',      'justify_right_on.gif', '-360px 0', '-380px 0'],
	"unorderedlist":  ['InsertUnorderedList',  'Insert Unordered List',	'list_unordered.gif',     'list_unordered_on.gif', '-400px 0', '-420px 0'],
	"orderedlist":    ['InsertOrderedList',    'Insert Ordered List',  	'list_ordered.gif',       'list_ordered_on.gif', '-440px 0', '-460px 0'],
	"outdent":        ['Outdent',              'Outdent',            	'indent_left.gif',        'indent_left_on.gif', '-480px 0', '-500px 0'],
	"indent":         ['Indent',               'Indent',             	'indent_right.gif',       'indent_right_on.gif', '-520px 0', '-540px 0'],
	"cut":            ['Cut',                  'Cut',                	'cut.gif',                'cut_on.gif', '-560px 0', '-580px 0'],
	"copy":           ['Copy',                 'Copy',               	'copy.gif',               'copy_on.gif', '-600px 0', '-620px 0'],
	"paste":          ['Paste',                'Paste',              	'paste.gif',              'paste_on.gif', '-640px 0', '-660px 0'],
	"forecolor":      ['ForeColor',            'Fore Color',          	'forecolor.gif',          'forecolor_on.gif', '-680px 0', '-700px 0'],
	"backcolor":      ['BackColor',            'Back Color',          	'backcolor.gif',          'backcolor_on.gif', '-720px 0', '-740px 0'],
	"undo":           ['Undo',                 'Undo',               	'undo.gif',               'undo_on.gif', '-760px 0', '-780px 0'],
	"redo":           ['Redo',                 'Redo',               	'redo.gif',               'redo_on.gif', '-800px 0', '-820px 0'],
	"inserttable":    ['InsertTable',          'Insert Table',        	'insert_table.gif',       'insert_table_on.gif', '-840px 0', '-860px 0'],
	"insertimage":    ['InsertImage',          'Insert Image',        	'insert_picture.gif',     'insert_picture_on.gif', '-880px 0', '-900px 0'],
	"createlink":     ['CreateLink',           'Create Link',         	'insert_hyperlink.gif',   'insert_hyperlink_on.gif', '-920px 0', '-940px 0'],
	"createlinkhelpdesigner":     ['CreateLinkHelpDesigner',           'Create Link Help Designer',         	'insert_hyperlink.gif',   'insert_hyperlink_on.gif', '-920px 0', '-940px 0'],
	"viewSource":     ['ViewSource',           'View Source',         	'view_source.gif',        'view_source_on.gif', '-960px 0', '-980px 0'],
	"viewText":       ['ViewText',             'View Text',           	'view_text.gif',          'view_text_on.gif', '-1000px 0', '-1020px 0'],
	//"help":           ['Help',                 'Help',               	'help.gif',               'help_on.gif', '0 0', '-20px 0'],
	"selectfont":     ['SelectFont',           'Select Font',        	'select_font.gif',        'select_font_on.gif', '-1040px 0', '-1125px 0'],
	"selectsize":     ['SelectSize',           'Select Size',        	'select_size.gif',        'select_size_on.gif', '-1210px 0', '-1260px 0'],
	"preview":		  ['Preview', 			   'Preview',       	 	'preview.gif',			   'preview_on.gif', '-1430px 0', '-1450px 0'],
	"print":		  ['Print', 			   'Print',       	 	 	'print.gif',			   'print_on.gif', '-1310px 0', '-1330px 0'],
	"removeformat":   ['RemoveFormat',         'Strip Word HTML',    	'remove_format.gif',      'remove_format_on.gif', '-1350px 0', '-1370px 0'],
	"delete":         ['Delete',               'Delete',             	'delete.gif',     		   'delete_on.gif', '-1390px 0','-1410px 0']
	},
	
	// stores the different settings for each textarea
	// the textarea identifier is used to store the settings object
	config: new Array(),
	// Create viewTextMode global variable and set to 0
	// enabling all toolbar commands while in HTML mode
	viewTextMode: new Array(),	
	
	/**
	 * Get the range of the given selection
	 *
	 * @param {Selection} sel Selection object
	 * @return {Range} Range object
	 */
	getRange: function(sel) {
		return sel.createRange ? sel.createRange() : sel.getRangeAt(0);
	},
	
	/**
	 * Get the iframe object of the WYSIWYG editor
	 * 
	 * @param {String} n Editor identifier 
	 * @return {HtmlIframeObject} Iframe object
	 */
	getEditor: function(n) {
		return $g("wysiwyg" + n);
	},
	
	/**
	 * Get editors window element
	 *
	 * @param {String} n Editor identifier 
	 * @return {Object} Html window object
	 */
	getEditorWindow: function(n) {
		return this.getEditor(n).contentWindow;
	},
	
	/**
	 * Attach the WYSIWYG editor to the given textarea element
	 *
	 * @param {String} id Textarea identifier (all = all textareas)
	 * @param {Settings} settings the settings which will be applied to the textarea
	 */
	attach: function(id, settings) {	
		if(id != "all") {	
			this.setSettings(id, settings);
			//::WYSIWYG_Core.includeCSS(this.config[id].CSSFile);
			WYSIWYG_Core.addEvent(window, "load", function generateEditor() {WYSIWYG._generate(id, settings);});
		}
		else {
			WYSIWYG_Core.addEvent(window, "load", function generateEditor() {WYSIWYG.attachAll(settings);});
		}
	},
	
	/**
	 * Attach the WYSIWYG editor to all textarea elements
	 *
	 * @param {Settings} settings Settings to customize the look and feel
	 */
	attachAll: function(settings) {
		var areas = document.getElementsByTagName("textarea");
		for(var i=0;i<areas.length;i++) {
			var id = areas[i].getAttribute("id");
			if(id == null || id == "") continue;
			this.setSettings(id, settings);
			//::WYSIWYG_Core.includeCSS(this.config[id].CSSFile);
			
			WYSIWYG._generate(id, settings);
		}
	},
	
	/**
	 * Display an iframe instead of the textarea. 
	 * It's used as textarea replacement to display HTML.
	 *
	 * @param id Textarea identifier (all = all textareas)
	 * @param settings the settings which will be applied to the textarea
	 */
	display: function(id, settings) {	
		if(id != "all") {	
			this.setSettings(id, settings);
			//::WYSIWYG_Core.includeCSS(this.config[id].CSSFile);
			WYSIWYG_Core.addEvent(window, "load", function displayIframe() {WYSIWYG._display(id, settings);});
		}
		else {
			WYSIWYG_Core.addEvent(window, "load", function displayIframe() {WYSIWYG.displayAll(settings);});
		}
	},
	
	/**
	 * Display an iframe instead of the textarea. 
	 * It's apply the iframe to all textareas found in the current document.
	 *
	 * @param settings Settings to customize the look and feel
	 */
	displayAll: function(settings) {
		var areas = document.getElementsByTagName("textarea");
		for(var i=0;i<areas.length;i++) {
			var id = areas[i].getAttribute("id");
			if(id == null || id == "") continue;
			this.setSettings(id, settings);
			//::WYSIWYG_Core.includeCSS(this.config[id].CSSFile);
			WYSIWYG._display(id, settings);
		}
	},
		
	/**
	 * Set settings in config array, use the textarea id as identifier
	 * 
	 * @param n Textarea identifier (all = all textareas)
	 * @param settings the settings which will be applied to the textarea
	 */
	setSettings: function(n, settings) {
		if(typeof(settings) != "object") {
			this.config[n] = new this.Settings();
		}
		else {
			this.config[n] = settings;
		}
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : insertImage()
	  Description : insert an image into WYSIWYG in rich text
	  Usage       : WYSIWYG.insertImage("test.jpg", 500, 200, "center", 0, "Picture Alternativ", 5, 5, "textareaID")
	  Arguments   : src - Source of the image
	  				width - Width
					height - Height
					align - Alignment of the image
					border - border 
					alt - Alternativ Text
					hspace - Horizontal Space
					vspace - Vertical Space
	                n  - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	insertImage: function(src, width, height, align, border, alt, hspace, vspace, n) {
	
		// get editor
		var doc = this.doc;//this.getEditorWindow(n).document;
		// get selection and range
		var sel = this.getSelection(n);
		var range = this.getRange(sel);
		
		// the current tag of range
		var img = this.findParentTag("img", range);
		
		// element is not a link
		var update = (img == null) ? false : true;
		if(!update) {
			img = doc.createElement("img");
		}
		
		// set the attributes
		WYSIWYG_Core.setAttribute(img, "src", mj.glb.uploadPath+src);
		WYSIWYG_Core.setAttribute(img, "style", "width:" + width + ";height:" + height);
		if(align != "") { WYSIWYG_Core.setAttribute(img, "align", align); } else { img.removeAttribute("align"); }
		WYSIWYG_Core.setAttribute(img, "border", border);
		WYSIWYG_Core.setAttribute(img, "alt", alt);
		WYSIWYG_Core.setAttribute(img, "hspace", hspace);
		WYSIWYG_Core.setAttribute(img, "vspace", vspace);
		WYSIWYG_Core.setAttribute(img, "rel", src);
		WYSIWYG_Core.setAttribute(img, "class", "mj-wysiwyg-image");
		img.removeAttribute("width");
		img.removeAttribute("height");
		
		// on update exit here
		if(update) { return; }   
		
		// Check if IE or Mozilla (other)
		if (WYSIWYG_Core.isMSIE) {
			range.pasteHTML(img.outerHTML);   
		}
		else {
			this.insertNodeAtSelection(img, n);
		}
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : insertLink()
	  Description : insert a link into WYSIWYG in rich text
	  Usage       : WYSIWYG.insertLink("http://www.google.de", "_blank", "", "", "", "textareaID")
	  Arguments   : href - The link url
	  				target - Target of the link
					style - Stylesheet of the link
					styleClass - Stylesheet class of the link
					name - Name attribute of the link
	                n  - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	insertLink: function(href, target, style, styleClass, name, n) {
	
		// get editor
		var doc = this.getEditorWindow(n).document;
		// get selection and range
		var sel = this.getSelection(n);
		var range = this.getRange(sel);
		var lin = null;
		
		// get element from selection
		if(WYSIWYG_Core.isMSIE) {
			if(sel.type == "Control" && range.length == 1) {	
				range = this.getTextRange(range(0));
				range.select();
			}
		}

		// find a as parent element
		lin = this.findParentTag("a", range);
				
		// check if parent is found
		var update = (lin == null) ? false : true;
		if(!update) {
			lin = doc.createElement("a");
		}
		
		// set the attributes
		WYSIWYG_Core.setAttribute(lin, "href", href);
		WYSIWYG_Core.setAttribute(lin, "class", styleClass);
		WYSIWYG_Core.setAttribute(lin, "className", styleClass);
		WYSIWYG_Core.setAttribute(lin, "target", target);
		WYSIWYG_Core.setAttribute(lin, "name", name);
		WYSIWYG_Core.setAttribute(lin, "style", style);
		
		// on update exit here
		if(update) { return; }
	
		// Check if IE or Mozilla (other)
		if (WYSIWYG_Core.isMSIE) {	
			range.select();
			lin.innerHTML = range.htmlText;
			range.pasteHTML(lin.outerHTML);   
		} 
		else {			
			var node = range.startContainer;	
			var pos = range.startOffset;
			if(node.nodeType != 3) { node = node.childNodes[pos]; }
			if(node.tagName)
				lin.appendChild(node);
			else
				lin.innerHTML = sel;
			this.insertNodeAtSelection(lin, n);
		}
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : removeFormat()
	  Description : Strip any HTML added by word
	  Usage       : removeFormat(n)
	  Arguments   : n  - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	removeFormat: function(n) {
		
		if ( !confirm(this.config[n].RemoveFormatConfMessage) ) { return; }
		var doc = this.getEditorWindow(n).document;
		var str = doc.body.innerHTML;
		
		str = str.replace(/<span([^>])*>(&nbsp;)*\s*<\/span>/gi, '');
	    str = str.replace(/<span[^>]*>/gi, '');
	    str = str.replace(/<\/span[^>]*>/gi, '');
	    str = str.replace(/<p([^>])*>(&nbsp;)*\s*<\/p>/gi, '');
	    str = str.replace(/<p[^>]*>/gi, '');
	    str = str.replace(/<\/p[^>]*>/gi, '');
	    str = str.replace(/<h([^>])[0-9]>(&nbsp;)*\s*<\/h>/gi, '');
	    str = str.replace(/<h[^>][0-9]>/gi, '');
	    str = str.replace(/<\/h[^>][0-9]>/gi, ''); 
		str = str.replace (/<B [^>]*>/ig, '<b>');
		
		// var repl_i1 = /<I[^>]*>/ig;
		// str = str.replace (repl_i1, '<i>');
		
		str = str.replace (/<DIV[^>]*>/ig, '');
		str = str.replace (/<\/DIV>/gi, '');
		str = str.replace (/<[\/\w?]+:[^>]*>/ig, '');
		str = str.replace (/(&nbsp;){2,}/ig, '&nbsp;');
		str = str.replace (/<STRONG>/ig, '');
		str = str.replace (/<\/STRONG>/ig, '');
		str = str.replace (/<TT>/ig, '');
		str = str.replace (/<\/TT>/ig, '');
		str = str.replace (/<FONT [^>]*>/ig, '');
		str = str.replace (/<\/FONT>/ig, '');
		str = str.replace (/STYLE=\"[^\"]*\"/ig, '');
		str = str.replace(/<([\w]+) class=([^ |>]*)([^>]*)/gi, '<$1$3');
  	    str = str.replace(/<([\w]+) style="([^"]*)"([^>]*)/gi, '<$1$3'); 
		str = str.replace(/width=([^ |>]*)([^>]*)/gi, '');
	    str = str.replace(/classname=([^ |>]*)([^>]*)/gi, '');
	    str = str.replace(/align=([^ |>]*)([^>]*)/gi, '');
	    str = str.replace(/valign=([^ |>]*)([^>]*)/gi, '');
	    str = str.replace(/<\\?\??xml[^>]>/gi, '');
	    str = str.replace(/<\/?\w+:[^>]*>/gi, '');
	    str = str.replace(/<st1:.*?>/gi, '');
	    str = str.replace(/o:/gi, ''); 
	    
	    str = str.replace(/<!--([^>])*>(&nbsp;)*\s*<\/-->/gi, '');
   		str = str.replace(/<!--[^>]*>/gi, '');
   		str = str.replace(/<\/--[^>]*>/gi, '');
		
		doc.body.innerHTML = str;
	},
	
	/**
	 * Display an iframe instead of the textarea.
	 * 
	 * @param n - ID of textarea to replace
	 * @param settings - object which holds the settings
	 */
	_display: function(n, settings) {
			
		// Get the textarea element
		var textarea = $g(n);
		
		// Validate if textarea exists
		if(textarea == null) {
			alert("No textarea found with the given identifier (ID: " + n + ").");
			return;
		}
		
		// Validate browser compatiblity
		if(!WYSIWYG_Core.isBrowserCompatible()) {
			if(this.config[n].NoValidBrowserMessage != "") { alert(this.config[n].NoValidBrowserMessage); }
			return;
		}
		
	    // Load settings in config array, use the textarea id as identifier
		if(typeof(settings) != "object") {
			this.config[n] = new this.Settings();
		}
		else {
			this.config[n] = settings;
		}
		
		// Hide the textarea 
		textarea.style.display = "none";
		
		// Override the width and height of the editor with the 
		// size given by the style attributes width and height
		if(textarea.style.width) {
			this.config[n].Width = textarea.style.width;
		}
		if(textarea.style.height) {
			this.config[n].Height = textarea.style.height;
		} 
			
	    // determine the width + height
		var currentWidth = this.config[n].Width;
		var currentHeight = this.config[n].Height;
	 
		// Calculate the width + height of the editor 
		var ifrmWidth = "100%";
		var	ifrmHeight = "100%";
		if(currentWidth.search(/%/) == -1) {
			ifrmWidth = currentWidth;
			ifrmHeight = currentHeight;
		}
				
		// Create iframe which will be used for rich text editing
		var iframe = '<table cellpadding="0" cellspacing="0" border="0" style="width:' + currentWidth + '; height:' + currentHeight + ';" class="tableTextareaEditor"><tr><td valign="top">\n' + '<iframe  frameborder="0" id="wysiwyg' + n + '" class="iframeText" style="width:' + ifrmWidth + ';height:' + ifrmHeight + ';"></iframe>\n'	 + '</td></tr></table>\n';

	    // Insert after the textArea both toolbar one and two
		textarea.insertAdjacentHTML("afterEnd", iframe);
						
		// Pass the textarea's existing text over to the content variable
	    var content = textarea.value;
		var doc = this.getEditorWindow(n).document;
		
		// Replace all \n with <br> 
		if(this.config[n].ReplaceLineBreaks) {
			content = content.replace(/(\r\n)|(\n)/ig, "<br>");
		}
			
		// Write the textarea's content into the iframe
	    doc.open();
	    doc.write(content);
	    doc.close();
	    
	    // Set default style of the editor window
		WYSIWYG_Core.setAttribute(doc.body, "style", this.config[n].DefaultStyle);
	},
	
	/**
	 * Replace the given textarea with wysiwyg editor
	 * 
	 * @param n - ID of textarea to replace
	 * @param settings - object which holds the settings
	 */
	_generate: function(n, settings) {
		this.stores = {};
		this.wins = [];

		 // Get the textarea element
		var textarea = $g(n);
		// Validate if textarea exists
		if(textarea == null) {
			alert("No textarea found with the given identifier (ID: " + n + ").");
			return;
		}	    
		
		// Validate browser compatiblity
		if(!WYSIWYG_Core.isBrowserCompatible()) {
			if(this.config[n].NoValidBrowserMessage != "") { alert(this.config[n].NoValidBrowserMessage); }
			return;
		}
								
		// Hide the textarea 
		textarea.style.display = 'none'; 
		
		// Override the width and height of the editor with the 
		// size given by the style attributes width and height
		if(textarea.style.width) {
			this.config[n].Width = textarea.style.width;
		}
		if(textarea.style.height) {
			this.config[n].Height = textarea.style.height;
		}
			
	    // determine the width + height
		var currentWidth = this.config[n].Width;
		var currentHeight = this.config[n].Height;
	 
		// Calculate the width + height of the editor 
		var toolbarWidth = currentWidth;
		var ifrmWidth = "100%";
		var	ifrmHeight = "100%";
		if(currentWidth.search(/%/) == -1) {
			toolbarWidth = currentWidth.replace(/px/gi, "");
			toolbarWidth = (parseFloat(toolbarWidth) -2) + "px";
			ifrmWidth = currentWidth;
			ifrmHeight = currentHeight;
		}
		
				
	    // Generate the WYSIWYG Table
	    // This table holds the toolbars and the iframe as the editor
	    var editor = "";
		currentWidth = '100%';
	    editor += '<table border="0" cellpadding="0" cellspacing="0" class="tableTextareaEditor" id="wysiwyg_table_' + n + '" style="width:' + currentWidth  + '; height:' + currentHeight + ';">';
	    editor += '<tr><td style="height:25px;">';
	    	  
		// Output all command buttons that belong to toolbar one
		for (var j = 0; j < this.config[n].Toolbar.length;j++) { 
			if(this.config[n].Toolbar[j] && this.config[n].Toolbar[j].length > 0) {
				var toolbar = this.config[n].Toolbar[j];
				
				// Generate WYSIWYG toolbar one
				toolbarWidth = '100%';
			    editor += '<table border="0" cellpadding="0" cellspacing="0" class="toolbar1" style="width:'+toolbarWidth+';" id="toolbar' + j + '_' + n + '">';
	    		editor += '<tr><td style="width: 6px;"><div class="seperator2"></div></td>';
				
				for (var i = 0; i < toolbar.length;i++) { 
				    if (toolbar[i]) {
				    	// Font selection
						if (toolbar[i] == "font"){
							editor += '<td style="width: 90px;"><span id="FontSelect' + n + '"></span></td>';
						}
						// Font size selection
						else if (toolbar[i] == "fontsize"){
							editor += '<td style="width: 60px;"><span id="FontSizes'  + n + '"></span></td>';
						}
						// Button print out
						else {
							// Get the values of the Button from the global ToolbarList object
							var buttonObj = this.ToolbarList[toolbar[i]];
							var buttonID = buttonObj[0];
							var buttonTitle = buttonObj[1];
							var divButton = false;
							if(buttonObj[4]){
								divButton = '<div alt="' + buttonTitle + '" id="' + buttonID + '" class="divbuttonEditor" style="background-position:'+buttonObj[4]+'" onmouseover="this.className=\'divbuttonEditorOver\'; this.style.backgroundPosition=\'' + buttonObj[5] + '\';" onmouseout="this.className=\'divbuttonEditor\'; this.style.backgroundPosition=\'' + buttonObj[4] + '\';" onclick="WYSIWYG.formatText(\'' + buttonID + '\',\'' + n + '\');" unselectable="on" width="20" height="20">'+mj.insertSpacer(20,20)+'</div>';
							}else{
								var buttonImage = this.config[n].ImagesDir + buttonObj[2];
								var buttonImageRollover  = this.config[n].ImagesDir + buttonObj[3];
							}
							if (toolbar[i] == "seperator") {
								editor += '<td style="width: 12px;" align="center">';
								//editor += '<img src="' + buttonImage + '" border=0 unselectable="on" width="2" height="18" hspace="2" unselectable="on">';
								editor += '<div class="seperator"></div>';
								editor += '</td>';
							}
							// View Source button
							else if (toolbar[i] == "viewSource"){
							    editor += '<td style="width: 22px;">';
							    editor += '<span id="HTMLMode' + n + '"><div alt="' + buttonTitle + '" id="' + buttonID + '" class="divbuttonEditor" style="background-position:'+buttonObj[4]+'" onmouseover="this.className=\'divbuttonEditorOver\'; this.style.backgroundPosition=\'' + buttonObj[5] + '\';" onmouseout="this.className=\'divbuttonEditor\'; this.style.backgroundPosition=\'' + buttonObj[4] + '\';" onclick="WYSIWYG.formatText(\'' + buttonID + '\',\'' + n + '\');" unselectable="on" width="20" height="20">'+mj.insertSpacer(20,20)+'</div></span>';
								editor += '<span id="textMode' + n + '"><div alt="View Text" id="ViewText" class="divbuttonEditor" style="background-position:-1000px 0" onmouseover="this.className=\'divbuttonEditorOver\'; this.style.backgroundPosition=\'-1020px 0\';" onmouseout="this.className=\'divbuttonEditor\'; this.style.backgroundPosition=\'-1000px 0\';" onclick="WYSIWYG.formatText(\'ViewText\',\'' + n + '\');" unselectable="on" width="20" height="20">'+mj.insertSpacer(20,20)+'</div></span>';
						        editor += '</td>';
					        }
							else if(divButton){
								editor += '<td style="width: 22px;">';
								editor += divButton;
								editor += '</td>';
							}
							else {
								editor += '<td style="width: 22px;">';
								editor += '<img src="' + buttonImage + '" border=0 unselectable="on" title="' + buttonTitle + '" id="' + buttonID + '" class="buttonEditor" onmouseover="this.className=\'buttonEditorOver\'; this.src=\'' + buttonImageRollover + '\';" onmouseout="this.className=\'buttonEditor\'; this.src=\'' + buttonImage + '\';" onclick="WYSIWYG.formatText(\'' + buttonID + '\',\'' + n + '\');" unselectable="on" width="20" height="20">';
								editor += '</td>';
							}
						}
			  		}
			  	}
			  	editor += '<td>&nbsp;</td></tr></table>';
			}
		}
		
	 	editor += '</td></tr><tr><td valign="top">\n';
		// Create iframe which will be used for rich text editing
		var toolBarCount = 0;
		for(var i=0,l=settings.Toolbar.length;i<l;i++)
			if(settings.Toolbar[i].length>0)
				toolBarCount++;
		var fHeight = (parseInt(currentHeight)-(toolBarCount*27))+'px';
		editor += '<iframe  onmouseover="this.contentWindow.document.designMode=\'on\'" frameborder="0" id="wysiwyg' + n + '" class="iframeText" style="width:100%;height:' + fHeight + ';"></iframe>\n'  + '</td></tr>';
		//editor += '<iframe  frameborder="0" id="wysiwyg' + n + '" class="iframeText" style="width:100%;height:' + fHeight + ';"></iframe>\n'  + '</td></tr>';
	    // Status bar HTML code
	    if(this.config[n].StatusBarEnabled) {
		    editor += '<tr><td class="wysiwyg-statusbar" style="height:10px;" id="wysiwyg_statusbar_' + n + '">&nbsp;</td></tr>';    
		}
	    editor += '</table>\n';
	    
		var d = "<div id='"+(n+'_1')+"' class='mj-rich-text-area' style='height:"+this.config[n].Height+";width:"+this.config[n].Width+";'>"+editor+"</div>";
		textarea.insertAdjacentHTML("afterEnd", d);
		
	    // Insert the editor after the textarea	    
	    //::textarea.insertAdjacentHTML("afterEnd", editor);
	    		
	    // Insert the Font Type and Size drop downs into the toolbar
	    // Hide the dynamic drop down lists for the Font Types and Sizes
    	this.outputFontSelect(n);
	  	this.outputFontSizes(n);
	  	this.hideFonts(n);
		this.hideFontSizes(n);
			
		// Hide the "Text Mode" button
		// Validate if textMode Elements are prensent
		if($g("textMode" + n)) {
			$g("textMode" + n).style.display = 'none'; 
		}
		
		
		// Pass the textarea's existing text over to the content variable
	    var content = textarea.value;
		var doc = this.getEditorWindow(n).document;		
		this.doc = doc;

		// Replace all \n with <br> 
		if(this.config[n].ReplaceLineBreaks) {
			content = content.replace(/\n\r|\n/ig, "<br>");
		}
				
		// Write the textarea's content into the iframe
	    doc.open();
	    doc.write(content);
	    doc.close();
	    		
		// Make the iframe editable in both Mozilla and IE
		// Improve compatiblity for IE + Mozilla
		if (doc.body.contentEditable) {
			doc.body.contentEditable = true;
		}
		else {
//			doc.designMode = "on";	
		}
	
		// Set default font style
		WYSIWYG_Core.setAttribute(doc.body, "style", this.config[n].DefaultStyle);
	    
	    // Event Handling
	    // Update the textarea with content in WYSIWYG when user submits form
	    for (var idx=0; idx < document.forms.length; idx++) {
	    	WYSIWYG_Core.addEvent(document.forms[idx], "submit", function xxx_aa() { WYSIWYG.updateTextArea(n); });
	    }
	    
	    // close font selection if mouse moves over the editor window
	    WYSIWYG_Core.addEvent(doc, "mouseover", function xxx_bb() { WYSIWYG.hideFonts(n); WYSIWYG.hideFontSizes(n); });
	    
	    // If it's true invert the line break capability of IE
		if(this.config[n].InvertIELineBreaks) {
			WYSIWYG_Core.addEvent(doc, "keypress", function xxx_cc() { WYSIWYG.invertIELineBreakCapability(n); });
		}
					
		// status bar update
		if(this.config[n].StatusBarEnabled) {
			WYSIWYG_Core.addEvent(doc, "mouseup", function xxx_dd() { WYSIWYG.updateStatusBar(n); });
		}
	    	    
    	// custom context menu
		if(this.config[n].ContextMenu) {	
			WYSIWYG_ContextMenu.init(n);		
		}
								
		// init viewTextMode var
	    this.viewTextMode[n] = false;			
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : disable()
	  Description : Disable the given WYSIWYG Editor Box
	  Usage       : WYSIWYG.disable(textareaID)
	  Arguments   : textareaID - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	disable: function(textareaID) {
		// set n to textareaID
		var n = textareaID;
		
		// get the editor window
		var editor = this.getEditorWindow(n);
	
		// Validate if editor exists
		if(editor == null) {
			alert("No editor found with the given identifier (ID: " + n + ").");
			return;
		}
		
		if(editor) {
			// disable design mode or content editable feature
			if(editor.document.body.contentEditable) {
				editor.document.body.contentEditable = false;
			}
			else {
				editor.document.designMode = "Off";		
			}
				
			// change the style of the body
			WYSIWYG_Core.setAttribute(editor.document.body, "style", this.config[n].DisabledStyle);
			
			// hide the status bar
			this.hideStatusBar(n);
							
			// hide all toolbars
			this.hideToolbars(n);
		}
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : enable()
	  Description : Enables the given WYSIWYG Editor Box
	  Usage       : WYSIWYG.enable(textareaID)
	  Arguments   : textareaID - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	enable: function(textareaID) {
		// set n to textareaID
		var n = textareaID;
		
		// get the editor window
		var editor = this.getEditorWindow(n);
	
		// Validate if editor exists
		if(editor == null) {
			alert("No editor found with the given identifier (ID: " + n + ").");
			return;
		}
		
		if(editor) {
			// disable design mode or content editable feature
			if(editor.document.body.contentEditable){
				editor.document.body.contentEditable = true;
			}
			else {
				editor.document.designMode = "On";		
			}
				
			// change the style of the body
			WYSIWYG_Core.setAttribute(editor.document.body, "style", this.config[n].DefaultStyle);
			
			// hide the status bar
			this.showStatusBar(n);
							
			// hide all toolbars
			this.showToolbars(n);
		}
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : getNodeTree()
	  Description : Returns the node structure of the current selection as array
	  Usage       : WYSIWYG.getNodeTree(n);
	  Arguments   : n  - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	getNodeTree: function(n) {
		
		var sel = this.getSelection(n);
		var range = this.getRange(sel);	
			
		// get element of range
		var tag = this.getTag(range);
		if(tag == null) { return; }
		// get parent of element
		var node = this.getParent(tag);
		// init the tree as array with the current selected element
		var nodeTree = new Array(tag);
		// get all parent nodes
		var ii = 1;
		
		while(node != null && node.nodeName != "#document") {
			nodeTree[ii] = node;
			node = this.getParent(node);			
			ii++;
		}
		
		return nodeTree;
	},
	
	/**
	 * Removes the current node of the selection
	 *
	 * @param {String} n The editor identifier (the textarea's ID)
	 */
	removeNode: function(n) {
		// get selection and range
		var sel = this.getSelection(n);
		var range = this.getRange(sel);
		// the current tag of range
		var tag = this.getTag(range);
		var parent = tag.parentNode;
		if(tag == null || parent == null) { return; }
		if(tag.nodeName == "HTML" || tag.nodeName == "BODY") { return; }

		// copy child elements of the node to the parent element before remove the node
		//var childNodes = new Array();
		//for(var i=0; i < tag.childNodes.length;i++)
		//	childNodes[i] = tag.childNodes[i];	
		//for(var i=0; i < childNodes.length;i++)
		//	parent.insertBefore(childNodes[i], tag);	
		
		// remove node
		parent.removeChild(tag);
		// validate if parent is a link and the node is only 
		// surrounded by the link, then remove the link too
		if(parent.nodeName == "A" && !parent.hasChildNodes()) {
			if(parent.parentNode) { parent.parentNode.removeChild(parent); }
		}
		// update the status bar
		this.updateStatusBar(n);
	},
	
	/**
	 * Get the selection of the given editor
	 * 
	 * @param n The editor identifier (the textarea's ID)
	 */
	getSelection: function(n) {
		var ifrm = this.getEditorWindow(n);
		var doc = ifrm.document;
		var sel = null;
		if(ifrm.getSelection){
			sel = ifrm.getSelection();
		}
		else if (doc.getSelection) {
			sel = doc.getSelection();
		}
		else if (doc.selection) {
			sel = doc.selection;
		}
		return sel;
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : updateStatusBar()
	  Description : Updates the status bar with the current node tree
	  Usage       : WYSIWYG.updateStatusBar(n);
	  Arguments   : n  - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	updateStatusBar: function(n) {
		
		// get the node structure
		var nodeTree = this.getNodeTree(n);
		if(nodeTree == null) { return; }
		// format the output
		var outputTree = "";
		var max = nodeTree.length - 1;
		for(var i=max;i>=0;i--) {
			if(nodeTree[i].nodeName != "HTML" && nodeTree[i].nodeName != "BODY") {
				outputTree += '<a class="wysiwyg-statusbar" href="javascript:WYSIWYG.selectNode(\'' + n + '\',' + i + ');">' + nodeTree[i].nodeName + '</a>';	
			}
			else {
				outputTree += nodeTree[i].nodeName;
			}
			if(i > 0) { outputTree += " > "; }
		}
			
		// update the status bar 	
		var statusbar = $g("wysiwyg_statusbar_" + n);
		if(statusbar){ 
			statusbar.innerHTML = outputTree; 
		}
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : disableDesignMode()
	  Description : Disable the design mode if right mouse button is pressed.
	  				It's needed for custom context menus on mozilla (firefox),
	  				because if design mode is on then you can`t diabled the browser
	  				context menu.
	  Usage       : WYSIWYG.disableDesignMode(e, n);
	  Arguments   : event - browser event (like which button pressed)
	  				n  - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	disableDesignMode: function(event, n) {
		var doc = this.getEditorWindow(n).document;
		if(event.which == 3) {
			doc.designMode = "off";
			return false;	
		}
		else if(event.which != 3 && doc.designMode == "off") {
			doc.designMode = "on";
			return true;
		}
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : formatText() (changed)
	  Description : Format the content within the WYSIWYG Editor
	  Usage       : WYSIWYG.formatText(id, n, selected);
	  Arguments   : cmd - The execCommand (e.g. Bold)
	                n  - The editor identifier that the command affects (the textarea's ID)
	                selected - The selected value when applicable (e.g. Arial)
	\* ---------------------------------------------------------------------- */
	formatText: function(cmd, n, selected) {
			
		// When user clicks toolbar button make sure it always targets its respective WYSIWYG
		this.getEditorWindow(n).focus();
		
		// When in Text Mode these execCommands are disabled
		var formatIDs = new Array("FontSize","FontName","Bold","Italic","Underline","Subscript","Superscript","Strikethrough","Justifyleft","Justifyright","Justifycenter","InsertUnorderedList","InsertOrderedList","Indent","Outdent","ForeColor","BackColor","InsertImage","InsertTable","CreateLink", "CreateLinkHelpDesigner", "Preview", "RemoveFormat");
	  
		// Check if button clicked is in disabled list
		for (var i = 0; i < formatIDs.length; i++) {
			if (formatIDs[i] == cmd) {
				 var disabled_id = 1; 
			}
		}
		
		// rbg to hex convertion implementation dependents on browser
		var toHexColor = WYSIWYG_Core.isMSIE ? WYSIWYG_Core._dec_to_rgb : WYSIWYG_Core.toHexColor;
		
		// popup screen positions
		var popupPosition = {left: parseInt(window.screen.availWidth / 3), top: parseInt(window.screen.availHeight / 3)};		
		
		// Check if in Text Mode and disabled button was clicked
		if (this.viewTextMode[n] == true && disabled_id == 1) {
		  alert("You are in TEXT Mode. This feature has been disabled.");
		  return;
		}
		
		// Check the insert image popup implementation
		var imagePopupFile = this.config[n].PopupsDir + 'insert_image.html';
		var imagePopupWidth = 400;
		var imagePopupHeight = 210;
		if(typeof this.config[n].ImagePopupFile != "undefined" && this.config[n].ImagePopupFile != "") {
			imagePopupFile = this.config[n].ImagePopupFile;
		}
		if(typeof this.config[n].ImagePopupWidth && this.config[n].ImagePopupWidth > 0) {
			imagePopupWidth = this.config[n].ImagePopupWidth;
		}
		if(typeof this.config[n].ImagePopupHeight && this.config[n].ImagePopupHeight > 0) {
			imagePopupHeight = this.config[n].ImagePopupHeight;
		}
		
		// switch which action have to do
		switch(cmd) {
			// Font size
			case "FontSize":
				this.getEditorWindow(n).document.execCommand("FontSize", false, selected);
			break;
			
			// FontName
			case "FontName": 
				this.getEditorWindow(n).document.execCommand("FontName", false, selected);
			break;
			
			// ForeColor and 
			case "ForeColor":
				var rgb = this.getEditorWindow(n).document.queryCommandValue(cmd);
		      	var currentColor = rgb != '' ? toHexColor(this.getEditorWindow(n).document.queryCommandValue(cmd)) : "000000";
			  	window.open(this.config[n].PopupsDir + 'select_color.html?color=' + currentColor + '&command=' + cmd + '&wysiwyg=' + n, 'popup', 'location=0,status=0,scrollbars=0,width=210,height=165,top=' + popupPosition.top + ',left=' + popupPosition.left).focus();
			break;
			
			// BackColor
			case "BackColor":
				var currentColor = toHexColor(this.getEditorWindow(n).document.queryCommandValue(cmd));
			  	window.open(this.config[n].PopupsDir + 'select_color.html?color=' + currentColor + '&command=' + cmd + '&wysiwyg=' + n, 'popup', 'location=0,status=0,scrollbars=0,width=210,height=165,top=' + popupPosition.top + ',left=' + popupPosition.left).focus();
			break;
			
			// InsertImage
			case "InsertImage": 
				//window.open(imagePopupFile + '?wysiwyg=' + n, 'popup', 'location=0,status=0,scrollbars=0,resizable=0,width=' + imagePopupWidth + ',height=' + imagePopupHeight + ',top=' + popupPosition.top + ',left=' + popupPosition.left).focus();
				this.showUploadForm(n);
			break;
			
			// Remove Image
			case "RemoveImage": 
				this.removeImage(n);
			break;
			
			// Remove Link
			case "RemoveLink": 
				this.removeLink(n);
			break;
			
			// Remove a Node
			case "RemoveNode": 
				this.removeNode(n);
			break;
			
			// Create Link
			case "CreateLink": 
				window.open(this.config[n].PopupsDir + 'insert_hyperlink.html?wysiwyg=' + n, 'popup', 'location=0,status=0,scrollbars=0,resizable=0,width=350,height=160,top=' + popupPosition.top + ',left=' + popupPosition.left).focus();
			break;
			
			// Create Link for help manager
			case "CreateLinkHelpDesigner": 
				this.showCreateLinkWindow(n);
			break;
			
			// InsertTable
			case "InsertTable": 
				window.open(this.config[n].PopupsDir + 'create_table.html?wysiwyg=' + n, 'popup', 'location=0,status=0,scrollbars=0,resizable=0,width=400,height=360,top=' + popupPosition.top + ',left=' + popupPosition.left).focus();
			break;
			
			// ViewSource
			case "ViewSource": 
				this.viewSource(n);
			break;
			
			// ViewText
			case "ViewText": 
				this.viewText(n);
			break;
			
			// Help
			/*
			case "Help":
				window.open(this.config[n].PopupsDir + 'about.html?wysiwyg=' + n, 'popup', 'location=0,status=0,scrollbars=0,resizable=0,width=400,height=350,top=' + popupPosition.top + ',left=' + popupPosition.left).focus();
			break;
			*/
			// Strip any HTML added by word
			case "RemoveFormat":
				this.removeFormat(n);	
			break;
			
			// Preview thx to Korvo
			case "Preview":
				window.open(this.config[n].PopupsDir + 'preview.html?wysiwyg=' + n,'popup', 'location=0,status=0,scrollbars=1,resizable=1,width=' + this.config[n].PreviewWidth + ',height=' + this.config[n].PreviewHeight + ',top=' + popupPosition.top + ',left=' + popupPosition.left).focus();
			break;
			
			// Print
			case "Print":
				this.print(n);
			break;
						
			default: 
				WYSIWYG_Core.execCommand(n, cmd);
				
		}
	 		
		// hide node the font + font size selection
		this.hideFonts(n);
		this.hideFontSizes(n);		
	},	
		
	/* ---------------------------------------------------------------------- *\
	  Function    : insertHTML()
	  Description : Insert HTML into WYSIWYG in rich text
	  Usage       : WYSIWYG.insertHTML("<b>hello</b>", "textareaID")
	  Arguments   : html - The HTML being inserted (e.g. <b>hello</b>)
	                n  - The editor identifier that the HTML 
						 will be inserted into (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	insertHTML: function(html, n) {	
		if (WYSIWYG_Core.isMSIE) {	  
			this.getEditorWindow(n).document.selection.createRange().pasteHTML(html);   
		} 
		else {
			var span = this.getEditorWindow(n).document.createElement("span");
			span.innerHTML = html;
			this.insertNodeAtSelection(span, n);		
		}
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : insertNodeAtSelection()
	  Description : insert HTML into WYSIWYG in rich text (mozilla)
	  Usage       : WYSIWYG.insertNodeAtSelection(insertNode, n)
	  Arguments   : insertNode - The HTML being inserted (must be innerHTML inserted within a div element)
	                n          - The editor identifier that the HTML will be inserted into (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	insertNodeAtSelection: function(insertNode, n) {
	
		// get editor document
		var doc = this.getEditorWindow(n).document;
		// get current selection
		var sel = this.getSelection(n);
		
		// get the first range of the selection
		// (there's almost always only one range)
		var range = sel.getRangeAt(0);
		
		// deselect everything
		sel.removeAllRanges();
		
		// remove content of current selection from document
		range.deleteContents();
		
		// get location of current selection
		var container = range.startContainer;
		var pos = range.startOffset;
		
		// make a new range for the new selection
		range = doc.createRange();
		
		if (container.nodeType==3 && insertNode.nodeType==3) {					
			// if we insert text in a textnode, do optimized insertion
			container.insertData(pos, insertNode.data);
			// put cursor after inserted text
			range.setEnd(container, pos+insertNode.length);
			range.setStart(container, pos+insertNode.length);		
		} 	
		else {
		
			var afterNode;	
			var beforeNode;
			if (container.nodeType==3) {
				// when inserting into a textnode
				// we create 2 new textnodes
				// and put the insertNode in between
				var textNode = container;
				container = textNode.parentNode;
				var text = textNode.nodeValue;
				
				// text before the split
				var textBefore = text.substr(0,pos);
				// text after the split
				var textAfter = text.substr(pos);
				
				beforeNode = document.createTextNode(textBefore);
				afterNode = document.createTextNode(textAfter);
				
				// insert the 3 new nodes before the old one
				container.insertBefore(afterNode, textNode);
				container.insertBefore(insertNode, afterNode);
				container.insertBefore(beforeNode, insertNode);
				
				// remove the old node
				container.removeChild(textNode);
			} 
			else {
				// else simply insert the node
				afterNode = container.childNodes[pos];
				container.insertBefore(insertNode, afterNode);
			}
			
			range.setEnd(afterNode, 0);
			range.setStart(afterNode, 0);
		}
		
		sel.addRange(range);
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : print()
	  Description : Print out the content of the WYSIWYG editor area
	  Usage       : WYSIWYG.print(n)
	  Arguments   : n - The editor identifier (textarea ID)
	\* ---------------------------------------------------------------------- */
	print: function(n) {
		if(document.all && navigator.appVersion.substring(22,23)==4) {
			var doc = this.getEditorWindow(n).document;
			doc.focus();
			var OLECMDID_PRINT = 6;
			var OLECMDEXECOPT_DONTPROMPTUSER = 2;
			var OLECMDEXECOPT_PROMPTUSER = 1;
			var WebBrowser = '<object id="WebBrowser1" width="0" height="0" classid="CLSID:8856F961-340A-11D0-A96B-00C04FD705A2"></object>';
			doc.body.insertAdjacentHTML('beforeEnd',WebBrowser);
			WebBrowser.ExecWB(OLECMDID_PRINT, OLECMDEXECOPT_DONTPROMPTUSER);
			WebBrowser.outerHTML = '';
		} else {
			this.getEditorWindow(n).print();
		}
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : outputFontSelect()
	  Description : creates the Font Select drop down and inserts it into the toolbar
	  Usage       : WYSIWYG.outputFontSelect(n)
	  Arguments   : n - The editor identifier that the Font Select will update
		                when making font changes (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	outputFontSelect: function(n) {	
		 
		var fontDiv = $g('FontSelect' + n);
		if(fontDiv == null) { return; }
		
		var fonts = this.config[n].Fonts;
		var FontSelectObj = this.ToolbarList['selectfont'];
		var FontSelect = this.config[n].ImagesDir  + FontSelectObj[2];
		var FontSelectOn  = this.config[n].ImagesDir + FontSelectObj[3];
		fonts.sort();
		
		var FontSelectDropDown = new Array;
		//FontSelectDropDown[n] = '<table border="0" cellpadding="0" cellspacing="0"><tr><td onMouseOver="$g(\'selectFont' + n + '\').src=\'' + FontSelectOn + '\';" onMouseOut="$g(\'selectFont' + n + '\').src=\'' + FontSelect + '\';"><img src="' + FontSelect + '" id="selectFont' + n + '" width="85" height="20" onClick="WYSIWYG.showFonts(\'' + n + '\');" unselectable="on" border="0"><br>';
		FontSelectDropDown[n] = '<table border="0" cellpadding="0" cellspacing="0"><tr><td><div alt="' + FontSelectObj[1] + '" id="' + FontSelectObj[0] + '" class="editorbackground" style="background-position:' + FontSelectObj[4] + ';width:85px;height:20px;" onmouseover="this.style.backgroundPosition=\'' + FontSelectObj[5] + '\';" onmouseout="this.style.backgroundPosition=\'' + FontSelectObj[4] + '\';" onclick="WYSIWYG.showFonts(\'' + n + '\');" unselectable="on" width="85" height="20">'+mj.insertSpacer(20,20)+'</div>';
		FontSelectDropDown[n] += '<span id="Fonts' + n + '" class="dropdown" style="width: 145px;">';
	
		for (var i = 0; i < fonts.length;i++) {
		  	if (fonts[i]) {
		  		FontSelectDropDown[n] += '<button type="button" onClick="WYSIWYG.formatText(\'FontName\',\'' + n + '\',\'' + fonts[i] + '\')\;" onMouseOver="this.className=\'mouseOver\'" onMouseOut="this.className=\'mouseOut\'" class="mouseOut" style="width: 120px;"><table cellpadding="0" cellspacing="0" border="0"><tr><td align="left" style="font-family:' + fonts[i] + '; font-size: 12px;">' + fonts[i] + '</td></tr></table></button><br>';	
		  	}
	  	}
		
		FontSelectDropDown[n] += '</span></td></tr></table>';
		fontDiv.insertAdjacentHTML("afterBegin", FontSelectDropDown[n]);
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : outputFontSizes()
	  Description : creates the Font Sizes drop down and inserts it into the toolbar
	  Usage       : WYSIWYG.outputFontSelect(n)
	  Arguments   : n   - The editor identifier that the Font Sizes will update
		                    when making font changes (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	outputFontSizes: function(n) {	
	
		var fontSizeDiv = $g('FontSizes' + n);
		if(fontSizeDiv == null) { return; }
		
		var fontSize = this.config[n].Fontsizes;
		var FontSizeObj = this.ToolbarList['selectsize'];
		var FontSize = this.config[n].ImagesDir + FontSizeObj[2];
		var FontSizeOn = this.config[n].ImagesDir + FontSizeObj[3];
	
		fontSize.sort();
		var FontSizesDropDown = new Array;
		//FontSizesDropDown[n] = '<table border="0" cellpadding="0" cellspacing="0"><tr><td onMouseOver="$g(\'selectSize' + n + '\').src=\'' + FontSizeOn + '\';" onMouseOut="$g(\'selectSize' + n + '\').src=\'' + FontSize + '\';"><img src="' + FontSize + '" id="selectSize' + n + '" width="49" height="20" onClick="WYSIWYG.showFontSizes(\'' + n + '\');" unselectable="on" border="0"><br>';
		FontSizesDropDown[n] = '<table border="0" cellpadding="0" cellspacing="0"><tr><td onMouseOver="$g(\'selectSize' + n + '\').src=\'' + FontSizeOn + '\';" onMouseOut="$g(\'selectSize' + n + '\').src=\'' + FontSize + '\';"><div alt="' + FontSizeObj[1] + '" class="editorbackground" id="selectSize' + n + '" style="background-position:' + FontSizeObj[4] + ';width:49px;height:20px;" onmouseover="this.style.backgroundPosition=\'' + FontSizeObj[5] + '\';" onmouseout="this.style.backgroundPosition=\'' + FontSizeObj[4] + '\';" onclick="WYSIWYG.showFontSizes(\'' + n + '\');" unselectable="on" width="49" height="20">'+mj.insertSpacer(20,20)+'</div>';
	  	FontSizesDropDown[n] += '<span id="Sizes' + n + '" class="dropdown" style="width: 170px;">';
	
		for (var i = 0; i < fontSize.length;i++) {
		  if (fontSize[i]) {
	      	FontSizesDropDown[n] += '<button type="button" onClick="WYSIWYG.formatText(\'FontSize\',\'' + n + '\',\'' + fontSize[i] + '\')\;" onMouseOver="this.className=\'mouseOver\'" onMouseOut="this.className=\'mouseOut\'" class="mouseOut" style="width: 145px;"><table cellpadding="0" cellspacing="0" border="0"><tr><td align="left" style="font-family: arial, verdana, helvetica;"><font size="' + fontSize[i] + '">size ' + fontSize[i] + '</font></td></tr></table></button><br>';	
	      }
	  	}
		
		FontSizesDropDown[n] += '</span></td></tr></table>';
		fontSizeDiv.insertAdjacentHTML("afterBegin", FontSizesDropDown[n]);
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : hideFonts()
	  Description : Hides the list of font names in the font select drop down
	  Usage       : WYSIWYG.hideFonts(n)
	  Arguments   : n   - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	hideFonts: function(n) {
		if($g('Fonts' + n)) { $g('Fonts' + n).style.display = 'none'; }
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : hideFontSizes()
	  Description : Hides the list of font sizes in the font sizes drop down
	  Usage       : WYSIWYG.hideFontSizes(n)
	  Arguments   : n   - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	hideFontSizes: function(n) {
		if($g('Sizes' + n)) { $g('Sizes' + n).style.display = 'none'; }
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : showFonts()
	  Description : Shows the list of font names in the font select drop down
	  Usage       : WYSIWYG.showFonts(n)
	  Arguments   : n   - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	showFonts: function(n) { 
		if($g('Fonts' + n) == null) { return; }
		if ($g('Fonts' + n).style.display == 'block') {
			$g('Fonts' + n).style.display = 'none';
		}
		else {
			$g('Fonts' + n).style.display = 'block'; 
			$g('Fonts' + n).style.position = 'absolute';		
		}
		
		// hide font size selection
		this.hideFontSizes(n);
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : showFontSizes()
	  Description : Shows the list of font sizes in the font sizes drop down
	  Usage       : WYSIWYG.showFonts(n)
	  Arguments   : n   - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	showFontSizes: function(n) { 
		if($g('Sizes' + n) == null) { return; }
		if ($g('Sizes' + n).style.display == 'block') {
			$g('Sizes' + n).style.display = 'none';
		}
		else {
			$g('Sizes' + n).style.display = 'block'; 
			$g('Sizes' + n).style.position = 'absolute';		
		}
		
		// hide font size selection
		this.hideFonts(n);
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : viewSource()
	  Description : Shows the HTML source code generated by the WYSIWYG editor
	  Usage       : WYSIWYG.showFonts(n)
	  Arguments   : n   - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	viewSource: function(n) {
		
		// document
		var doc = this.getEditorWindow(n).document;
			
		// View Source for IE 	 
		if (WYSIWYG_Core.isMSIE) {
			var iHTML = doc.body.innerHTML;
			// strip off the absolute urls
			iHTML = this.stripURLPath(n, iHTML);
			// replace all decimal color strings with hex decimal color strings
			iHTML = WYSIWYG_Core.replaceRGBWithHexColor(iHTML);
			doc.body.innerText = iHTML;
		}
	  	// View Source for Mozilla/Netscape
	  	else {
	  		// replace all decimal color strings with hex decimal color strings
			var html = WYSIWYG_Core.replaceRGBWithHexColor(doc.body.innerHTML);
	    	html = document.createTextNode(html);
	    	doc.body.innerHTML = "";
	    	doc.body.appendChild(html);
	  	}
	  
		// Hide the HTML Mode button and show the Text Mode button
		// Validate if Elements are present
		if($g('HTMLMode' + n)) {
		    $g('HTMLMode' + n).style.display = 'none'; 
		}
	    if($g('textMode' + n)) {
		    $g('textMode' + n).style.display = 'block';
		}
		
		// set the font values for displaying HTML source
		doc.body.style.fontSize = "12px";
		doc.body.style.fontFamily = "Courier New"; 
		
	  	this.viewTextMode[n] = true;
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : viewSource()
	  Description : Shows the HTML source code generated by the WYSIWYG editor
	  Usage       : WYSIWYG.showFonts(n)
	  Arguments   : n   - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	viewText: function(n) { 
		
		// get document
		var doc = this.getEditorWindow(n).document;
		
		// View Text for IE 	  	 
		if (WYSIWYG_Core.isMSIE) {
	    	var iText = doc.body.innerText;
	    	// strip off the absolute urls
			iText = this.stripURLPath(n, iText);
			// replace all decimal color strings with hex decimal color strings
			iText = WYSIWYG_Core.replaceRGBWithHexColor(iText);
	    	doc.body.innerHTML = iText;
		}
	  
		// View Text for Mozilla/Netscape
	  	else {
	    	var html = doc.body.ownerDocument.createRange();
	    	html.selectNodeContents(doc.body);
	    	// replace all decimal color strings with hex decimal color strings
			html = WYSIWYG_Core.replaceRGBWithHexColor(html.toString());
	    	doc.body.innerHTML = html;
		}
					  
		// Hide the Text Mode button and show the HTML Mode button
		// Validate if Elements are present
		if($g('textMode' + n)) {
			$g('textMode' + n).style.display = 'none'; 
		}
		if($g('HTMLMode' + n)) {
			$g('HTMLMode' + n).style.display = 'block';
		}
		
		// reset the font values (changed)
		WYSIWYG_Core.setAttribute(doc.body, "style", this.config[n].DefaultStyle);
		
		this.viewTextMode[n] = false;
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : getDocumentPath()
	  Description : Get the path of the given document
	  Usage       : WYSIWYG.getDocumentPath(doc)
	  Arguments   : doc  - Document of which you get the the path
	\* ---------------------------------------------------------------------- */
	getDocumentPathOfUrl: function(url) {
		var path = null;
		
		// if local file system, convert local url into web url
		url = url.replace(/file:\/\//gi, "file:///");
		url = url.replace(/\\/gi, "\/");
		var pos = url.lastIndexOf("/");
		if(pos != -1) {
			path = url.substring(0, pos + 1);
		}
		return path;
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : getDocumentUrl()
	  Description : Get the documents url, convert local urls to web urls
	  Usage       : WYSIWYG.getDocumentUrl(doc)
	  Arguments   : doc  - Document of which you get the the path
	\* ---------------------------------------------------------------------- */
	getDocumentUrl: function(doc) {
		// if local file system, convert local url into web url
		var url = doc.URL;
		url = url.replace(/file:\/\//gi, "file:///");
		url = url.replace(/\\/gi, "\/");
		return url;
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : stripURLPath()
	  Description : Strips off the defined image and the anchor urls of the given content.
	  				It also can strip the document URL automatically if you define auto.
	  Usage       : WYSIWYG.stripURLPath(content)
	  Arguments   : content  - Content on which the stripping applies
	\* ---------------------------------------------------------------------- */
	stripURLPath: function(n, content, exact) {
	
		// parameter exact is optional
		if(typeof exact == "undefined") {
			exact = true;
		}
	
		var stripImgageUrl = null;
		var stripAnchorUrl = null;
		
		// add url to strip of anchors to array
		if(this.config[n].AnchorPathToStrip == "auto") {
			stripAnchorUrl = this.getDocumentUrl(document);
		}
		else if(this.config[n].AnchorPathToStrip != "") {
			stripAnchorUrl = this.config[n].AnchorPathToStrip;
		}
		
		// add strip url of images to array
		if(this.config[n].ImagePathToStrip == "auto") {
			stripImgageUrl = this.getDocumentUrl(document);
		}
		else if(this.config[n].ImagePathToStrip != "") {
			stripImgageUrl = this.config[n].ImagePathToStrip;
		}
		
		var url;
		var regex;
		var result;
		// strip url of image path
		if(stripImgageUrl) {
			// escape reserved characters to be a valid regex	
			url = WYSIWYG_Core.stringToRegex(this.getDocumentPathOfUrl(stripImgageUrl));	
			
			// exact replacing of url. regex: src="<url>"
			if(exact) {
				regex = eval("/(src=\")(" + url + ")([^\"]*)/gi");
				content = content.replace(regex, "$1$3");	
			}
			// not exect replacing of url. regex: <url>
			else {
				regex = eval("/(" + url + ")(.+)/gi");
				content = content.replace(regex, "$2");	
			}
			
			// strip absolute urls without a heading slash ("images/print.gif")	
			result = this.getDocumentPathOfUrl(stripImgageUrl).match(/.+[\/]{2,3}[^\/]*/,"");
			if(result) {
				url = WYSIWYG_Core.stringToRegex(result[0]);
				
				// exact replacing of url. regex: src="<url>"
				if(exact) {
					regex = eval("/(src=\")(" + url + ")([^\"]*)/gi");
					content = content.replace(regex, "$1$3");
				}
				// not exect replacing of url. regex: <url>
				else {
					regex = eval("/(" + url + ")(.+)/gi");
					content = content.replace(regex, "$2");	
				}
			}	
		}
		
		// strip url of image path
		if(stripAnchorUrl) {						
			// escape reserved characters to be a valid regex		
			url = WYSIWYG_Core.stringToRegex(this.getDocumentPathOfUrl(stripAnchorUrl));
			
			// strip absolute urls with a heading slash ("/product/index.html")
			// exact replacing of url. regex: src="<url>"
			if(exact) {
				regex = eval("/(href=\")(" + url + ")([^\"]*)/gi");
				content = content.replace(regex, "$1$3");	
			}
			// not exect replacing of url. regex: <url>
			else {
				regex = eval("/(" + url + ")(.+)/gi");
				content = content.replace(regex, "$2");	
			}
			
			// strip absolute urls without a heading slash ("product/index.html")	
			result = this.getDocumentPathOfUrl(stripAnchorUrl).match(/.+[\/]{2,3}[^\/]*/,"");
			if(result) {
				url = WYSIWYG_Core.stringToRegex(result[0]);
				// exact replacing of url. regex: src="<url>"
				if(exact) {
					regex = eval("/(href=\")(" + url + ")([^\"]*)/gi");
					content = content.replace(regex, "$1$3");	
				}
				// not exect replacing of url. regex: <url>
				else {
					regex = eval("/(" + url + ")(.+)/gi");
					content = content.replace(regex, "$2");	
				}
				
			}
			
			// stip off anchor links with #name			
			url = WYSIWYG_Core.stringToRegex(stripAnchorUrl);
			// exact replacing of url. regex: src="<url>"
			if(exact) {
				regex = eval("/(href=\")(" + url + ")(#[^\"]*)/gi");
				content = content.replace(regex, "$1$3");
			}
			// not exect replacing of url. regex: <url>
			else {
				regex = eval("/(" + url + ")(.+)/gi");
				content = content.replace(regex, "$2");	
			}
			
			
			// stip off anchor links with #name (only for local system)
			url = this.getDocumentUrl(document);
			var pos = url.lastIndexOf("/");
			if(pos != -1) {
				url = url.substring(pos + 1, url.length);
				url = WYSIWYG_Core.stringToRegex(url);
				// exact replacing of url. regex: src="<url>"
				if(exact) {
					regex = eval("/(href=\")(" + url + ")(#[^\"]*)/gi");
					content = content.replace(regex, "$1$3");
				}
				// not exect replacing of url. regex: <url>
				else {
					regex = eval("/(" + url + ")(.+)/gi");
					content = content.replace(regex, "$2");	
				}
			}
		}
		
		return content;
	},	
		
	/* ---------------------------------------------------------------------- *\
	  Function    : updateTextArea()
	  Description : Updates the text area value with the HTML source of the WYSIWYG
	  Arguments   : n   - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	updateTextArea: function(n) {	
		// on update switch editor back to html mode
		if(this.viewTextMode[n]) { this.viewText(n); }
		// get inner HTML
		var content = this.getEditorWindow(n).document.body.innerHTML;
		// strip off defined URLs on IE
		content = this.stripURLPath(n, content);
		// replace all decimal color strings with hex color strings
		content = WYSIWYG_Core.replaceRGBWithHexColor(content);
		// remove line breaks before content will be updated
		if(this.config[n].ReplaceLineBreaks) { content = content.replace(/(\r\n)|(\n)/ig, ""); }
		// set content back in textarea
		$g(n).value = content;
	},
		
	/* ---------------------------------------------------------------------- *\
	  Function    : hideToolbars()
	  Description : Hide all toolbars
	  Usage       : WYSIWYG.hideToolbars(n)
	  Arguments   : n - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	hideToolbars: function(n) {
		for(var i=0;i<this.config[n].Toolbar.length;i++) {
			var toolbar = $g("toolbar" + i + "_" + n);
			if(toolbar) { toolbar.style.display = "none"; }
		}	
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : showToolbars()
	  Description : Display all toolbars
	  Usage       : WYSIWYG.showToolbars(n)
	  Arguments   : n - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	showToolbars: function(n) {
		for(var i=0;i<this.config[n].Toolbar.length;i++) {
			var toolbar = $g("toolbar" + i + "_" + n);
			if(toolbar) { toolbar.style.display = ""; }
		}	
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : hideStatusBar()
	  Description : Hide the status bar
	  Usage       : WYSIWYG.hideStatusBar(n)
	  Arguments   : n - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	hideStatusBar: function(n) {
		var statusbar = $g('wysiwyg_statusbar_' + n);
		if(statusbar) {	statusbar.style.display = "none"; }
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : showStatusBar()
	  Description : Display the status bar
	  Usage       : WYSIWYG.showStatusBar(n)
	  Arguments   : n - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	showStatusBar: function(n) {
		var statusbar = $g('wysiwyg_statusbar_' + n);
		if(statusbar) { statusbar.style.display = ""; }
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : findParentTag()
	  Description : Get the given parent tag of a range
	  Usage       : WYSIWYG.findParentTag(parentTagName, range)
	  Arguments   : parentTagName - Parent tag to find
	  				range - Range 
	\* ---------------------------------------------------------------------- */
	findParentTag: function(parentTagName, range){
		parentTagName = parentTagName.toUpperCase();
		var rangeWorking;
		var elmWorking = null;
		try {
			if(!WYSIWYG_Core.isMSIE) {
				var node = range.startContainer;	
				var pos = range.startOffset;
				if(node.nodeType != 3) { node = node.childNodes[pos]; }
				elmWorking = node;
				while (elmWorking.tagName != "HTML") {
			  		if (elmWorking.tagName == parentTagName){
			  			return elmWorking;
			  		} 
			  		elmWorking = elmWorking.parentNode;
			 	}
			 	return null;
			}
			else {
				if(range.length > 0) {
					elmWorking = range.item(0);
				}
				else {
					elmWorking = range.parentElement();	
				}
				while (elmWorking.tagName != "HTML") {
			  		if (elmWorking.tagName == parentTagName){
			   			return elmWorking;
			  		} else {
			   			elmWorking = elmWorking.parentElement;
			  		}
			 	}
				rangeWorking = range.duplicate();
				rangeWorking.collapse(true);
				rangeWorking.moveEnd("character", 1);
				if (rangeWorking.text.length>0) {
					while (rangeWorking.compareEndPoints("EndToEnd", range) < 0){
			  			rangeWorking.move("Character");
			  			if (null != this.findParentTag(parentTagName, rangeWorking)){
			   				return this.findParentTag(parentTagName, rangeWorking);
			  			}
			 		}
			 	}
			 	return null;
			}
		}
		catch(e) {
			return null;
		}
	},
		
	/* ---------------------------------------------------------------------- *\
	  Function    : getTag()
	  Description : Get the acutally tag of the given range
	  Usage       : WYSIWYG.getTag(range)
	  Arguments   : range - Range
	\* ---------------------------------------------------------------------- */
	getTag: function(range) {
		try {
		    if(!WYSIWYG_Core.isMSIE) {
				var node = range.startContainer;	
				var pos = range.startOffset;
				if(node.nodeType != 3) { node = node.childNodes[pos]; }
				
				if(node.nodeName && node.nodeName.search(/#/) != -1) {
					return node.parentNode;
				}
				return node;
			}
			else {
				if(range.length > 0) {
					return range.item(0);
				}
				else if(range.parentElement()) {
					return range.parentElement();
				}
			}
			return null;
		}
		catch(e) {
			return null;
		}
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : getParent()
	  Description : Get the parent node of an node
	  Usage       : WYSIWYG.getParent(node)
	  Arguments   : element - Element which parent will be returned
	\* ---------------------------------------------------------------------- */
	getParent: function(element) {
		if(element.parentNode) {
			return element.parentNode;
		}
		return null;
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : getTextRange()
	  Description : Get the text range object of the given element
	  Usage       : WYSIWYG.getTextRange(element)
	  Arguments   : element - An element of which you get the text range object
	\* ---------------------------------------------------------------------- */
	getTextRange: function(element){
		var range = element.parentTextEdit.createTextRange();
		range.moveToElementText(element);
		return range;
	},
	

	
	/* ---------------------------------------------------------------------- *\
	  Function    : invertIELineBreakCapability()
	  Description : Inverts the line break capability of IE (Thx to richyrich)
	  				Normal: ENTER = <p> , SHIFT + ENTER = <br>
	  				Inverted: ENTER = <br>, SHIFT + ENTER = <p>
	  Usage       : WYSIWYG.invertIELineBreakCapability(n)
	  Arguments   : n   - The editor identifier (the textarea's ID)
	\* ---------------------------------------------------------------------- */
	invertIELineBreakCapability: function(n) {
	
		var editor = this.getEditorWindow(n);
		var sel;
		// validate if the press key is the carriage return key
		if (editor.event.keyCode==13) {
	    	if (!editor.event.shiftKey) {
				sel = this.getRange(this.getSelection(n));
	            sel.pasteHTML("<br>");
	            editor.event.cancelBubble = true;
	            editor.event.returnValue = false;
	            sel.select();
	            sel.moveEnd("character", 1);
	            sel.moveStart("character", 1);
	            sel.collapse(false);
	            return false;
			}
	        else {
	            sel = this.getRange(this.getSelection(n));
	            sel.pasteHTML("<p>");
	            editor.event.cancelBubble = true;
	            editor.event.returnValue = false;
	            sel.select();
	            sel.moveEnd("character", 1);
	            sel.moveStart("character", 1);
	            sel.collapse(false);
	            return false;
	    	}
		}  
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : selectNode()
	  Description : Select a node within the current editor
	  Usage       : WYSIWYG.selectNode(n, level)
	  Arguments   : n   - The editor identifier (the textarea's ID)
	  				level - identifies the level of the element which will be selected
	\* ---------------------------------------------------------------------- */
	selectNode: function(n, level) {
		
		var sel = this.getSelection(n);
		var range = this.getRange(sel);
		var parentnode = this.getTag(range);
		var i = 0;
		
		for (var node=parentnode; (node && (node.nodeType == 1)); node=node.parentNode) {
			if (i == level) {
				this.nodeSelection(n, node);
			}
			i++;
		}
		
		this.updateStatusBar(n);
	},
	
	/* ---------------------------------------------------------------------- *\
	  Function    : nodeSelection()
	  Description : Do the node selection
	  Usage       : WYSIWYG.nodeSelection(n, node)
	  Arguments   : n   - The editor identifier (the textarea's ID)
	  				node - The node which will be selected
	\* ---------------------------------------------------------------------- */
	nodeSelection: function(n, node) {
		
		var doc = this.getEditorWindow(n).document;
		var sel = this.getSelection(n);
		var range = this.getRange(sel);
		
		if(!WYSIWYG_Core.isMSIE) {
			if (node.nodeName == "BODY") {
				range.selectNodeContents(node);
			} else {
				range.selectNode(node);
			}

			/*
			if (endNode) {
				try {
					range.setStart(node, startOffset);
					range.setEnd(endNode, endOffset);
				} catch(e) {
				}
			}
			*/
			
			if (sel) { sel.removeAllRanges(); }
			if (sel) { sel.addRange(range);	 }
		}
		else {
			// MSIE may not select everything when BODY is selected - 
			// start may be set to first text node instead of first non-text node - 
			// no known workaround
			if ((node.nodeName == "TABLE") || (node.nodeName == "IMG") || (node.nodeName == "INPUT") || (node.nodeName == "SELECT") || (node.nodeName == "TEXTAREA")) {
				try {
					range = doc.body.createControlRange();
					range.addElement(node);
					range.select();
				} 
				catch(e) { }
			} 
			else {
				range = doc.body.createTextRange();
				if (range) {
					range.collapse();
					if (range.moveToElementText) {
						try {
							range.moveToElementText(node);
							range.select();
						} catch(e) {
							try {
								range = doc.body.createTextRange();
								range.moveToElementText(node);
								range.select();
							} 
							catch(e) {}
						}
					} else {
						try {
							range = doc.body.createTextRange();
							range.moveToElementText(node);
							range.select();
						} 
						catch(e) {}
					}
				}
			}
		}
	},
	
	showCreateLinkWindow : function(n){
		if(this.config[n].treeSource)
			this.browseLink.call(this, function(url){
				//this.insertLink(url, target, style, styleClass, name, n);
				this.insertLink(url, '', '', '', '', this.n);
				this.linkWin.close();
			},n);
	},
	
	browseLink : function(cb,n){
		var t = this;
		t.n=n;
		t.linkWinCallback = function(){
			if(t.linkWinTree.selectedNode)
				cb.call(t, t.linkWinTree.selectedNode.url);
		};
		if(!t.linkWin){
			var _w=350,_h=420;
			t.linkWin = new mj.window({
				renderTo : mj.NE(),
				title : mj.lng.objects.browseLink.winTitle,
				modal : true,
				width : _w,
				height : _h,
				minWidth : 350,
				minHeight : 320,
				buttons : [
					{title: mj.lng.titles.buttons.cancel, scope:this,handler:function(){t.linkWin.hide();}},
					{title: mj.lng.titles.buttons.ok, handler:t.linkWinCallback}
				]
			});
			_w = _w - 14;
			_h = _h - 58;
			t.waitMask = $(mj.NE(t.linkWin.getBody(),{
				cls:'mj-page-wait-mask mj-opacity-8',
				style:'display:none;width:'+_w+'px;height:'+_h+'px;',
				html:'<table width="100%" height="100%"><tr><td align="center" valign="middle"><img src="'+mj.glb.imagePath+'ajax-loader.gif"/><br/><br/><span class="mj-page-wait-title">Lütfen Bekleyin...</span></td></tr></table>'
			}));
			t.waitMaskShow = function(){
				t.waitMaskActive=true;
				t.waitMask[0].style.display='block';
			};
			t.waitMaskHide = function(){
				t.waitMaskActive=false;
				t.waitMask[0].style.display='none';
			};
			t.linkWinTree = new mj.tree({
				renderTo : mj.NE(t.linkWin.getBody()),
				store : new mj.store({data:[]}),
				mode : 'local'
			});
		}else{
			t.linkWin.buttons[1].setHandler(t.linkWinCallback, t);
			// if(!t.bWinTree.store.loaded)
				// t.bWinTree.load();
		}
		t.linkWinTree.store.on('beforeload', function(){
			t.waitMaskShow();
		},t);
		t.linkWinTree.store.on('load', function(){
			t.waitMaskHide();
		},t);
		if(t.config[n].treeSource)
			t.linkWinTree.store.data=t.config[n].treeSource.trees.subjectTree.store.data;
		//if(!t.linkWinTree.store.loaded)
			t.linkWinTree.load();
		t.wins.push(t.linkWin);
		t.linkWin.show();
	},
	
	showUploadForm : function(n){
		this.browseImage.call(this, function(fileUrl){
			var image = this.imageForm.getValue();
			this.insertImage(fileUrl, image.width, image.height, image.alignment, image.border, image.alt, image.hspace, image.vspace, n);
			this.bWin.close();
		}, this);
	},
	
	browseImage : function(cb, scope){
		var t = this;
		t.bWinCallback = function(){
			var fileName = t.bWin.getFile.call(this);
			if(fileName){
				cb.call(scope||this, fileName);
				t.bWin.hide();
			}
		};
		if(!t.bWin){
			var _w=700,_h=420;
			t.bWin = new mj.window({
				renderTo : mj.NE(),
				title : mj.lng.objects.browseImage.winTitle,
				modal : true,
				width : _w,
				height : _h,
				minWidth :520,
				minHeight : 420,
				buttons : [
					{title: mj.lng.titles.buttons.cancel, scope:this,handler:function(){t.bWin.hide();}},
					{title: mj.lng.titles.buttons.ok, handler:t.bWinCallback}
				]
			});
			_w = _w - 14;
			_h = _h - 58;
			t.waitMask = $(mj.NE(t.bWin.getBody(),{
				cls:'mj-page-wait-mask mj-opacity-8',
				style:'display:none;width:'+_w+'px;height:'+_h+'px;',
				html:'<table width="100%" height="100%"><tr><td align="center" valign="middle"><img src="'+mj.glb.imagePath+'ajax-loader.gif"/><br/><br/><span class="mj-page-wait-title">Lütfen Bekleyin...</span></td></tr></table>'
			}));
			t.waitMaskShow = function(){
				t.waitMaskActive=true;
				t.waitMask[0].style.display='block';
			};
			t.waitMaskHide = function(){
				t.waitMaskActive=false;
				t.waitMask[0].style.display='none';
			};
			t.waitMaskShow();
			t.init = function(){
				if(this != arguments.callee._oScope){
					return arguments.callee.apply(arguments.callee._oScope, arguments);
				};
				var t = this;
				t.bWin.getFile = function(){
					switch(t.bWinTab.activeTab){
						case 0 :
							if(t.bWinView.selections.length>0)
								return t.bWinView.selections[0].store.fileName;
							break;
						case 1 : 
							if(t.bWinTree.selectedNode){
								t.bWinUploadForm.setValue({'klasor':mj.glb.uploadPath+t.bWinTree.selectedNode.id});
								t.bWinUploadForm.submit({
									url : mj.glb.functionsPath,
									params : {event:'upload'},
									success : function(data){
										t.bWinView.store.load();
										t.bWinTab.setActive(0);
									},
									failure : function(data){
										mj.message(data.msg);
									},
									scope:t,
									encoded : true
								});
							}else
								new mj.message({
									title : mj.lng.glb.info,
									msg : mj.lng.objects.browseImage.selectFolderBefore,
									modal : true
								});
							break;
						case 2 :
							var url = t.bWinURL.getValue();
							if(url)
								return url;
							break;
					}
					return false;
				};
				t.mainLayout = new mj.layout({
					renderTo : mj.NE(t.bWin.getBody()),
					layout : 'border',
					items : [
						{
							region  : 'south',
							initial : 85,
							min : 85,
							max : 195,
							split: true,
							collapsible : true
						}
					]
				});
				t.imageForm = new mj.form({
					renderTo : t.mainLayout.getBody('south'),
					layout : 'border',
					items : [
						new mj.form.fieldSet({
							title : mj.lng.objects.wysiwyg.imageProperties,
							items : [
								new mj.form.textField({
									dataIndex : 'url',
									title : mj.lng.glb.url,
									labelWidth : '120px',
									width : 320,
									readOnly : true
								}),
								new mj.form.textField({
									dataIndex : 'alt',
									title : mj.lng.objects.wysiwyg.altText,
									labelWidth : '120px',
									width : 320
								})
							]
						}),
						new mj.form.fieldSet({
							title : mj.lng.objects.wysiwyg.layout,
							items : [
								new mj.form.textField({
									dataIndex : 'width',
									title : mj.lng.glb.width,
									labelWidth : '120px',
									width : 110
								}),
								new mj.form.combo({
									dataIndex : 'alignment',
									title : mj.lng.glb.alignment,
									labelWidth : '90px',
									width : 110,
									right : true,
									clearOnTriggerClick : true,
									store : new mj.store({data:[
										{id:"left",text:mj.lng.glb.left},
										{id:"right",text:mj.lng.glb.right},
										{id:"texttop",text:mj.lng.objects.wysiwyg.texttop},
										{id:"absmiddle",text:mj.lng.objects.wysiwyg.absmiddle},
										{id:"baseline",text:mj.lng.objects.wysiwyg.baseline},
										{id:"absbottom",text:mj.lng.objects.wysiwyg.absbottom},
										{id:"bottom",text:mj.lng.glb.bottom},
										{id:"middle",text:mj.lng.glb.middle},
										{id:"top",text:mj.lng.glb.top}
									]})
								}),
								new mj.form.textField({
									dataIndex : 'height',
									title : mj.lng.glb.height,
									labelWidth : '120px',
									width : 110
								}),
								new mj.form.textField({
									dataIndex : 'hspace',
									title : mj.lng.objects.wysiwyg.hspace,
									right : true,
									labelWidth : '90px',
									width : 110
								}),
								new mj.form.numberField({
									dataIndex : 'border',
									title : mj.lng.objects.wysiwyg.border,
									labelWidth : '120px',
									width : 110
								}),
								new mj.form.textField({
									dataIndex : 'vspace',
									title : mj.lng.objects.wysiwyg.vspace,
									right : true,
									labelWidth : '90px',
									width : 110
								})
							]
						})
					]
				});
				t.bWinLayout = new mj.layout({
					renderTo : t.mainLayout.getBody('center'),
					layout : 'border',
					items : [
						{
							region  : 'west',
							initial : 190,
							min : 100,
							max : 190,
							split: false,
							collapsible : true
						}
					]
				});
				t.bWinWestPanel = new mj.panel({
					renderTo : t.bWinLayout.getBody('west'),
					fitToParent : true
				});
				t.stores['bWinTree'] = new mj.store({
					url : mj.glb.functionsPath,
					params : {
						myRoot : mj.glb.uploadPath,
						node : mj.glb.uploadFolder,
						event : 'getDirTree',
						fileTypes : '*'
					}
				});
				t.bWinTree = new mj.tree({
					renderTo : t.bWinWestPanel.getBody(),
					store : t.stores.bWinTree,
					mode : 'remote',
					icon : true
				});
				t.bWinTab = new mj.tab({
					renderTo : t.bWinLayout.getBody('center'),
					activeTab : 0,
					tabWidth : 120,
					border:false,
					items :[{
							title: mj.lng.objects.browseImage.files,
							iconCls:'tabs',
							closable : false
						},{
							title: mj.lng.objects.browseImage.upload,
							iconCls:'tabs',
							closable : false
						}/*,{
							title: mj.lng.objects.browseImage.adres,
							iconCls:'tabs',
							closable : false
						}*/
					]
				});
				t.bWinTab.on('tabchange', function(tab, newTab, oldTab){
					t.bWin.buttons[1].setTitle(newTab==1?mj.lng.objects.browseImage.upload:mj.lng.objects.browseImage.select);
					if(newTab==1){
						t.bWinUploadPanelBody.empty();
						t.bWinUploadForm = new mj.form({
							renderTo : t.bWinUploadPanelBody,
							items:[
								new mj.form.textField({
									hidden : true,
									type : 'hidden',
									name : 'klasor'
								}),
								new mj.form.fileInput({
									id:'resim',
									name : 'resim',
									maxFile : 10,
									title : mj.lng.objects.browseImage.browse,
									labelWidth : '110px'
								})
							]
						});
					}
				}, t);
				var tpl=['<div class=\"thumb-wrap\">',
				'<div class=\"thumb\"><table width="80" height="80" cellpadding="0" cellspacing="0"><tr><td align="center" valign="middle"><img src=\"{url}\" title=\"{name}\" style="width:{width}px;height:{height}px;"/></td></tr></table></div>',
				'</div>'];
				t.bWinViewPanel = new mj.panel({
					renderTo : t.bWinTab.tabs[0].getBody(),
					fitToParent : true
				});
				t.stores['bWinView'] = new mj.store({
					url : mj.glb.functionsPath,
					params : {
						myRoot : mj.glb.uploadPath,
						node : mj.glb.uploadFolder,
						fileTypes : '*',
						event : 'getImageView'
					}
				});
				t.bWinView = new mj.view({
					renderTo : t.bWinViewPanel.getBody(),
					store : t.stores.bWinView,
					pbar : new mj.pager({limit:15,pos:'bottom'}),
					tpl : new mj.template(tpl),
					selector : 'div.thumb-wrap'
				});
				t.bWinView.on('itemclick', function(view, item){
					t.imageForm.clear();
					var d = item.store;
					t.imageForm.setValue({
						url : d.fileName,
						alt : d.name,
						width : d._width+'px',
						height : d._height+'px'
					});
				}, t);
				t.bWinView.on('dblclick',function(a){
					t.bWinCallback();
				},t);
				t.bWinTree.on('nodeclick', function(ptree,pnode){
					var ps = ptree.selectedNode;
					t.bWinView.store.params.start = 0;
					t.bWinView.pbar.params.start = 0;
					t.bWinView.store.params.current = 1;
					t.bWinView.pbar.params.current = 1;
					t.bWinView.store.params.node = ps.id;
					t.bWinView.store.load();
				}, t);
				/*
				t.bWinUploadPanel = new mj.panel({
					renderTo : t.bWinTab.tabs[1].getBody(),
					fitToParent : true
				});
				*/
				t.bWinUploadPanelBody = t.bWinTab.tabs[1].getBody();//t.bWinUploadt.getBody();
				/*
				t.bWinURLForm = new mj.form({
					renderTo : t.bWinTab.tabs[2].getBody(),
					items:[
						t.bWinURL = new mj.form.textField({
							title : mj.lng.objects.browseImage.url,
							labelWidth : '125px',
							id : 'url',
							width : 330
						})
					]
				});
				*/
				t.bWin.buttons[1].setHandler(t.bWinCallback, scope);
				if(!t.bWinTree.store.loaded)
					t.bWinTree.load();
				t.wins.push(t.bWin);
				t.bWin.show();
				t.bWinTree.store.on('beforeload', function(){
					t.waitMaskShow();
				},t);
				t.bWinTree.store.on('load', function(){
					t.waitMaskHide();
				},t);
				t.bWinView.store.on('beforeload', function(){
					t.waitMaskShow();
				},t);
				t.bWinView.store.on('load', function(){
					t.waitMaskHide();
				},t);
				t.waitMaskHide();
			};
			t.init._oScope = t;
			setTimeout(t.init,10);
		}else{
			t.bWin.buttons[1].setHandler(t.bWinCallback, scope);
			if(!t.bWinTree.store.loaded)
				t.bWinTree.load();
			t.wins.push(t.bWin);
			t.bWin.show();
		}
}
};

/********************************************************************
 * openWYSIWYG core functions Copyright (c) 2006 openWebWare.com
 * Contact us at devs@openwebware.com
 * This copyright notice MUST stay intact for use.
 *
 * $Id: wysiwyg.js,v 1.10 2006/12/25 09:17:07 xhaggi Exp $
 ********************************************************************/
var WYSIWYG_Core = {

	/**
	 * Holds true if browser is MSIE, otherwise false
	 */
	isMSIE: navigator.appName == "Microsoft Internet Explorer" ? true : false,

	/**
	 * Holds true if browser is Firefox (Mozilla)
	 */
	isFF: !document.all && document.getElementById && !this.isOpera,
	
	/**
	 * Holds true if browser is Opera, otherwise false
	 */
	isOpera: navigator.appName == "Opera" ? true : false,
	
	/**
	 * Trims whitespaces of the given string
	 *
	 * @param str String
	 * @return Trimmed string
	 */
	trim: function(str) {
		return str.replace(/^\s*|\s*$/g,"");
	},
	
	/**
	 * Determine if the given parameter is defined
	 * 
	 * @param p Parameter
	 * @return true/false dependents on definition of the parameter 
	 */
	defined: function(p) {
		return typeof p == "undefined" ? false : true;	
	},
	
	/**
	 * Determine if the browser version is compatible
	 *
	 * @return true/false depending on compatiblity of the browser
	 */
	isBrowserCompatible: function() {
		// Validate browser and compatiblity
		if ((navigator.userAgent.indexOf('Safari') != -1 ) || !document.getElementById || !document.designMode){   
			//no designMode (Safari lies)
	   		return false;
		} 
		return true;
	},
	
	/**
	 * Set the style attribute of the given element.
	 * Private method to solve the IE bug while setting the style attribute.
	 *
	 * @param element The element on which the style attribute will affect
	 * @param style Stylesheet which will be set
	 */
	_setStyleAttribute: function(element, style) {
		var styles = style.split(";");
		var pos;
		for(var i=0;i<styles.length;i++) {
			var attributes = styles[i].split(":");
			if(attributes.length == 2) {
				try {
					var attr = WYSIWYG_Core.trim(attributes[0]);
					while((pos = attr.search(/-/)) != -1) {
						var strBefore = attr.substring(0, pos);
						var strToUpperCase = attr.substring(pos + 1, pos + 2);
						var strAfter = attr.substring(pos + 2, attr.length);
						attr = strBefore + strToUpperCase.toUpperCase() + strAfter;
					}
					var value = WYSIWYG_Core.trim(attributes[1]).toLowerCase();
					element.style[attr] = value;
				}
				catch (e) {
					//alert(e);
				}
			}
		}
	},
	
	/**
	 * Set an attribute's value on the given node element.
	 *
	 * @param node Node element
	 * @param attr Attribute which is set
	 * @param value Value of the attribute
	 */
	setAttribute: function(node, attr, value) {
		if(value == "") {return;}
		if(attr.toLowerCase() == "style") {
			this._setStyleAttribute(node, value);
		}
		else {
			node.setAttribute(attr, value);
		}
	},
	
	/**
	 * Cancel the given event.
	 *
	 * @param e Event which will be canceled
	 */
	cancelEvent: function(e) {
		if (!e) return false;
		if (this.isMSIE) {
			e.returnValue = false;
			e.cancelBubble = true;
		} else {
			e.preventDefault();
			e.stopPropagation && e.stopPropagation();
		}
		return false;	
	},
	
	/**
	 * Converts a RGB color string to hex color string.
	 *
	 * @param color RGB color string
	 * @param Hex color string
	 */
	toHexColor: function(color) {
		color = color.replace(/^rgb/g,'');
		color = color.replace(/\(/g,'');
		color = color.replace(/\)/g,'');
		color = color.replace(/ /g,'');
		color = color.split(',');
		var r = parseFloat(color[0]).toString(16).toUpperCase();
		var g = parseFloat(color[1]).toString(16).toUpperCase();
		var b = parseFloat(color[2]).toString(16).toUpperCase();
		if (r.length<2) { r='0'+r; }
		if (g.length<2) { g='0'+g; }
		if (b.length<2) { b='0'+b; }
		return r + g + b;
	},
	
	/**
	 * Converts a decimal color to hex color string.
	 *
	 * @param Decimal color
	 * @param Hex color string
	 */
	_dec_to_rgb: function(value) {
		var hex_string = "";
		for (var hexpair = 0; hexpair < 3; hexpair++) {
			var myByte = value & 0xFF;            // get low byte
			value >>= 8;                          // drop low byte
			var nybble2 = myByte & 0x0F;          // get low nybble (4 bits)
			var nybble1 = (myByte >> 4) & 0x0F;   // get high nybble
			hex_string += nybble1.toString(16);   // convert nybble to hex
			hex_string += nybble2.toString(16);   // convert nybble to hex
		}
		return hex_string.toUpperCase();
	},
	
	/**
	 * Replace RGB color strings with hex color strings within a string.
	 * 
	 * @param {String} str RGB String
	 * @param {String} Hex color string
	 */
	replaceRGBWithHexColor: function(str) {
		// find all decimal color strings
		var matcher = str.match(/rgb\([0-9 ]+,[0-9 ]+,[0-9 ]+\)/gi);
		if(matcher) {
			for(var j=0; j<matcher.length;j++) {
				var regex = eval("/" + WYSIWYG_Core.stringToRegex(matcher[j]) + "/gi");
				// replace the decimal color strings with hex color strings
				str = str.replace(regex, "#" + this.toHexColor(matcher[j]));
			}
		}
		return str;
	},
	
	/**
	 * Execute the given command on the given editor
	 * 
	 * @param n The editor's identifier
	 * @param cmd Command which is execute
	 */
	execCommand: function(n, cmd, value) {
		if(typeof(value) == "undefined") value = null;
		
		// firefox BackColor problem fixed
		if(cmd == 'BackColor' && WYSIWYG_Core.isFF) cmd = 'HiliteColor';
		
		// firefox cut, paste and copy
		if(WYSIWYG_Core.isFF && (cmd == "Cut" || cmd == "Paste" || cmd == "Copy")) {
			try {
				WYSIWYG.getEditorWindow(n).document.execCommand(cmd, false, value);
			}
			catch(e) {
				if(confirm("Copy/Cut/Paste is not available in Mozilla and Firefox\nDo you want more information about this issue?")) {
					window.open('http://www.mozilla.org/editor/midasdemo/securityprefs.html');
				}
			}
		}
		
		else {
			WYSIWYG.getEditorWindow(n).document.execCommand(cmd, false, value);
		}
	},
	
	/**
	 * Parse a given string to a valid regular expression
	 * 
	 * @param {String} string String to be parsed
	 * @return {RegEx} Valid regular expression
	 */
	stringToRegex: function(string) {
		
		string = string.replace(/\//gi, "\\/");
		string = string.replace(/\(/gi, "\\(");
		string = string.replace(/\)/gi, "\\)");
		string = string.replace(/\[/gi, "\\[");
		string = string.replace(/\]/gi, "\\]");
		string = string.replace(/\+/gi, "\\+");
		string = string.replace(/\$/gi, "\\$");
		string = string.replace(/\*/gi, "\\*");
		string = string.replace(/\?/gi, "\\?");
		string = string.replace(/\^/gi, "\\^");
		string = string.replace(/\\b/gi, "\\\\b");
		string = string.replace(/\\B/gi, "\\\\B");
		string = string.replace(/\\d/gi, "\\\\d");
		string = string.replace(/\\B/gi, "\\\\B");
		string = string.replace(/\\D/gi, "\\\\D");
		string = string.replace(/\\f/gi, "\\\\f");
		string = string.replace(/\\n/gi, "\\\\n");
		string = string.replace(/\\r/gi, "\\\\r");
		string = string.replace(/\\t/gi, "\\\\t");
		string = string.replace(/\\v/gi, "\\\\v");
		string = string.replace(/\\s/gi, "\\\\s");
		string = string.replace(/\\S/gi, "\\\\S");
		string = string.replace(/\\w/gi, "\\\\w");
		string = string.replace(/\\W/gi, "\\\\W");
		
		return string;			
	},
	
	/**
	 * Add an event listener
	 *
	 * @param obj Object on which the event will be attached
	 * @param ev Kind of event
	 * @param fu Function which is execute on the event
	 */
	addEvent: function(obj, ev, fu) {
		if (obj.attachEvent)
			obj.attachEvent("on" + ev, fu);
		else
			obj.addEventListener(ev, fu, false);
	},
	
	/**
	 * Remove an event listener
	 *
	 * @param obj Object on which the event will be attached
	 * @param ev Kind of event
	 * @param fu Function which is execute on the event
	 */
	removeEvent:  function(obj, ev, fu) {
		if (obj.attachEvent)
			obj.detachEvent("on" + ev, fu);
		else
			obj.removeEventListener(ev, fu, false);
	},
	
	/**
	 * Includes a javascript file
	 *
	 * @param file Javascript file path and name
	 */
	includeJS: function(file) {
		var script = document.createElement("script");
		this.setAttribute(script, "type", "text/javascript");
		this.setAttribute(script, "src", file);
		var heads = document.getElementsByTagName("head");
		for(var i=0;i<heads.length;i++) {
			heads[i].appendChild(script);		
		}
	},
	
	/**
	 * Includes a stylesheet file
	 *
	 * @param file Stylesheet file path and name
	 */
	includeCSS: function(path) {
		var link = document.createElement("link");
		this.setAttribute(link, "rel", "stylesheet");
		this.setAttribute(link, "type", "text/css");
		this.setAttribute(link, "href", path);
		var heads = document.getElementsByTagName("head");
		for(var i=0;i<heads.length;i++) {
			heads[i].appendChild(link);		
		}
	},
	
	/**
	 * Get the screen position of the given element.
	 * 
	 * @param {HTMLObject} elm1 Element which position will be calculate
	 * @param {HTMLObject} elm2 Element which is the last one before calculation stops
	 * @param {Object} Left and top position of the given element
	 */
	getElementPosition: function(elm1, elm2) {
		var top = 0, left = 0; 	
		while (elm1 && elm1 != elm2) {
			left += elm1.offsetLeft;
			top += elm1.offsetTop;
			elm1 = elm1.offsetParent;
		}
		return {left : left, top : top};
	}
};

/**
 * Context menu object
 */
var WYSIWYG_ContextMenu = {
	
	html: "",
	contextMenuDiv: null,
	
	/**
	 * Init function
	 *
	 * @param {String} n Editor identifier
	 */
	init: function(n) {
		var doc = WYSIWYG.getEditorWindow(n).document;
			
		// create context menu div
		this.contextMenuDiv = document.createElement("div");
		this.contextMenuDiv.className = "wysiwyg-context-menu-div";
		this.contextMenuDiv.setAttribute("class", "wysiwyg-context-menu-div");
		this.contextMenuDiv.style.display = "none";
		this.contextMenuDiv.style.position = "absolute";
		this.contextMenuDiv.style.zindex = 1000;
		this.contextMenuDiv.style.left = "0";
		this.contextMenuDiv.style.top = "0";
		this.contextMenuDiv.unselectable = "on";		
		document.body.insertBefore(this.contextMenuDiv, document.body.firstChild);
		
		// bind event listeners
		WYSIWYG_Core.addEvent(doc, "contextmenu", function context(e) { WYSIWYG_ContextMenu.show(e, n); });
		WYSIWYG_Core.addEvent(doc, "click", function context(e) { WYSIWYG_ContextMenu.close(); });
		WYSIWYG_Core.addEvent(doc, "keydown", function context(e) { WYSIWYG_ContextMenu.close(); });
		WYSIWYG_Core.addEvent(document, "click", function context(e) { WYSIWYG_ContextMenu.close(); });
	},
	
	/**
	 * Show the context menu
	 *
	 * @param e Event
	 * @param n Editor identifier
	 */
	show: function(e, n) {
		if(this.contextMenuDiv == null) return false;
		
		var ifrm = WYSIWYG.getEditor(n);
		var doc = WYSIWYG.getEditorWindow(n).document;
	
		// set the context menu position
		var pos = WYSIWYG_Core.getElementPosition(ifrm);		
		var x = WYSIWYG_Core.isMSIE ? pos.left + e.clientX : pos.left + (e.pageX - doc.body.scrollLeft);
		var y = WYSIWYG_Core.isMSIE ? pos.top + e.clientY : pos.top + (e.pageY - doc.body.scrollTop);
					
		this.contextMenuDiv.style.left = x + "px"; 
		this.contextMenuDiv.style.top = y + "px";
		this.contextMenuDiv.style.visibility = "visible";
		this.contextMenuDiv.style.display = "block";	
		
		// call the context menu, mozilla needs some time
		window.setTimeout("WYSIWYG_ContextMenu.output('" + n + "')", 10);
			
		WYSIWYG_Core.cancelEvent(e);
		return false;
	},
	
	/**
	 * Output the context menu items
	 *
	 * @param n Editor identifier
	 */
	output: function (n) {
												
		// get selection
		var sel = WYSIWYG.getSelection(n);
		var range = WYSIWYG.getRange(sel);
	
		// get current selected node					
		var tag = WYSIWYG.getTag(range);
		if(tag == null) { return; }
		
		// clear context menu
		this.clear();
		
		// Determine kind of nodes
		var isImg = (tag.nodeName == "IMG") ? true : false;
		var isLink = (tag.nodeName == "A") ? true : false;
		
		// Selection is an image or selection is a text with length greater 0
		var len = 0;
		if(WYSIWYG_Core.isMSIE)
			len = (document.selection && range.text) ? range.text.length : 0;
		else
			len = range.toString().length;
		var sel = len != 0 || isImg;
		
		// Icons
		var iconLink = { enabled: WYSIWYG.config[n].ImagesDir + WYSIWYG.ToolbarList["createlink"][3], disabled: WYSIWYG.config[n].ImagesDir + WYSIWYG.ToolbarList["createlink"][2]};
		var iconImage = { enabled: WYSIWYG.config[n].ImagesDir + WYSIWYG.ToolbarList["insertimage"][3], disabled: WYSIWYG.config[n].ImagesDir + WYSIWYG.ToolbarList["insertimage"][2]};
		var iconDelete = { enabled: WYSIWYG.config[n].ImagesDir + WYSIWYG.ToolbarList["delete"][3], disabled: WYSIWYG.config[n].ImagesDir + WYSIWYG.ToolbarList["delete"][2]};
		var iconCopy = { enabled: WYSIWYG.config[n].ImagesDir + WYSIWYG.ToolbarList["copy"][3], disabled: WYSIWYG.config[n].ImagesDir + WYSIWYG.ToolbarList["copy"][2]};
		var iconCut = { enabled: WYSIWYG.config[n].ImagesDir + WYSIWYG.ToolbarList["cut"][3], disabled: WYSIWYG.config[n].ImagesDir + WYSIWYG.ToolbarList["cut"][2]};
		var iconPaste = { enabled: WYSIWYG.config[n].ImagesDir + WYSIWYG.ToolbarList["paste"][3], disabled: WYSIWYG.config[n].ImagesDir + WYSIWYG.ToolbarList["paste"][2]};
		
		// Create context menu html
		this.html += '<table class="wysiwyg-context-menu" border="0" cellpadding="0" cellspacing="0">';
		
		// Add items
		this.addItem(n, 'Copy', iconCopy, 'Copy', sel);
		this.addItem(n, 'Cut', iconCut, 'Cut', sel);
		this.addItem(n, 'Paste', iconPaste, 'Paste', true);
		this.addSeperator();
		this.addItem(n, 'InsertImage', iconImage, 'Modify Image Properties...', isImg);
		this.addItem(n, 'CreateLink', iconLink, 'Create or Modify Link...', sel || isLink);
		this.addItem(n, 'RemoveNode', iconDelete, 'Remove', true);
		
		this.html += '</table>';
		this.contextMenuDiv.innerHTML = this.html;
	},
	
	/**
	 * Close the context menu
	 */
	close: function() {
		this.contextMenuDiv.style.visibility = "hidden";
		this.contextMenuDiv.style.display = "none";
	},
	
	/**
	 * Clear context menu
	 */
	clear: function() {
		this.contextMenuDiv.innerHTML = "";
		this.html = "";	
	},
		
	/**
	 * Add context menu item 
	 * 
	 * @param n editor identifier
	 * @param cmd Command
	 * @param icon Icon which is diabled
	 * @param title Title of the item
	 * @param disabled If item is diabled
	 */
	addItem: function(n, cmd, icon, title, disabled) {
		var item = '';
		
		if(disabled) {
			item += '<tr>';
			item += '<td class="icon"><a href="javascript:WYSIWYG.formatText(\'' + cmd + '\',\'' + n + '\', null);"><img src="' + icon.enabled + '" border="0"></a></td>';
			item += '<td onmouseover="this.className=\'mouseover\'" onmouseout="this.className=\'\'" onclick="WYSIWYG.formatText(\'' + cmd + '\',\'' + n + '\', null);WYSIWYG_ContextMenu.close();"><a href="javascript:void(0);">' + title + '</a></td>';
			item += '</tr>';
		}
		else {
			item += '<tr>';
			item += '<td class="icon"><img src="' + icon.disabled + '" border="0"></td>';
			item += '<td onmouseover="this.className=\'mouseover\'" onmouseout="this.className=\'\'"><span class="disabled">' + title + '</span></td>';
			item += '</tr>';
		}
		
		this.html += item;
	},
	
	/**
	 * Add seperator to context menu
	 */
	addSeperator: function() {
		var output = '';
		output += '<tr>';
		output += '<td colspan="2" style="text-align:center;"><hr size="1" color="#C9C9C9" width="95%"></td>';
		output += '</tr>';
		this.html += output;
	}
};

/**
 * Get an element by it's identifier
 *
 * @param id Element identifier
 */
function $g(id) {
	return document.getElementById(id);
};

/**
 * Emulates insertAdjacentHTML(), insertAdjacentText() and 
 * insertAdjacentElement() three functions so they work with Netscape 6/Mozilla
 * by Thor Larholm me@jscript.dk
 */
if(typeof HTMLElement!="undefined" && !HTMLElement.prototype.insertAdjacentElement){
	HTMLElement.prototype.insertAdjacentElement = function (where,parsedNode) {
	  switch (where){
		case 'beforeBegin':
			this.parentNode.insertBefore(parsedNode,this);
			break;
		case 'afterBegin':
			this.insertBefore(parsedNode,this.firstChild);
			break;
		case 'beforeEnd':
			this.appendChild(parsedNode);
			break;
		case 'afterEnd':
			if (this.nextSibling) { 
				this.parentNode.insertBefore(parsedNode,this.nextSibling); 
			}
			else { 
				this.parentNode.appendChild(parsedNode); 
			}
			break;
	  }
	};

	HTMLElement.prototype.insertAdjacentHTML = function (where,htmlStr) {
		var r = this.ownerDocument.createRange();
		r.setStartBefore(this);
		var parsedHTML = r.createContextualFragment(htmlStr);
		this.insertAdjacentElement(where,parsedHTML);
	};


	HTMLElement.prototype.insertAdjacentText = function (where,txtStr) {
		var parsedText = document.createTextNode(txtStr);
		this.insertAdjacentElement(where,parsedText);
	};
	
}

mj.designer = function(config){
	mj.designer.superclass.constructor.call(this, config);
};
mj.designer.prototype = {
	componentClass : 'mj.designer',
	dataURL : '',
	textURL : '',
	showFontManager : false,
	showTags : false,
	init : function(){
		var t = this, renderTo = t.renderTo, _renderTo = t._renderTo = $(renderTo);
		window.dropEls = [];
		t.width = 800;
		t.height = 460;
		t.designSides = [];
		t.activeSide = 0;
		t.layout = new mj.layout({
			renderTo : renderTo,
			layout : 'border',
			items : [
				{
					region  : 'west',
					initial : 315
				}
			]
		});
		var _items = [
			{
				title : 'Resim',
				closable : false
			},
			{
				title : 'Yazı',
				closable : false
			}
		];
		t._sizeColorSelectable = (t.designsize&&t.designsize.length>1)||t.designcolor.length>1;
		if(t._sizeColorSelectable)
			_items.push({
					title : 'Ebat&Renk',
					closable : false
				}
			);
		t.westTabs = new mj.tab({
			renderTo : t.layout.getBody('west'),
			activeTab : 0,
			tabWidth : 90,
			border : false,
			items : _items
		});
		var wtCnt = t.westTabs.tabs[0].getBody();
		wtCnt.css('overflow', 'hidden');
		t.resimTabs = new mj.tab({
			renderTo : wtCnt,
			activeTab : 0,
			tabWidth : 103,
			tabPosition : 'bottom',
			items : [
				{
					title : 'Galeri',
					closable : false
				},
				{
					title : 'Resim Yükle',
					iconCls : 'g-upload',
					closable : false
				}
			]
		});
		var galleryTemplate = ['<div class="thumb-wrap" id="{id}">',
		'<table cellpadding="0" cellspacing="0"><tr><td align="center" valign="center" width="80px" height="80px"><img src="{url}" {widthHeight}/></td></tr></table>',
		'</div>'];
		t.imagesLayout = new mj.layout({
			renderTo : t.resimTabs.tabs[0].getBody(),
			layout : 'border',
			border : false,
			items : [
				{
					region  : 'north',
					split : true,
					collapsible : true,
					initial : 80,
					min : 60,
					max : 260
				}
			]
		});
		var cnt = $(t.imagesLayout.getBody('north'));
		cnt.addClass('combo-list');
		cnt.css({overflowY:'scroll',background:'#fff'});
		var cmbTpl = '<div class="combo-list-item mj-unselectable">{text}</div>';
		t.imagesFilter = new mj.view({
			renderTo : cnt,
			store : new mj.store({
				url : t.dataURL,
				params : {
					event : 'getTagList'
				}
			}),
			tpl : new mj.template(cmbTpl),
			selector : 'div.combo-list-item',
			overClass : 'combo-over',
			selectedClass : 'combo-selected',
			multiSelect : true,
			filter : false,
			scope : t,
			border : false
		});
		t.imagesFilter._cM = new mj.contextmenu({
			renderTo : mj.NE(),
			parent : t.imagesFilter.cnt,
			canHide : true,
			style : 'vertical',
			width : 150,
			items : [
				{
					iconCls : 'mj-warning',
					title : 'Sakıncalı içerik bildir!',
					handler : function(){
						if(t.imagesFilter.selected.length==1){
							new mj.message({
								title:'Onay',
								modal : true,
								msg:'Seçili etiketin kaldırılmasını talep etmek istediğinizden emin misiniz?',
								buttons:['YES','NO'],
								cb:function(el,btn){
									if(btn=='YES'){
										var s = [];
										for(var i=0, l=t.imagesFilter.selections.length; i<l; i++)
											s.push(t.imagesFilter.selections[i].store.id);
										t.imagesFilter.store.params = {event : 'markToCheckTerm', id : parseInt(t.imagesFilter.store.data[t.imagesFilter.sel[0].index].id)}; 
										t.imagesFilter.store.load();
										t.imagesFilter.store.params = {event : 'getTagList'};
									}
									el.window.close();
								}
							});
						}
					}
				}
			]
		});
		
		t.imagesFilter.on('itemclick', function(){
			var s = [];
			for(var i=0, l=t.imagesFilter.selections.length; i<l; i++)
				s.push(t.imagesFilter.selections[i].store.id);
			t.imagesView.store.params.tags = '('+s.join(',')+')';
			t.imagesView.store.load();
		});
		t.imagesViewPanel = new mj.panel({
			renderTo : t.imagesLayout.getBody('center'),
			border : false
		});
		t.imagesView = new mj.view({
			renderTo : t.imagesViewPanel.getBody(),
			store : new mj.store({
				url : t.dataURL,
				params : {
					event : 'getGalleryImages'
				}
			}),
			pbar : new mj.pager({
				limit:20,
				pos:'bottom',
				elements:{
					prev : true,
					next : true,
					refresh : true
				},
				pageInfo : false
			}),
			tpl : new mj.template(galleryTemplate),
			selector : 'div.thumb-wrap',
			border : false
		});
		t.imagesView.pbar.tbar.addButton({
			iconCls : 'mj-warning',
			alt : 'Sakıncalı içerik bildir!',
			handler : function(){
				if(t.imagesView.selected.length==1){
					new mj.message({
						title:'Onay',
						modal : true,
						msg:'Seçili resmin kaldırılmasını talep etmek istediğinizden emin misiniz?',
						buttons:['YES','NO'],
						cb:function(el,btn){
							if(btn=='YES'){
								var s = [];
								for(var i=0, l=t.imagesFilter.selections.length; i<l; i++)
									s.push(t.imagesFilter.selections[i].store.id);
								t.imagesView.store.params = {event : 'markToCheckPublicGalleryImage', id : parseInt(t.imagesView.store.data[t.imagesView.sel.index].id), tags : '('+s.join(',')+')'}; 
								t.imagesView.store.load();
								t.imagesView.store.params = {event : 'getGalleryImages'};
							}
							el.window.close();
						}
					});
				}
			}
		});
		if(t.isDesigner){
			t.imagesView.pbar.tbar.addButton({
				iconCls : 'mj-delete',
				alt : 'Seçili resmi sil',
				handler : function(){
					if(t.imagesView.selected.length==1){
						new mj.message({
							title:'Onay',
							modal : true,
							msg:'Seçili resmi silmek istediğinizden emin misiniz?',
							buttons:['YES','NO'],
							cb:function(el,btn){
								if(btn=='YES'){
									var s = [];
									for(var i=0, l=t.imagesFilter.selections.length; i<l; i++)
										s.push(t.imagesFilter.selections[i].store.id);
									t.imagesView.store.params = {event : 'deletePublicGalleryImage', id : parseInt(t.imagesView.store.data[t.imagesView.sel.index].id), tags : '('+s.join(',')+')'}; 
									t.imagesView.store.load();
									t.imagesView.store.params = {event : 'getGalleryImages'};
								}
								el.window.close();
							}
						});
					}
				}
			});
		}
		t.uploadedImagesPanel = new mj.panel({
			renderTo : t.resimTabs.tabs[1].getBody(),
			border : false
		});
		t.uploadedImages = new mj.view({
			renderTo : t.uploadedImagesPanel.getBody(),
			store : new mj.store({
				url : t.dataURL,
				params : {
					event : 'getUserImages'
				}
			}),
			pbar : new mj.pager({
				limit:20,
				pos:'bottom',
				elements:{
					prev : true,
					next : true,
					refresh : true
				},
				pageInfo : false
			}),
			tpl : new mj.template(galleryTemplate),
			selector : 'div.thumb-wrap',
			border : false
		});
		t.uploadedImages.pbar.tbar.addSplitter();
		t.uploadedImages.pbar.tbar.addButton({
			iconCls : 'g-upload',
			alt : 'Bilgisayarımdan resim yükle',
			title : 'Resim Yükle',
			handler : function(){
				if(!t.uploadWindow){
					t.uploadWindow = new mj.window({
						title : 'Yüklenecek Resimleri Seçin',
						width : 500,
						height : 400,
						modal : true,
						buttons : [
							{
								title  : 'Gönder',
								handler : function(){
										t.uploadWindow.waitMask = $(mj.NE(t.uploadWindow.body,{
											cls:'mj-page-wait-mask mj-opacity-8',
											style:'display:none;width:100%;height:100%;',
											html:'<table width="100%" height="100%"><tr><td align="center" valign="middle"><img src="'+mj.glb.imagePath+'ajax-loader.gif"/><br/><br/><span class="mj-page-wait-title">'+mj.lng.glb.pleaseWait+'</span></td></tr></table>'
										}));
										t.uploadWindow.waitMask.show()
										if(t.currentTags){
											var tags = [];
											for(var i=0,l=t.currentTags.length;i<l;i++)
												tags.push(t.currentTags[i].value);
										}else
											var tags = false;
										t.uploadWindow.uploadForm.setValue({'tags':tags.toJSONString(),'event':'uploadGalleryImage'});
										var btns = t.uploadWindow.buttons;
											btns[0].disable();
											btns[1].disable();
										setTimeout(function(){
											t.uploadWindow.uploadForm.submit({
												url : '/design',
												success : function(data){
													t.imagesFilter.store.load();
													t.uploadedImages.store.load();
													mj.message(data.msg);
													t.uploadWindow.waitMask.hide();
													btns[0].enable();
													btns[1].enable();
													t.uploadWindow.close();
												},
												failure : function(data){
													t.uploadWindow.waitMask.hide();
													btns[0].enable();
													btns[1].enable();
													mj.message(data.msg);
												},
												scope:this,
												encoded : true
											});
										},10);
								}
							},{
								title  : 'Vazgeç',
								handler : function(){
									t.uploadWindow.hide();
								}
							}
						]
					});
					t.uploadWindow.mask.mask.css('height', Math.max(document.body.offsetHeight,document.documentElement.scrollHeight));
					var cnt = t.uploadWindow.getBody();
					cnt = mj.NE(cnt, {style:'padding:5px;', html:"Resim yükleme talimatları..."});
					t.uploadWindow.formCnt = $(mj.NE(cnt, {style:'height:140px'}));
					if(t.showTags){
						t.tagcombo = new mj.form.combo({
							renderTo : cnt,
							title : 'Etiketler',
							mode : 'remote',
							dataIndex : 'tag',
							store : new mj.store({
								url : t.dataURL,
								params : {
									event : 'getTagList'
								}
							}),
							width : 250
						});
						t.tagcombo._el.width(340);
						t.tagcombo._el.css('float', 'left');
						t.addTagBtn = new mj.button({
							renderTo : mj.NE(cnt, {style:'padding-top:3px'}),
							title : 'Etiketi Ekle',
							handler : function(){
								var selectedId=t.tagcombo.getValue(), selectedValue = t.tagcombo.getElValue().toString().trim();
								if(selectedValue!=''){
									if(t.tagcombo.displayValue != selectedValue)
										id = '';
									if(mj.getIndex(t.currentTags, 'value', selectedValue) == -1)
										t.insertTag(selectedId, selectedValue);
									t.tagcombo.setValue();
									t.tagcombo.setElValue('');
								}
							}
						});
						t.removeTagBtn = new mj.button({
							renderTo : mj.NE(cnt, {style:'padding-top:3px'}),
							title : 'Sil',
							handler : function(){
								if(t.selectedTag){
									var tag = t.selectedTag;
									tag.selected = false;
									t.currentTags.remove(tag);
									tag.cnt.remove();
									tag = null;
									t.selectedTag = null;
									t.removeTagBtn._el.hide();
								}
							}
						});
						mj.NE(cnt, {style:'clear:both', html:'&nbsp;'});
						t.currentTags = [];
						t.tagDiv = $(mj.NE(cnt, {style:'padding:3px'}));
						t.insertTag = function(id, value){
							var index = t.currentTags.push({'id' : id, 'value' : value})-1;
							var tag = t.currentTags[index], itemCnt = tag.cnt = $(mj.NE(t.tagDiv, {cls:'tag-container', children:[
								{cls:'tag-icon',html:mj.insertSpacer(16,16)},
								{style:'float:left;', html:value}
							]}));
							itemCnt.bind('mouseover', {scope:tag}, function(e){
								var tag = e.data.scope;
								if(!tag.selected)
									tag.cnt.addClass('tag-hover');
							});
							itemCnt.bind('mouseout', {scope:tag}, function(e){
								var tag = e.data.scope;
								if(!tag.selected)
									tag.cnt.removeClass('tag-hover');
							});
							itemCnt.bind('click', {scope:tag}, function(e){
								var tag = e.data.scope;
								if(t.selectedTag){
									t.selectedTag.cnt.removeClass('tag-selected');
									t.selectedTag.selected = false;
								}
								t.selectedTag = tag;
								tag.selected = true;
								tag.cnt.removeClass('tag-hover');
								tag.cnt.addClass('tag-selected');
								t.removeTagBtn._el.show();
							});
						};
					}
				}
				if(t.removeTagBtn)
					t.removeTagBtn._el.hide();
				t.uploadWindow.formCnt.empty();
				t.uploadWindow.uploadForm = new mj.form({
					renderTo : t.uploadWindow.formCnt,
					items:[
						new mj.form.textField({
							hidden : true,
							'type' : 'hidden',
							name : 'event'
						}),
						new mj.form.textField({
							hidden : true,
							'type' : 'hidden',
							name : 'tags'
						}),
						new mj.form.fileInput({
							id:'resim',
							name : 'resim',
							maxFile : 5,
							title : 'Dosyaları Seçin',
							labelWidth : '110px'
						}),
						new mj.form.checkBox({
							labelWidth : 160,
							title : 'Bu resim genel galeriye eklenebilir',
							name : 'uploadAgreementCheck',
							itemStyle : 'padding-top:75px;'
						})
					]
				});
				mj.NE(t.uploadWindow.uploadForm.items[2].input.parent(), {style:'clear:both', html:'&nbsp'});
				t.currentTags = [];
				if(t.tagDiv)
					t.tagDiv.empty();
				t.uploadWindow.show();
			}
		});
		t.uploadedImages.pbar.tbar.addButton({
			iconCls : 'mj-delete',
			alt : 'Seçili resmimi sil',
			title : 'Sil',
			handler : function(){
				if(t.uploadedImages.selected.length>0){
					var p = t.uploadedImages.store.params;
					t.uploadedImages.store.params = {event:'deleteGalleryImage',id:t.uploadedImages.items[t.uploadedImages.selected[0].index].store.id};
					t.uploadedImages.store.load();
					t.uploadedImages.store.params = p;
				}
			}
		});
		t.centerLayoutPanel = new mj.panel({
			renderTo : t.layout.getBody('center'),
			border : false
		});
		t.centerLayout = new mj.layout({
			renderTo : t.centerLayoutPanel.getBody(),
			layout : 'border',
			border : false,
			items : [
				{
					region : 'south',
					initial : 27
				}
			]
		});
		t.bbar =  new mj.menu({
			renderTo:t.centerLayout.getBody('south'),
			items: [
				{id:'btnfront' ,iconCls:'g-bringtofront',handler:function(){
					if(t.selectedItem){
						var selectedIndex = t.selectedItem.zIndex;
						var next = mj.getIndex(t.designSides[t.activeSide].designElements, 'zIndex', selectedIndex+1);
						if(next>-1){
							t.designSides[t.activeSide].designElements[next].zIndex = selectedIndex;
							t.designSides[t.activeSide].designElements[next].cnt.css('z-index', selectedIndex);
							t.selectedItem.zIndex += 1;
							t.selectedItem.cnt.css('z-index', t.selectedItem.zIndex);
						}
					}
				},alt:'Üste getir'},
				{id:'btnback' ,iconCls:'g-sendtoback',handler:function(){
					if(t.selectedItem){
						var selectedIndex = t.selectedItem.zIndex;
						if(selectedIndex>0){
							var next = mj.getIndex(t.designSides[t.activeSide].designElements, 'zIndex', selectedIndex-1);
							if(next>-1){
								t.designSides[t.activeSide].designElements[next].zIndex = selectedIndex;
								t.designSides[t.activeSide].designElements[next].cnt.css('z-index', selectedIndex);
								t.selectedItem.zIndex -= 1;
								t.selectedItem.cnt.css('z-index', t.selectedItem.zIndex);
							}
						}
					}
				},alt:'Alta gönder'},
				{id:'btnaligncenter' ,iconCls:'mj-align-center',handler:function(){
					if(t.selectedItem){
						var nL = parseInt((t.designSides[t.activeSide].mWidth-t.selectedItem.area.width)/2);
						t.selectedItem.area.left = nL;
						t.selectedItem.cnt.css('left', nL+'px');
					}
				},alt:'Yatay ortala'},
				{id:'btnalignmiddle' ,iconCls:'mj-align-middle',handler:function(){
					if(t.selectedItem){
						var nT = parseInt((t.designSides[t.activeSide].mHeight-t.selectedItem.area.height)/2);
						t.selectedItem.area.top = nT;
						t.selectedItem.cnt.css('top', nT+'px');
					}
				},alt:'Dikey ortala'},
				{id:'btndelete' ,iconCls:'mj-delete',handler:function(){
					if(t.selectedItem){
						var selectedIndex = t.selectedItem.zIndex;
						if(selectedIndex>-1){
							t.designSides[t.activeSide].designElements.remove(t.selectedItem);
							t.selectedItem.cnt.remove();
							t.selectedItem = null;
							for(var i=0,l=t.designSides[t.activeSide].designElements.length; i<l; i++){
								if(t.designSides[t.activeSide].designElements[i].zIndex > selectedIndex){
									t.designSides[t.activeSide].designElements[i].zIndex = t.designSides[t.activeSide].designElements[i].zIndex-1;
									t.designSides[t.activeSide].designElements[i].cnt.css('z-index', t.designSides[t.activeSide].designElements[i].zIndex);
								}
							}
							t.z--;
							t.calcPrice();
						}
					}
				},alt:'Sil'},
				'|',
				{
					id:'btnfinish', iconCls:'g-accept', title:'&nbsp;Kaydet', alt:'Tasarımı Kaydet', handler:function(){
						var elements = [];
						for(var i=0, l=t.designSides.length;i<l;i++){
							var side = t.designSides[i];
							for(var j=0, sideElLength=side.designElements.length;j<sideElLength;j++){
								var item = side.designElements[j];
								elements.push({
									designSideId : side.designSideId,
									itemId : item.elementId,
									pTop : item.area.top,
									pLeft : item.area.left,
									width : item.area.width,
									height : item.area.height,
									zIndex : item.zIndex,
									fontId : item.font,
									text : item.text,
									cR : item.color.r,
									cG : item.color.g,
									cB : item.color.b,
									scale : side.scale
								});
							}
						}
						var cnt = $(mj.NE(mj.bd, {style:'display:none'}));
						var mask = new mj.mask({zIndex:15});
						mask.mask.css('height', Math.max(document.body.offsetHeight,document.documentElement.scrollHeight));
						var infoDiv = $(mj.NE(mj.bd,{
							style : 'position:absolute;left:50%;top:50%;margin-left:-125px;mergin-top:-21px;width:250px;height:100px;z-index:16;background:#FFFFFF;border:2px dashed #20558A;padding:10px;font-family:Verdana;font-size:12px;',
							children : [
								{tag:'img', src:t.ajaxIndicator, style:'float:left'},
								{html:'Tasarımınız hazırlanıyor. Lütfen bekleyin. Bu işlem bir kaç dakika sürebilir. <br/><span style="color:#A7170A;font-weight:bold;">Not: Tasarımınız hazırlandıktan sonra otomatik olarak sepetinize eklenecektir.</span>', style:'float:left;width:200px;margin-left:10px;'}
							]
						}));
						mask.show(15);
						mj.load(cnt, {
							url : t.dataURL,
							params : {
								event : 'saveDesign',
								designItemId : t.designItemId,
								elements : elements.toJSONString(),
								size : t._sizeColorSelectable && t.sizeForm ? (t.sizeForm.getValue()).size : t.designsize[0].id,
								color : t._sizeColorSelectable && t.colorView && t.colorView.selections ? t.colorView.selections[0].store.id : t.designcolor[0].id
							},
							callback : function(data){
								data = eval(data);
								t.trigger('save', data.id);
								cnt.remove();
								infoDiv.remove();
								mask.destroy();
							},
							dataType : 'json'
						});
					}
				},
				{
					id:'btncancel', iconCls:'g-cancel', title:'&nbsp;Vazgeç', alt:'Tasarımı kaydetmeden çık', handler:function(){
						document.location.href = "/";
					}
				}
			]
		});
		t.priceEl = $(mj.NE(t.bbar.el, {html:'Fiyat: TL', cls:'mj-page-before-text mj-unselectable', style:'float:right;padding-bottom:5px;padding-top:5px;text-align:right;cursor:default;'}));
		t.z = 0;

		t.imagesView.store.on('load', function(){
			for(var i=0, l=t.imagesView.items.length;i<l;i++){
				var dragItem = t.imagesView.items[i];
				dragItem.drag = new mj.drag({el:dragItem.el,parent : mj.bd,position:'absolute',appendParent:true, moving:false});
				$(dragItem.el).css('position', 'relative');
				dragItem.drag.on('dragstop',function(e,toW,fromW){
					var dragItem = this, data=dragItem.store;
					t.addGalleryImage({elementId:data.id, src : data.url, area:{top:0, left:0, width:data.width, height:data.height, maxWidth:data.width, maxHeight:data.height}}, t.activeSide);
				}, dragItem);
			}
		});
		t.uploadedImages.store.on('load', function(){
			for(var i=0, l=t.uploadedImages.items.length;i<l;i++){
				var dragItem = t.uploadedImages.items[i];
				dragItem.drag = new mj.drag({el:dragItem.el,parent : mj.bd,position:'absolute',appendParent:true, moving:false});
				$(dragItem.el).css('position', 'relative');
				dragItem.drag.on('dragstop',function(e,toW,fromW){
					var dragItem = this, data=dragItem.store;
					t.addGalleryImage({elementId:data.id, src : data.url, area:{top:0, left:0, width:data.width, height:data.height, maxWidth:data.width, maxHeight:data.height}}, t.activeSide);
				}, dragItem);
			}
		});
		t.textLayoutPanel = new mj.panel({
			renderTo : t.westTabs.tabs[1].getBody()
		});
		t.textLayout = new mj.layout({
			renderTo : t.textLayoutPanel.getBody(),
			layout : 'border',
			items : [
				{
					region  : 'north',
					split : false,
					collapsible : false,
					initial : 50/* ,
					min : 50,
					max : 50 */
				}
			]
		});
		var cnt = $(t.textLayout.getBody('north'));
		cnt.css({background:'#fff',paddingLeft:'7px'});
		t.textForm = new mj.form({
			renderTo : cnt,
			items:[
				new mj.form.textField({
					hidden : true,
					'type' : 'hidden',
					name : 'event'
				}),
				new mj.form.textField({
					hidden : true,
					'type' : 'hidden',
					name : 'font'
				}),
				new mj.form.textField({
					hidden : true,
					'type' : 'hidden',
					name : 'fontcolor',
					id : 'fontcolor'
				}),
				new mj.form.textField({
					name : 'text',
					title : 'Eklemek istediğiniz metni girin',
					labelWidth : '240px',
					width : 230
				})
			]
		});
		t.textForm.items[3].input.css({marginTop:2});
		cnt = t.textForm.items[3]._el;
		window.pickColor = function(a){
			return true;
		};
		mj.NE(cnt, {
			tag : 'a',
			rel : 'colorpicker&objcode=fontcolor&objshow=showcolor&showrgb=1&okfunc=pickColor',
			style : 'text-decoration:none;',
			children : [
				{id:'showcolor', style:'margin:2px;width:20px;height:20px;border:1px solid #C6C6C6;background:#fff;float:left;cursor:pointer;', html:mj.insertSpacer(22,22), title:'Renk seçmek için tıklayın'}
			]
		});
		$.ColorPicker.init();
		var _r=30,_g=135,_b=178;
		$.ColorPicker.currentColor = {r: _r, g: _g, b: _b};
		jQuery('#showcolor').css("background-color", 'rgb(' + _r + ',' + _g + ',' + _b + ')');
		t.addTextBtn = new mj.button({
			renderTo : mj.NE(cnt),
			title : 'Ekle',
			handler : function(){
				var text = t.textForm.items[3].getValue();
				if(!text || text.toString().trim() == "")
					mj.message("Lütfen eklemek istediğiniz metni girin!");
				else if(!t.textView.selections || !t.textView.selections[0] || t.textView.selections[0].store.id<1)
					mj.message("Lütfen yazı tipini seçin!");
				else{
					var c = $.ColorPicker.currentColor, fontId = t.textView.selections[0].store.id;
					var dragItem = this, data=dragItem.store, maxWidth = t.designSides[t.activeSide].designitem.area.width, maxHeight = t.designSides[t.activeSide].designitem.area.height;
					var cnt = $(mj.NE(mj.bd, {style:'display:none'}));
					mj.load(cnt, {
						url : t.textURL,
						params : {
							t : text,
							f : fontId,
							w : maxWidth,
							h : maxHeight,
							r : c.r,
							g : c.g,
							b : c.b,
							c : 1,
							m : 1
						},
						callback : function(data){
							var textItem = $('img', cnt)[0], dataarr = data.split('|');
							if(dataarr && dataarr.length==3 && parseInt(dataarr[0])>0){
								var maxWidth = dataarr[0], maxHeight = dataarr[1];
								t.addText.call(t, {src : t.textURL+'?t='+mj.escape(text)+'&f='+fontId+'&h='+maxHeight+'&w='+maxWidth+'&r='+c.r+'&g='+c.g+'&b='+c.b+'&m=1', area:{top:0, left:0, width:maxWidth, height:maxHeight, maxWidth:maxWidth, maxHeight:maxHeight}, text:text,font:fontId,color:{r:c.r,g:c.g,b:c.b}}, t.activeSide);
								t.textForm.items[3].clear();
							}
						}
					});
					cnt.remove();
				}
			}
		});
		cnt = t.textLayout.getBody('center');
		var fontTemplate = ['<div class="thumb-wrap" id="{id}" title="{fontname}">',
		'<table cellpadding="0" cellspacing="0"><tr><td align="center" valign="center" width="175px"><img src="{url}" width="{width}px"/></td></tr></table>',
		'</div>'];
		t.textViewPanel = new mj.panel({
			renderTo : t.textLayout.getBody('center')
		});
		t.textView = new mj.view({
			renderTo : t.textViewPanel.getBody(),
			store : new mj.store({
				url : t.dataURL,
				params : {
					event : 'getFonts'
				}
			}),
			pbar : new mj.pager({
				limit:20,
				pos:'bottom',
				elements:{
					prev : true,
					next : true,
					refresh : true
				},
				pageInfo : false
			}),
			tpl : new mj.template(fontTemplate),
			selector : 'div.thumb-wrap'
		});
		t.textView.pbar.tbar.addSplitter();
		if(t.showFontManager){
			t.textView.pbar.tbar.addButton({
				iconCls : 'g-upload-font',
				handler : function(){
					if(!t.uploadFontWindow){
						t.uploadFontWindow = new mj.window({
							title : 'Yüklenecek Yazı Tiplerini Seçin',
							width : 400,
							height : 250,
							modal : true,
							buttons : [
								{
									title  : 'Gönder',
									handler : function(){
										t.uploadFontWindow.uploadForm.setValue({'event':'uploadFont'});
										t.uploadFontWindow.uploadForm.submit({
											url : '/design',
											success : function(data){
												t.textView.store.load();
												mj.message(data.msg);
												t.uploadFontWindow.close();
											},
											failure : function(data){
												mj.message(data.msg);
											},
											scope:this,
											encoded : true
										});
									}
								},{
									title  : 'Vazgeç',
									handler : function(){
										t.uploadFontWindow.hide();
									}
								}
							]
						});
						var cnt = t.uploadFontWindow.getBody();
						cnt = mj.NE(cnt, {style:'padding:5px;', html:"Yazı tipi yükleme talimatları..."});
						t.uploadFontWindow.formCnt = $(mj.NE(cnt, {style:'height:120px'}));
					}
					t.uploadFontWindow.formCnt.empty();
					t.uploadFontWindow.uploadForm = new mj.form({
						renderTo : t.uploadFontWindow.formCnt,
						items:[
							new mj.form.textField({
								hidden : true,
								'type' : 'hidden',
								name : 'event'
							}),
							new mj.form.fileInput({
								id:'font',
								name : 'font',
								maxFile : 5,
								title : 'Dosyaları Seçin',
								labelWidth : '110px'
							})
						]
					});
					t.uploadFontWindow.show();
				}
			});
			t.textView.pbar.tbar.addButton({
				iconCls : 'g-delete-font',
				handler : function(){
					if(t.textView.selections && t.textView.selections[0] && t.textView.selections[0].store.id>0){
						t.textView.store.params.event = 'deleteFont';
						t.textView.store.params.font = t.textView.selections[0].store.id;
						t.textView.store.load();
						t.textView.store.params.event = 'getFonts';
					}
				}
			});
		}
		if(t.sides.length>0){
			var sides = [];
			for(var i=0,l=t.sides.length; i<l; i++)
				sides.push({title: t.sides[i].title, closable:false});
			t.designSideTabs = new mj.tab({
				renderTo : t.centerLayout.getBody('center'),
				activeTab : 0,
				tabWidth : 120,
				items : sides
			});
			t.designSideTabs.on('tabchange', function(tab, newtab, oldtab){
				t.clearSelection();
				t.activeSide = newtab;
			});
			for(var i=0,l=t.sides.length; i<l; i++){
				var cnt = t.designSideTabs.tabs[i].getBody().css('overflow', 'hidden'), s = t.sides[i];
				cnt = $((new mj.panel({
					renderTo : cnt
				})).getBody()).css('overflow', 'hidden');
				var dA = $(mj.NE(cnt, {style:'background:white;width:'+(t.width-219)+'px;height:'+(t.height-57)+'px;position:relative;overflow:hidden'}));
				t.designSides.push({designSideId: s.designSideId, designElements:[], designArea: dA, scale:s.scale});
				t.setDesignItem({src : s.src, area:{top:s.area.top, left:s.area.left, width:s.area.width, height:s.area.height}, borderWidth:s.borderWidth, colors:{border:s.colors.border,selected:s.colors.selected,hover:s.colors.hover}}, i);
				/*
				dA.bind('scroll', function(){
					dA.trigger('contextmenu');
				}).bind('contextmenu', function(e){
					e.preventDefault();
				});
				*/
			}
		}
		t.designPhotoStore = new mj.store({data:t.designphoto});
		t.designPhotoStore.load();
		if(t._sizeColorSelectable){
			var cnt = $((new mj.panel({
				renderTo : t.westTabs.tabs[2].getBody()
			})).getBody());
			if(t.designsize&&t.designsize.length>1){
				t.sizeForm = new mj.form({
					renderTo : mj.NE(cnt, {style:'padding:3px'}),
					items : [
						t.sizeRadio = new mj.form.radio({
							title : 'Ebat',
							dataIndex : 'size',
							items : t.designsize
						})
					]
				});
				t.sizeRadio.setValue(t.designsize[0].id);
			}
			if(t.designcolor.length>1){
				var colorTemplate = [
					'<div class="thumb-wrap" id="{id}">',
					'<table cellpadding="0" cellspacing="0"><tr><td align="center" valign="center" width="80px" height="100px"><img src="{src}" width="80px"/><br/>',
					'<div style="width:10px;height:10px;background:{color};float:left;border:1px solid #808080;margin-top:2px">',
					mj.insertSpacer(10,10),
					'</div>',
					'{title}</td></tr></table>',
					'</div>'
				];
				t.colorView = new mj.view({
					renderTo : mj.NE(cnt, {style:'padding:3px'}),
					store : t.designcolor,
					tpl : new mj.template(colorTemplate),
					selector : 'div.thumb-wrap'
				});
				t.colorView.load();
				t.colorView.on('itemclick', function(){
					t.setColor.call(t, t.colorView.selections[0].store);
				});
				t.colorView.select(0);
				t.setColor.call(t, t.colorView.selections[0].store);
			}else
				t.setColor(t.designcolor[0]);
				//t.colorView.select(0);
		}else
			t.setColor(t.designcolor[0]);
		t.imagesFilter.store.load();
		t.textView.store.load();
	},
	calcPrice : function(){
		var t=this;
		t.total=t.price;
		for(var i=0,l=t.designSides.length;i<l;i++){
			for(var j=0,jl=t.designSides[i].designElements.length;j<jl;j++){
				t.total += j==0 ? t.sides[i].priceAdd : 0;
				t.total += typeof t.designSides[i].designElements[j].font!='undefined' ? t.sides[i].pricePerText : t.sides[i].pricePerItem;
			}
		}
		t.priceEl.attr('title', t.total+' TL');
		t.priceEl[0].innerHTML = 'Fiyat: '+mj.format.float2Money(t.total,2,',','.')+' TL&nbsp;';
	},
	setDesignItem : function(designitem, side){
		var t = this;
		t.designSides[side].designitem = designitem;
		t.designSides[side].designitem.area.top -= t.designSides[side].designitem.borderWidth;
		t.designSides[side].designitem.area.left -= t.designSides[side].designitem.borderWidth;
		t.designSides[side].designBackground = $(mj.NE(t.designSides[side].designArea, {tag:'img', style:'position:absolute;', src:t.designSides[side].designitem.src}));
		t.designSides[side].designSpace = $(mj.NE(t.designSides[side].designArea, {tag:'div', style:'position:absolute;top:'+t.designSides[side].designitem.area.top+'px;left:'+t.designSides[side].designitem.area.left+'px;width:'+t.designSides[side].designitem.area.width+'px;height:'+t.designSides[side].designitem.area.height+'px;border:'+t.designSides[side].designitem.borderWidth+'px dashed '+t.designSides[side].designitem.colors.border,html:'&nbsp;'}));
		t.designSides[side].mWidth = t.designSides[side].designitem.area.width;
		t.designSides[side].mHeight = t.designSides[side].designitem.area.height;
		window.dropEls.push(t.designSides[side].designSpace);
		$(t.designSides[side].designSpace).bind('mousedown', function(){
			t.clearSelection();
		});
		t.imagesView.store.params.width = t.designSides[side].designitem.area.width;
		t.imagesView.store.params.height = t.designSides[side].designitem.area.height;
		t.uploadedImages.store.params.width = t.designSides[side].designitem.area.width;
		t.uploadedImages.store.params.height = t.designSides[side].designitem.area.height;
		t.uploadedImages.store.load();
		t.calcPrice();
	},
	setColor : function(color){
		var t = this;
		for(var i=0,l=t.designSides.length; i<l; i++){
			var side = t.designSides[i];
			t.designPhotoStore.filter('designColorId', color.id.toString());
			t.designPhotoStore.filter('designSideId', side.designSideId.toString(), true);
			var scd = t.designPhotoStore.data[0];
			side.designBackground.attr('src', scd.src);
			side.designSpace.css({
				borderWidth:scd.borderWidth,
				borderColor:scd.borderColor
			});
			side.designitem.colors = {
				border:scd.borderColor,
				selected:scd.selectedColor,
				hover:scd.hoverColor
			};
		}
	},
	clearSelection : function(){
		if(this.selectedItem){
			this.selectedItem.border.css('border-color', 'transparent');
			this.selectedItem.selected = false;
			this.selectedItem = null;
		}
	},
	addItem : function(item, side){
		var t=this, dE=t.designSides[side].designElements;
		var l = dE.push(item);
		item = dE[l-1];
		item.zIndex = t.z++;
		item.cnt = $(mj.NE(t.designSides[side].designSpace, {style:'position:absolute;z-index:'+item.zIndex+';top:'+item.area.top+'px;left:'+item.area.left+'px;width:'+item.area.width+'px;height:'+item.area.height+'px;'}));
		item.border = $(mj.NE(item.cnt, {style:'border-color:transparent;border-style:dashed;border-width:1px;position:absolute;width:'+item.area.width+'px;height:'+item.area.height+'px;'}));
		item.img = $(mj.NE(item.cnt, {tag:'img', src:item.src, style:'width:'+item.area.width+'px;height:'+item.area.height+'px;'}));
		item.cnt.bind('mouseover', {scope:item}, function(e){
			var item = e.data.scope;
			if(!item.selected)
				item.border.css('border-color', t.designSides[side].designitem.colors.hover);
		});
		item.cnt.bind('mouseout', {scope:item}, function(e){
			var item = e.data.scope;
			if(!item.selected)
				item.border.css('border-color', 'transparent');
		});
		item.cnt.bind('click',{scope:item},function(e){
			var item = e.data.scope;
			//t.clearSelection();
			t.selectedItem = item;
			item.selected = true;
			item.border.css('border-color', t.designSides[side].designitem.colors.selected);
		});
		item.resizer = new mj.resizer({
			el : item.cnt,
			proxy : true,
			keepAspectRatio : true,
			maxWidth : item.area.maxWidth,
			maxHeight : item.area.maxHeight,
			parentBorders : {
				maxWidth : t.designSides[side].mWidth,
				maxHeight : t.designSides[side].mHeight
			}
		});
		item.resizer.se.on('resize', function(d,width,height){
			item.area.width = width;
			item.area.height = height;
		});
		item.dragger = new mj.drag({
			el : item.cnt,
			dragEl : $.browser.msie ? item.img : item.border,
			parent : t.designSides[side].designSpace,
			resizer : item.resizer
		});
		item.dragger.on('dragafterstop', function(){
			item.area.left = parseInt(item.dragger._el.css('left'));
			item.area.top = parseInt(item.dragger._el.css('top'));
		});
		item.cnt.bind('resize', {scope:item}, function(e){
			var item = e.data.scope, w = item.cnt.width(), h = item.cnt.height();
			item.img.width(w);
			item.img.height(h);
			item.border.width(w);
			item.border.height(h);
		});
		t.calcPrice();
	},
	addGalleryImage : function(item, side){
		item.color = {};
		this.addItem(item, side);
	},
	addText : function(item, side){
		this.addItem(item, side);
	}
};
mj.extend(mj.designer, mj.component);
mj.version='v0.8-b2941';
