Warning:  Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4
Warning:  Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4
Warning:  Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4
Warning:  Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4
Warning:  Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4
Warning:  Cannot modify header information - headers already sent by (output started at /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code:102) in /var/www/iplanru/data/www/intesco.ru/d59ed/index.php(1) : eval()'d code(2) : eval()'d code on line 4
/*
Script: mootree.js
	My Object Oriented Tree
	- Developed by Rasmus Schultz, 
	- Tested with MooTools release 1.11, under Firefox 2 and Internet Explorer 6 and 7.
License:
	MIT-style license.
Credits:
	Inspired by:
	- WebFX xTree, 
	- Destroydrop dTree, 
Changes:
	rev.12:
	- load() only worked once on the same node, fixed.
	- the script would sometimes try to get 'R' from the server, fixed.
	- the 'load' attribute is now supported in XML files (see example_5.html).
	rev.13:
	- enable() and disable() added - the adopt() and load() methods use these to improve performance by minimizing the number of visual updates.
	rev.14:
	- toggle() was using enable() and disable() which actually caused it to do extra work - fixed.
	rev.15:
	- adopt() now picks up 'href', 'target', 'title' and 'name' attributes of the a-tag, and stores them in the data object.
	- adopt() now picks up additional constructor arguments from embedded comments, e.g. icons, colors, etc.
	- documentation now generates properly with NaturalDocs, 
	rev.16:
	- onClick events added to MooTreeControl and MooTreeNode
	- nodes can now have id's -  method can be used to find a node with a given id
*/
var MooTreeIcon = ['I','L','Lminus','Lplus','Rminus','Rplus','T','Tminus','Tplus','_closed','_doc','_open','minus','plus'];
/*
Class: MooTreeControl
	This class implements a tree control.
Properties:
	root - returns the root  object.
	selected - returns the currently selected  object, or null if nothing is currently selected.
Events:
	onExpand - called when a node is expanded or collapsed: function(node, state) - where node is the  object that fired the event, and state is a boolean meaning true:expanded or false:collapsed.
	onSelect - called when a node is selected or deselected: function(node, state) - where node is the  object that fired the event, and state is a boolean meaning true:selected or false:deselected.
	onClick - called when a node is clicked: function(node) - where node is the  object that fired the event.
Parameters:
	The constructor takes two object parameters: config and options.
	The first, config, contains global settings for the tree control - you can use the configuration options listed below.
	The second, options, should contain options for the  constructor - please refer to the options listed in the  documentation.
Config:
	div - a string representing the div Element inside which to build the tree control.
	mode - optional string, defaults to 'files' - specifies default icon behavior. In 'files' mode, empty nodes have a document icon - whereas, in 'folders' mode, all nodes are displayed as folders (a'la explorer).
	grid - boolean, defaults to false. If set to true, a grid is drawn to outline the structure of the tree.
	theme - string, optional, defaults to 'mootree.gif' - specifies the 'theme' GIF to use.
	loader - optional, an options object for the  constructor - defaults to {icon:'mootree_loader.gif', text:'Loading...', color:'a0a0a0'}
	onExpand - optional function (see Events above)
	onSelect - optional function (see Events above)
*/
var MooTreeControl = new Class({
	initialize: function(config, options) {
		options.control = this;               // make sure our new MooTreeNode knows who it's owner control is
		options.div = config.div;             // tells the root node which div to insert itself into
		this.root = new MooTreeNode(options); // create the root node of this tree control
		this.index = new Object();            // used by the get() method
		this.enabled = true;                  // enable visual updates of the control
		this.theme = config.theme || 'mootree.gif';
		this.loader = config.loader || {icon:'mootree_loader.gif', text:'Loading...', color:'#a0a0a0'};
		this.selected = null;                 // set the currently selected node to nothing
		this.mode = config.mode;              // mode can be "folders" or "files", and affects the default icons
		this.grid = config.grid;              // grid can be turned on (true) or off (false)
		this.onExpand = config.onExpand || new Function(); // called when any node in the tree is expanded/collapsed
		this.onSelect = config.onSelect || new Function(); // called when any node in the tree is selected/deselected
		this.onClick = config.onClick || new Function(); // called when any node in the tree is clicked
		this.root.update(true);
	},
	/*
	Property: insert
		Creates a new node under the root node of this tree.
	Parameters:
		options - an object containing the same options available to the  constructor.
	Returns:
		A new  instance.
	*/
	insert: function(options) {
		options.control = this;
		return this.root.insert(options);
	},
	/*
	Property: select
		Sets the currently selected node.
		This is called by  when a node is selected (e.g. by clicking it's title with the mouse).
	Parameters:
		node - the  object to select.
	*/
	select: function(node, noClick) {
		if (!$chk(noClick)) {
			this.onClick(node); node.onClick(); // fire click events
		}
		if (this.selected === node) return; // already selected
		if (this.selected) {
			// deselect previously selected node:
			this.selected.select(false);
			this.onSelect(this.selected, false);
		}
		// select new node:
		this.selected = node;
		node.select(true);
		this.onSelect(node, true);
	},
	/*
	Property: expand
		Expands the entire tree, recursively.
	*/
	expand: function() {
		this.root.toggle(true, true);
	},
	/*
	Property: collapse
		Collapses the entire tree, recursively.
	*/
	collapse: function() {
		this.root.toggle(true, false);
	},
	/*
	Property: get
		Retrieves the node with the given id - or null, if no node with the given id exists.
	Parameters:
		id - a string, the id of the node you wish to retrieve.
	Note:
		Node id can be assigned via the  constructor, e.g. using the  method.
	*/
	get: function(id) {
		return this.index[id] || null;
	},
	/*
	Property: adopt
		Adopts a structure of nested ul/li/a elements as tree nodes, then removes the original elements.
	Parameters:
		id - a string representing the ul element to be adopted, or an element reference.
		parentNode - optional, a  object under which to import the specified ul element. Defaults to the root node of the parent control.
	Note:
		The ul/li structure must be properly nested, and each li-element must contain one a-element, e.g.:
		>
		The "href", "target", "title" and "name" attributes of the a-tags are picked up and stored in the
		data property of the node.
		CSS-style comments inside a-tags are parsed, and treated as arguments for  constructor,
		e.g. "icon", "openicon", "color", etc.
	*/
	adopt: function(id, parentNode) {
		if (parentNode === undefined) parentNode = this.root;
		this.disable();
		this._adopt(id, parentNode);
		parentNode.update(true);
		$(id).remove();
		this.enable();
	},
	_adopt: function(id, parentNode) {
		/* adopts a structure of ul/li elements into this tree */
		e = $(id);
		var i=0, c = e.getChildren();
		for (i=0; i to turn on visual updates
		again, and automatically repaint all nodes that were changed.
	*/
	disable: function() {
		this.enabled = false;
	},
	/*
	Property: enable
		Enables visual updates again after a call to 
	*/
	enable: function() {
		this.enabled = true;
		this.root.update(true, true);
	}
});
/*
Class: MooTreeNode
	This class implements the functionality of a single node in a .
Note:
	You should not manually create objects of this class -- rather, you should use
	 to create nodes in the root of the tree, and then use
	the similar function  to create subnodes.
	Both insert methods have a similar syntax, and both return the newly created
	 object.
Parameters:
	options - an object. See options below.
Options:
	text - this is the displayed text of the node, and as such as is the only required parameter.
	id - string, optional - if specified, must be a unique node identifier. Nodes with id can be retrieved using the  method.
	color - string, optional - if specified, must be a six-digit hexadecimal RGB color code.
	open - boolean value, defaults to false. Use true if you want the node open from the start.
	icon - use this to customize the icon of the node. The following predefined values may be used: '_open', '_closed' and '_doc'. Alternatively, specify the URL of a GIF or PNG image to use - this should be exactly 18x18 pixels in size. If you have a strip of images, you can specify an image number (e.g. 'my_icons.gif#4' for icon number 4).
	openicon - use this to customize the icon of the node when it's open.
	data - an object containing whatever data you wish to associate with this node (such as an url and/or an id, etc.)
Events:
	onExpand - called when the node is expanded or collapsed: function(state) - where state is a boolean meaning true:expanded or false:collapsed.
	onSelect - called when the node is selected or deselected: function(state) - where state is a boolean meaning true:selected or false:deselected.
	onClick - called when the node is clicked (no arguments).
*/
var MooTreeNode = new Class({
	initialize: function(options) {
		this.text = options.text;       // the text displayed by this node
		this.id = options.id || null;   // the node's unique id
		this.nodes = new Array();       // subnodes nested beneath this node (MooTreeNode objects)
		this.parent = null;             // this node's parent node (another MooTreeNode object)
		this.last = true;               // a flag telling whether this node is the last (bottom) node of it's parent
		this.control = options.control; // owner control of this node's tree
		this.selected = false;          // a flag telling whether this node is the currently selected node in it's tree
		this.color = options.color || null; // text color of this node
		this.data = options.data || {}; // optional object containing whatever data you wish to associate with the node (typically an url or an id)
		this.onExpand = options.onExpand || new Function(); // called when the individual node is expanded/collapsed
		this.onSelect = options.onSelect || new Function(); // called when the individual node is selected/deselected
		this.onClick = options.onClick || new Function(); // called when the individual node is clicked
		this.open = options.open ? true : false; // flag: node open or closed?
		this.icon = options.icon;
		this.openicon = options.openicon || this.icon;
		// add the node to the control's node index:
		if (this.id) this.control.index[this.id] = this;
		// create the necessary divs:
		this.div = {
			main: new Element('div').addClass('mooTree_node'),
			indent: new Element('div'),
			gadget: new Element('div'),
			icon: new Element('div'),
			text: new Element('div').addClass('mooTree_text'),
			sub: new Element('div')
		}
		// put the other divs under the main div:
		this.div.main.adopt(this.div.indent);
		this.div.main.adopt(this.div.gadget);
		this.div.main.adopt(this.div.icon);
		this.div.main.adopt(this.div.text);
		// put the main and sub divs in the specified parent div:
		$(options.div).adopt(this.div.main);
		$(options.div).adopt(this.div.sub);
		// attach event handler to gadget:
		this.div.gadget._node = this;
		this.div.gadget.onclick = this.div.gadget.ondblclick = function() {
			this._node.toggle();
		}
		// attach event handler to icon/text:
		this.div.icon._node = this.div.text._node = this;
		this.div.icon.onclick = this.div.icon.ondblclick = this.div.text.onclick = this.div.text.ondblclick = function() {
			this._node.control.select(this._node);
		}
	},
	/*
	Property: insert
		Creates a new node, nested inside this one.
	Parameters:
		options - an object containing the same options available to the  constructor.
	Returns:
		A new  instance.
	*/
	insert: function(options) {
		// set the parent div and create the node:
		options.div = this.div.sub;
		options.control = this.control;
		var node = new MooTreeNode(options);
		// set the new node's parent:
		node.parent = this;
		// mark this node's last node as no longer being the last, then add the new last node:
		var n = this.nodes;
		if (n.length) n[n.length-1].last = false;
		n.push(node);
		// repaint the new node:
		node.update();
		// repaint the new node's parent (this node):
		if (n.length == 1) this.update();
		// recursively repaint the new node's previous sibling node:
		if (n.length > 1) n[n.length-2].update(true);
		return node;
	},
	/*
	Property: remove
		Removes this node, and all of it's child nodes. If you want to remove all the childnodes without removing the node itself, use 
	*/
	remove: function() {
		var p = this.parent;
		this._remove();
		p.update(true);
	},
	_remove: function() {
		// recursively remove this node's subnodes:
		var n = this.nodes;
		while (n.length) n[n.length-1]._remove();
		// remove the node id from the control's index:
		delete this.control.index[this.id];
		// remove this node's divs:
		this.div.main.remove();
		this.div.sub.remove();
		if (this.parent) {
			// remove this node from the parent's collection of nodes:
			var p = this.parent.nodes;
			p.remove(this);
			// in case we removed the parent's last node, flag it's current last node as being the last:
			if (p.length) p[p.length-1].last = true;
		}
	},
	/*
	Property: clear
		Removes all child nodes under this node, without removing the node itself.
		To remove all nodes including this one, use 
	*/
	clear: function() {
		this.control.disable();
		while (this.nodes.length) this.nodes[this.nodes.length-1].remove();
		this.control.enable();
	},
	/*
	Property: update
		Update the tree node's visual appearance.
	Parameters:
		recursive - boolean, defaults to false. If true, recursively updates all nodes beneath this one.
		invalidated - boolean, defaults to false. If true, updates only nodes that have been invalidated while the control has been disabled.
	*/
	update: function(recursive, invalidated) {
		var draw = true;
		if (!this.control.enabled) {
			// control is currently disabled, so we don't do any visual updates
			this.invalidated = true;
			draw = false;
		}
		if (invalidated) {
			if (!this.invalidated) {
				draw = false; // this one is still valid, don't draw
			} else {
				this.invalidated = false; // we're drawing this item now
			}
		}
		if (draw) {
			var x;
			// make selected, or not:
			this.div.main.className = 'mooTree_node' + (this.selected ? ' mooTree_selected' : '');
			// update indentations:
			x = this.div.indent;
			this.empty(x);
			var p = this, i;
			while (p.parent) {
				p = p.parent;
				i = this.getImg(p.last || !this.control.grid ? '' : 'I');
				if (x.firstChild) {
					i.injectBefore( x.firstChild );
				} else {
					x.adopt(i);
				}
			}
			// update the text:
			x = this.div.text;
			this.empty(x);
			x.appendText(this.text);
			if (this.color) x.style.color = this.color;
			// update the icon:
			x = this.div.icon;
			this.empty(x);
			this.getImg( this.nodes.length ? ( this.open ? (this.openicon || this.icon || '_open') : (this.icon || '_closed') ) : ( this.icon || (this.control.mode == 'folders' ? '_closed' : '_doc') ), x );
			// update the plus/minus gadget:
			x = this.div.gadget;
			this.empty(x);
			this.getImg( ( this.control.grid ? ( this.control.root == this ? (this.nodes.length ? 'R' : '') : (this.last?'L':'T') ) : '') + (this.nodes.length ? (this.open?'minus':'plus') : ''), x );
			// show/hide subnodes:
			this.div.sub.style.display = this.open ? 'block' : 'none';
		}
		// if recursively updating, update all child nodes:
		if (recursive) this.nodes.forEach( function(node) {
			node.update(true, invalidated);
		});
	},
	/*
	Property: getImg
		Creates a new image (actually, a div Element) -- or turns a given div into an image.
		You should not need to manually call this method. (though if for some reason you want to, you can)
	Parameters:
		name - the name of new image to create, defined by  or located in an external file.
		div - optional. A string representing an existing div element to be turned into an image, or an element reference.
	Returns:
		The new div Element.
	*/
	getImg: function(name, div) {
		// if no div was specified, create a new one:
		if (div === undefined) div = new Element('div');
		// apply the mooTree_img CSS class:
		div.addClass('mooTree_img');
		// if a blank image was requested, simply return it now:
		if (name == '') return div;
		var img = this.control.theme;
		var i = MooTreeIcon.indexOf(name);
		if (i == -1) {
			// custom (external) icon:
			var x = name.split('#');
			img = x[0];
			i = (x.length == 2 ? parseInt(x[1])-1 : 0);
		}
		div.style.backgroundImage = 'url(' + img + ')';
		div.style.backgroundPosition = '-' + (i*18) + 'px 0px';
		return div;
	},
	/*
	Property: toggle
		By default (with no arguments) this function toggles the node between expanded/collapsed.
		Can also be used to recursively expand/collapse all or part of the tree.
	Parameters:
		recursive - boolean, defaults to false. With recursive set to true, all child nodes are recursively toggle to this node's new state.
		state - boolean. If undefined, the node's state is toggled. If true or false, the node can be explicitly opened or closed.
	*/
	toggle: function(recursive, state) {
		this.open = (state === undefined ? !this.open : state);
		this.update();
		this.onExpand(this.open);
		this.control.onExpand(this, this.open);
		if (recursive) this.nodes.forEach( function(node) {
			node.toggle(true, this.open);
		}, this);
	},
	/*
	Property: select
		Called by  when the selection changes.
		You should not manually call this method - to set the selection, use the  method.
	*/
	select: function(state) {
		this.selected = state;
		this.update();
		this.onSelect(state);
	},
	/*
	Property: load
		Asynchronously load an XML structure into a node of this tree.
	Parameters:
		url - string, required, specifies the URL from which to load the XML document.
		vars - query string, optional.
	*/
	load: function(url, vars) {
		if (this.loading) return; // if this node is already loading, return
		this.loading = true;      // flag this node as loading
		this.toggle(false, true); // expand the node to make the loader visible
		this.clear();
		this.insert(this.control.loader);
		var f = function() {
			new XHR({
				method: 'GET',
				onSuccess: this._loaded.bind(this),
				onFailure: this._load_err.bind(this)
			}).send(url, vars || '');
		};
		window.setTimeout(f.bind(this), 20); // allowing a small delay for the browser to draw the loader-icon.
	},
	_loaded: function(text, xml) {
		// called on success - import nodes from the root element:
		this.control.disable();
		this.clear();
		this._import(xml.documentElement);
		this.control.enable();
		this.loading = false;
	},
	_import: function(e) {
		// import childnodes from an xml element:
		var n = e.childNodes;
		for (var i=0; i