1 /** @namespace gtk namespace */
  2 gtk = {};
  3 
  4 
  5 
  6 /**
  7  * @namespaces maylabs
  8  */
  9 
 10 var mylabs = mylabs || {};
 11 /** @namespace jsgtk name space */
 12 jsgtk = {};
 13 
 14 /**
 15 * Drag Object : make dom object draggable by www.youngpup.net
 16 */
 17 jsgtk.domDrag = {
 18 
 19 	obj : null,
 20 
 21 	/**
 22 	* init() method 				: The initalization function for the drag object
 23 	* @param {object} o 			: The element to act as the drag handle
 24 	* @param {object} oRoot 		: The element to be dragged, if not specified, the handle will be the element dragged.
 25 	* @param {integer} minX 		: min x of coordinate allowed for the element
 26 	* @param {integer} maxX 		: max x of coordinate allowed for the element
 27 	* @param {integer} minY 		: min y of coordinate allowed for the element
 28 	* @param {integer} maxY 		: max y of coordinate allowed for the element
 29 	* @param {boolean} bSwapHorzRef : Toggle the horizontal coordinate system
 30 	* @param {boolean} bSwapVertRef : Toggle the vertical coordinate system
 31 	* @param {function} fxMapper	: Functions for mapping x and y coordinates to others
 32 	* @param {function} fyMapper 	: Functions for mapping x and y coordinates to others
 33 	*/
 34 	init : function(o, oRoot, minX, maxX, minY, maxY, hDisable, vDisable, bSwapHorzRef, bSwapVertRef, fXMapper, fYMapper){
 35 
 36 		o.onmousedown = jsgtk.domDrag.start;
 37 
 38 		o.hmode	= bSwapHorzRef ? false : true ;
 39 		o.vmode	= bSwapVertRef ? false : true ;
 40 
 41 		o.root = oRoot && oRoot != null ? oRoot : o ;
 42 
 43 		if (o.hmode  && isNaN(parseInt(o.root.style.left  ))) o.root.style.left   = "0px";
 44 		if (o.vmode  && isNaN(parseInt(o.root.style.top   ))) o.root.style.top    = "0px";
 45 		if (!o.hmode && isNaN(parseInt(o.root.style.right ))) o.root.style.right  = "0px";
 46 		if (!o.vmode && isNaN(parseInt(o.root.style.bottom))) o.root.style.bottom = "0px";
 47 
 48 		o.minX	= typeof minX != 'undefined' ? minX : null;
 49 		o.minY	= typeof minY != 'undefined' ? minY : null;
 50 		o.maxX	= typeof maxX != 'undefined' ? maxX : null;
 51 		o.maxY	= typeof maxY != 'undefined' ? maxY : null;
 52 
 53 		o.minX	= hDisable ? 0 : o.minX;
 54 		o.maxX	= hDisable ? 0 : o.maxX;
 55 		o.minY	= vDisable ? 0 : o.minY;
 56 		o.maxY	= vDisable ? 0 : o.maxY;
 57 
 58 		o.xMapper = fXMapper ? fXMapper : null;
 59 		o.yMapper = fYMapper ? fYMapper : null;
 60 
 61 		o.root.onDragStart	= new Function();
 62 		o.root.onDragEnd	= new Function();
 63 		o.root.onDrag		= new Function();
 64 	},
 65 
 66 	start : function(e){
 67 
 68 		var o = jsgtk.domDrag.obj = this;
 69 
 70 		e = jsgtk.domDrag.fixE(e);
 71 
 72 		var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
 73 		var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
 74 
 75 		o.root.onDragStart(x, y, e);
 76 
 77 		o.lastMouseX	= e.clientX;
 78 		o.lastMouseY	= e.clientY;
 79 
 80 		if (o.hmode) {
 81 
 82 			if (o.minX != null)	o.minMouseX	= e.clientX - x + o.minX;
 83 			if (o.maxX != null)	o.maxMouseX	= o.minMouseX + o.maxX - o.minX;
 84 
 85 		} else {
 86 			if (o.minX != null) o.maxMouseX = -o.minX + e.clientX + x;
 87 			if (o.maxX != null) o.minMouseX = -o.maxX + e.clientX + x;
 88 		}
 89 
 90 		if (o.vmode) {
 91 
 92 			if (o.minY != null)	o.minMouseY	= e.clientY - y + o.minY;
 93 			if (o.maxY != null)	o.maxMouseY	= o.minMouseY + o.maxY - o.minY;
 94 
 95 		} else {
 96 			if (o.minY != null) o.maxMouseY = -o.minY + e.clientY + y;
 97 			if (o.maxY != null) o.minMouseY = -o.maxY + e.clientY + y;
 98 		}
 99 
100 		document.onmousemove	= jsgtk.domDrag.drag;
101 		document.onmouseup		= jsgtk.domDrag.end;
102 
103 		return false;
104 	},
105 
106 	drag : function(e){
107 
108 		e = jsgtk.domDrag.fixE(e);
109 
110 		var o = jsgtk.domDrag.obj;
111 
112 		var ey	= e.clientY;
113 		var ex	= e.clientX;
114 
115 		var y = parseInt(o.vmode ? o.root.style.top  : o.root.style.bottom);
116 		var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right );
117 		var nx, ny;
118 
119 		if (o.minX != null) ex = o.hmode ? Math.max(ex, o.minMouseX) : Math.min(ex, o.maxMouseX);
120 
121 		if (o.maxX != null) ex = o.hmode ? Math.min(ex, o.maxMouseX) : Math.max(ex, o.minMouseX);
122 
123 		if (o.minY != null) ey = o.vmode ? Math.max(ey, o.minMouseY) : Math.min(ey, o.maxMouseY);
124 
125 		if (o.maxY != null) ey = o.vmode ? Math.min(ey, o.maxMouseY) : Math.max(ey, o.minMouseY);
126 
127 		nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1));
128 		ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1));
129 
130 		if (o.xMapper) nx = o.xMapper(y);
131 		else if (o.yMapper)	ny = o.yMapper(x);
132 
133 		jsgtk.domDrag.obj.root.style[o.hmode ? "left" : "right"] = nx + "px";
134 		jsgtk.domDrag.obj.root.style[o.vmode ? "top" : "bottom"] = ny + "px";
135 
136 		jsgtk.domDrag.obj.lastMouseX	= ex;
137 		jsgtk.domDrag.obj.lastMouseY	= ey;
138 
139 		jsgtk.domDrag.obj.root.onDrag(nx, ny, e);
140 		return false;
141 	},
142 
143 	end : function(){
144 
145 		document.onmousemove = null;
146 		document.onmouseup   = null;
147 
148 		jsgtk.domDrag.obj.root.onDragEnd(
149 			parseInt(jsgtk.domDrag.obj.root.style[jsgtk.domDrag.obj.hmode ? "left" : "right"]),
150 			parseInt(jsgtk.domDrag.obj.root.style[jsgtk.domDrag.obj.vmode ? "top" : "bottom"])
151 		);
152 
153 		jsgtk.domDrag.obj = null;
154 	},
155 
156 	fixE : function(e){
157 
158 		if (typeof e == 'undefined') e = window.event;
159 
160 		if (typeof e.layerX == 'undefined') e.layerX = e.offsetX;
161 		if (typeof e.layerY == 'undefined') e.layerY = e.offsetY;
162 		return e;
163 	}
164 };
165 /*
166 
167 uuid.js - Version 0.3
168 JavaScript Class to create a UUID like identifier
169 
170 Copyright (C) 2006-2008, Erik Giberti (AF-Design), All rights reserved.
171 
172 This program is free software; you can redistribute it and/or modify it under
173 the terms of the GNU General Public License as published by the Free Software
174 Foundation; either version 2 of the License, or (at your option) any later
175 version.
176 
177 This program is distributed in the hope that it will be useful, but WITHOUT ANY
178 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
179 PARTICULAR PURPOSE. See the GNU General Public License for more details.
180 
181 You should have received a copy of the GNU General Public License along with
182 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
183 Place, Suite 330, Boston, MA 02111-1307 USA
184 
185 The latest version of this file can be downloaded from
186 http://www.af-design.com/resources/javascript_uuid.php
187 
188 HISTORY:
189 6/5/06 	- Initial Release
190 5/22/08 - Updated code to run faster, removed randrange(min,max) in favor of
191           a simpler rand(max) function. Reduced overhead by using getTime()
192           method of date class (suggestion by James Hall).
193 9/5/08	- Fixed a bug with rand(max) and additional efficiencies pointed out
194 	  by Robert Kieffer http://broofa.com/
195 
196 KNOWN ISSUES:
197 - Still no way to get MAC address in JavaScript
198 - Research into other versions of UUID show promising possibilities
199   (more research needed)
200 - Documentation needs improvement
201 
202 */
203 
204 function UUID(){
205 	this.id = this.createUUID();
206 }
207 
208 UUID.prototype.valueOf = function(){ return this.id; };
209 UUID.prototype.toString = function(){ return this.id; };
210 
211 
212 UUID.prototype.createUUID = function(){
213 	var dg = new Date(1582, 10, 15, 0, 0, 0, 0);
214 	var dc = new Date();
215 	var t = dc.getTime() - dg.getTime();
216 	var h = '-';
217 	var tl = UUID.getIntegerBits(t,0,31);
218 	var tm = UUID.getIntegerBits(t,32,47);
219 	var thv = UUID.getIntegerBits(t,48,59) + '1'; // version 1, security version is 2
220 	var csar = UUID.getIntegerBits(UUID.rand(4095),0,7);
221 	var csl = UUID.getIntegerBits(UUID.rand(4095),0,7);
222 
223 	var n = UUID.getIntegerBits(UUID.rand(8191),0,7) +
224 			UUID.getIntegerBits(UUID.rand(8191),8,15) +
225 			UUID.getIntegerBits(UUID.rand(8191),0,7) +
226 			UUID.getIntegerBits(UUID.rand(8191),8,15) +
227 			UUID.getIntegerBits(UUID.rand(8191),0,15); // this last number is two octets long
228 	return tl + h + tm + h + thv + h + csar + csl + h + n;
229 };
230 
231 
232 
233 
234 UUID.getIntegerBits = function(val,start,end){
235 	var base16 = UUID.returnBase(val,16);
236 	var quadArray = new Array();
237 	var quadString = '';
238 	var i = 0;
239 	for(i=0;i<base16.length;i++){
240 		quadArray.push(base16.substring(i,i+1));
241 	}
242 	for(i=Math.floor(start/4);i<=Math.floor(end/4);i++){
243 		if(!quadArray[i] || quadArray[i] == '') quadString += '0';
244 		else quadString += quadArray[i];
245 	}
246 	return quadString;
247 };
248 
249 UUID.returnBase = function(number, base){
250 	return (number).toString(base).toUpperCase();
251 };
252 
253 UUID.rand = function(max){
254 	return Math.floor(Math.random() * (max + 1));
255 };
256 
257 
258 jsgtk.Dom = {
259 		ie: (function(){ return (window.opera === undefined && (navigator.userAgent.indexOf('Internet Explorer') >= 0 || navigator.userAgent.indexOf("MSIE") >= 0)) ? true : false; })(),
260 		ie6or7: (function() { return (window.opera === undefined && (navigator.userAgent.indexOf("MSIE 6.0") >= 0 || navigator.userAgent.indexOf("MSIE 7.0") >= 0)) ? true : false; })(),
261 		doc: document,
262 		create: function(args){
263 		    if(!args.tag){ return null; }
264 		    var tag;
265 		    if((args.name || args.type) && this.ie) {
266 		      var name = (args.name) ? "name='" + args.name + "'" : "";
267 		      var type = (args.type) ? "type='" + args.type + "'" : "";
268 		      var html = '<' + args.tag + ' ' + name + ' '+ type +' />';
269 		      tag = this.doc.createElement(html);
270 		      delete args.name;
271 		    }
272 		    else {
273 		        tag = this.doc.createElement(args.tag);
274 	        }
275 		    delete args.tag;
276 
277 		    if(args.append) {
278 		      args.append.appendChild(tag);
279 		      delete args.append;
280 		    }
281 
282 		    args.edit = tag;
283 		    tag = this.edit(args);
284 
285 		    return tag;
286 	    },
287 	    edit: function(args){
288 		    var tag = args.edit;
289 		    delete args.edit;
290 
291 		    if(args.text) {
292 		      tag.appendChild(this.doc.createTextNode(args.text));
293 		      delete args.text;
294 		    }
295 
296 		    if(args.className){
297 			    tag.className = args.className;
298 			    delete args.className;
299 		    }
300 
301 			    var style = args.style;
302 		    if (style && this.ie) {
303 			    var styleCollections = style.split(";"), len = styleCollections.length;
304 			    for (var i=styleCollections.length; i--;) {
305 				    var styleString = styleCollections[i].replace(/ /g, '');
306 				    if (styleString) {
307                         var styleKeyValue = styleString.split(":");
308                         tag.style[this._camelize(styleKeyValue[0])] = styleKeyValue[1];
309 				    }
310 			    }
311 
312 			    delete style ;
313 		    }
314 
315 		    for(property in args){
316 		      tag.setAttribute(property, args[property]);
317 		    }
318 		    return tag;
319 	    },
320 	    _camelize: function(string) {
321 		    var parts = string.split('-'), len = parts.length;
322 		    if (len == 1){ return parts[0]; }
323 
324 		    var camelized = string.charAt(0) == '-' ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1): parts[0];
325 
326 		    for (var i = 1; i < len; i++){
327 		      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
328             }
329 
330 		    return camelized;
331 	    },
332 
333 		/*
334 		* Return the width and height of given text
335 		* @param {string} - text to be measured
336 		* @return {array} - widht and height of text
337 		*/
338 		getTextSize: function(text){
339 			var span = jsgtk.Dom.create({'tag': 'span', 'text': text});
340 			document.body.appendChild(span);
341 			var size = [span.offsetWidth, span.offsetHeight];
342 			document.body.removeChild(span);
343 			return size;
344 		},
345 
346 		/**
347 		* showElement() method
348 		* @param {object} dom  : dom object
349 		*/
350 		showElement: function(element){
351 			element.style.display = "block";
352 		},
353 
354 		/**
355 		* showElement() method
356 		* @param {object} dom  : dom object
357 		*/
358 		hideElement: function(element){
359 			element.style.display = "none";
360 		},
361 
362 		isShowed: function(element){
363 		    return element.style.display === "none" ? false : true;
364 		},
365 
366 		hilightCell: function(element, style){
367 		    for(el in style){
368 		        element.style[el] = style[el];
369 		    }
370 		},
371 		SortTable: function(table){
372 			var t = new SortableTable(table);
373 		}
374 };
375 jsgtk.Event = {
376 
377 	/**
378 	 * Add a new event listener to a dom object The event will be fired when the browser event occurs.
379 	 * @param {object} domObj
380 	 * @param {String} type
381 	 * @param {Function} callback
382 	 * @return {object} - handle used to remove listeners
383 	 */
384 	addDomListener: function(domObj, type, callback){
385 		if(domObj.addEventListener){
386 			domObj.addEventListener(type, callback, false);
387 		} else {
388 			domObj.attachEvent("on" + type, callback);
389 		}
390 		var handler = {
391 			obj: domObj,
392 			type: type,
393 			callback: callback
394 		};
395 
396 		return handler;
397 	},
398 
399 	/**
400 	 * Add a new event listener to a standard object this event can be fired using the trigger() method.
401 	 * @param {object} obj - Scope the callback will be called in
402 	 * @param {String} type
403 	 * @param {Function} callback
404 	 * @return {object} - handle used to remove listeners
405 	 */
406 	addListener: function(obj, type, callback){
407 		if(!obj.listeners) obj.listeners = {};
408 		if(!obj.listeners[type]) obj.listeners[type] = [];
409 		obj.listeners[type].push(callback);
410 		return {
411 			obj: obj,
412 			type: type,
413 			callback: callback,
414 			isDomObj: false
415 		};
416 	},
417 
418 	/**
419 	 * Remove an event listener which was added using addListener or addDomListener.
420 	 * @param {object} handler
421 	 */
422 	removeListener: function(handler){
423 		if(handler.obj.removeEventListener){
424 			handler.obj.removeEventListener(handler.type, handler.callback, false);
425 		} else {
426 			handler.obj.detachEvent("on" + handler.type, handler.callback);
427 		}
428 	},
429 
430 	/**
431 	 * Re-register event handler which was removed
432 	 * @param {object} handler
433 	 */
434 	registerHandler: function(handler){
435 		if(handler.obj.addEventListener){
436 			handler.obj.addEventListener(handler.type, handler.callback, false);
437 		} else {
438 			handler.obj.attachEvent("on" + handler.type, handler.callback);
439 		}
440 		return handler;
441 	},
442 
443 		/**
444 	 * Trigger an oject event which has been added using addListener().
445 	 * @param {object} obj
446 	 * @param {String} type
447 	 * @param {Anything} arguments - the arguments can be overloaded to pass additional items
448 	 */
449 	trigger: function(obj, type){
450 		if(obj.listeners && obj.listeners[type]){
451 			var _args = [];
452 			for(var i=2; i< arguments.length; i++){
453 				_args[i - 2]= arguments[i];
454 			}
455 			for(var i = 0; i < obj.listeners[type].length; i++){
456 				obj.listeners[type][i].apply(obj,_args);
457 			}
458 		}
459 	},
460 
461 	/**
462 	* Cancell bubbling phase of event
463 	* @param {object} e - event object
464 	*/
465 	stopBubble: function(e){
466         if ( e && e.stopPropagation ) e.stopPropagation();
467         else window.event.cancelBubble = true;
468 	},
469 
470 	stopDefault: function(e){
471 		if ( e && e.preventDefault )
472 		     e.preventDefault();
473 		else
474 		     window.event.returnValue = false;
475     	return false;
476 	}
477 };
478 jsgtk.Util = {
479     clone: function(obj){
480         var Clone = function(){};
481         Clone.prototype = obj;
482 
483         var c = new Clone();
484         c.constructor = Clone;
485         return c;
486     },
487 	isMatched: function(target, text){
488 		return new RegExp(target).test(text);
489 	},
490     arrayRemoveElement: function(array, element){
491 		var isFound = false;
492 		for(var i = 0, len = array.length; i < len; i++){
493 			if(array[i] === element){
494 				isFound = true;
495 				return i;
496 			}
497 		}
498 		if(isFound) array.splice(i, 1);
499 	},
500     arraySwapElements: function(array, element1, element2){
501         var index1 = array.indexOf(element1);
502         var index2 = array.indexOf(element2);
503 
504         array[index1] = null;
505         array[index2] = null;
506 
507         array[index1] = element2;
508         array[index2] = element1;
509     },
510     windowHeight: function(){
511         var de = document.documentElement;
512         return self.innerHeight || ( de && de.clientHeight ) || document.body.clientHeight;
513     },
514 
515     windowWidth: function(){
516         var de = document.documentElement;
517         return self.innerWidth || ( de && de.clientWidth ) || document.body.clientWidth;
518     },
519 
520     getWindowHeight: function(){
521         return jsgtk.Util.windowHeight();
522     },
523 
524     getWindowWidth: function(){
525         return jsgtk.Util.windowWidth();
526     },
527     calculateTextWidthHeight: function(text){
528         var span = jsgtk.Dom.create({"append": document.body, "tag": "span", "style" : "position:absolute;"});
529 	    var text = jsgtk.Dom.create({"append": span, "tag": "text", "text": text});
530 	    var width = span.clientWidth;
531 	    var height = span.clientHeight;
532 	    document.body.removeChild(span);
533 	    return [width, height];
534     },
535     getTextFromTop : function(parentHeight, childHeight){
536         return (parentHeight / 2) - (childHeight / 2);
537     },
538 
539     trim : function(str){
540         return str.replace(/^\s+|\s+$/, '');
541     },
542 
543     fullHeight: function(elem) {
544         var height;
545         document.body.appendChild(elem);
546         if ( this.getStyle( elem, 'display' ) != 'none' ){
547             height = elem.offsetHeight || this.getHeight(elem);
548             document.body.removeChild(elem);
549             return height;
550         }
551         var old = this.resetCSS(elem, {
552                 display: '',
553                 visibility: 'hidden',
554                 position: 'absolute'
555             });
556         height = elem.clientHeight || this.getHeight(elem);
557         this.restoreCSS(elem, old);
558         document.body.removeChild(elem);
559 
560         return height;
561     },
562 
563     fullWidth: function(elem) {
564         var width;
565 
566         document.body.appendChild(elem);
567         if (this.getStyle(elem, 'display') != 'none' ){
568             width = elem.offsetWidth || this.getWidth( elem );
569             document.body.removeChild(elem);
570 
571             return width + jsgtk.Util.EXTRAPIXEL;
572         }
573         var old = this.resetCSS( elem, {
574             display: '',
575             visibility: 'hidden',
576             position: 'absolute'
577         });
578 
579         width = elem.clientWidth || this.getWidth( elem );
580         this.restoreCSS( elem, old );
581         document.body.removeChild(elem);
582 
583         return width + jsgtk.Util.EXTRAPIXEL;
584     },
585 
586     getStyle: function(elem, name){
587         if (elem.style[name])
588             return elem.style[name];
589         else if (elem.currentStyle)
590             return elem.currentStyle[name];
591         else if (document.defaultView && document.defaultView.getComputedStyle) {
592             name = name.replace(/([A-Z])/g,"-$1");
593             name = name.toLowerCase();
594             var s = document.defaultView.getComputedStyle(elem,"");
595             return s && s.getPropertyValue(name);
596         } else
597             return null;
598     },
599 
600     getHeight: function(elem) {
601         return parseInt( this.getStyle( elem, 'height' ) );
602     },
603 
604     getWidth: function(elem){
605         return parseInt( this.getStyle( elem, 'width' ) );
606     },
607 
608 	pageX: function(elem) {
609         return elem.offsetParent ? elem.offsetLeft + this.pageX(elem.offsetParent) : elem.offsetLeft;
610     },
611 
612     pageY: function(elem) {
613         return elem.offsetParent ? elem.offsetTop + this.pageY(elem.offsetParent) : elem.offsetTop;
614     },
615 
616     getPageSize: function() {
617         var x, y, b = document.body, wi = window.innerHeight, ws = window.scrollMaxY;
618         if (wi && ws) {
619             x = b.scrollWidth;
620             y = wi + ws;
621         } else if (b.scrollHeight > b.offsetHeight) {
622             x = b.scrollWidth;
623             y = b.scrollHeight;
624         } else {
625             x = b.offsetWidth;
626             y = b.offsetHeight;
627         }
628         var w, h, d = document.documentElement;
629         if (self.innerHeight) {
630             w = self.innerWidth;
631             h = self.innerHeight;
632         } else if (d && d.clientHeight) {
633             w = d.clientWidth;
634             h = d.clientHeight;
635         } else if (b) {
636             w = b.clientWidth;
637             h = b.clientHeight;
638         }
639         var pH = (y < h) ? h : y, pW = (x < w) ? w : x;
640 
641         return [pW, pH, w, h];
642     },
643 
644     resetCSS: function(elem, prop) {
645         var old = {};
646         for ( var i in prop ) {
647             old[i] = elem.style[i];
648             elem.style[i] = prop[i];
649         }
650         return old;
651     },
652 
653     restoreCSS: function(elem, prop) {
654         for ( var i in prop )
655             elem.style[i] = prop[i];
656     },
657 
658     debug: function(msg){
659         throw(msg);
660     },
661 
662     removeArrayElements: function(array, from, to){
663         Array.remove(array, from, to);
664     },
665 
666     getScrollX: function() {
667         var de = document.documentElement;
668         return pageXOffset ||( de && de.scrollLeft ) || document.body.scrollLeft;
669     },
670 
671     getScrollY: function() {
672         var de = document.documentElement;
673         return self.pageYOffset ||( de && de.scrollTop ) || document.body.scrollTop;
674     },
675 
676     detect: {
677 	    init: function () {
678 		    this.browser = this.searchString(this.dataBrowser) || "An unknown browser";
679 		    this.version = this.searchVersion(navigator.userAgent)
680 			    || this.searchVersion(navigator.appVersion)
681 			    || "an unknown version";
682 		    this.OS = this.searchString(this.dataOS) || "an unknown OS";
683 	    },
684 	    searchString: function (data) {
685 		    for (var i=0;i<data.length;i++)	{
686 			    var dataString = data[i].string;
687 			    var dataProp = data[i].prop;
688 			    this.versionSearchString = data[i].versionSearch || data[i].identity;
689 			    if (dataString) {
690 				    if (dataString.indexOf(data[i].subString) != -1)
691 					    return data[i].identity;
692 			    }
693 			    else if (dataProp)
694 				    return data[i].identity;
695 		    }
696 	    },
697 	    searchVersion: function (dataString) {
698 		    var index = dataString.indexOf(this.versionSearchString);
699 		    if (index == -1) return;
700 		    return parseFloat(dataString.substring(index+this.versionSearchString.length+1));
701 	    },
702 	    dataBrowser: [
703 		    {
704 			    string: navigator.userAgent,
705 			    subString: "Chrome",
706 			    identity: "Chrome"
707 		    },
708 		    { 	string: navigator.userAgent,
709 			    subString: "OmniWeb",
710 			    versionSearch: "OmniWeb/",
711 			    identity: "OmniWeb"
712 		    },
713 		    {
714 			    string: navigator.vendor,
715 			    subString: "Apple",
716 			    identity: "Safari",
717 			    versionSearch: "Version"
718 		    },
719 		    {
720 			    prop: window.opera,
721 			    identity: "Opera"
722 		    },
723 		    {
724 			    string: navigator.vendor,
725 			    subString: "iCab",
726 			    identity: "iCab"
727 		    },
728 		    {
729 			    string: navigator.vendor,
730 			    subString: "KDE",
731 			    identity: "Konqueror"
732 		    },
733 		    {
734 			    string: navigator.userAgent,
735 			    subString: "Firefox",
736 			    identity: "Firefox"
737 		    },
738 		    {
739 			    string: navigator.vendor,
740 			    subString: "Camino",
741 			    identity: "Camino"
742 		    },
743 		    {		// for newer Netscapes (6+)
744 			    string: navigator.userAgent,
745 			    subString: "Netscape",
746 			    identity: "Netscape"
747 		    },
748 		    {
749 			    string: navigator.userAgent,
750 			    subString: "MSIE",
751 			    identity: "Explorer",
752 			    versionSearch: "MSIE"
753 		    },
754 		    {
755 			    string: navigator.userAgent,
756 			    subString: "Gecko",
757 			    identity: "Mozilla",
758 			    versionSearch: "rv"
759 		    },
760 		    { 		// for older Netscapes (4-)
761 			    string: navigator.userAgent,
762 			    subString: "Mozilla",
763 			    identity: "Netscape",
764 			    versionSearch: "Mozilla"
765 		    }
766 	    ],
767 	    dataOS : [
768 		    {
769 			    string: navigator.platform,
770 			    subString: "Win",
771 			    identity: "Windows"
772 		    },
773 		    {
774 			    string: navigator.platform,
775 			    subString: "Mac",
776 			    identity: "Mac"
777 		    },
778 		    {
779 			       string: navigator.userAgent,
780 			       subString: "iPhone",
781 			       identity: "iPhone/iPod"
782 	        },
783 		    {
784 			    string: navigator.platform,
785 			    subString: "Linux",
786 			    identity: "Linux"
787 		    }
788 	    ]
789 
790     }
791 };
792 
793 jsgtk.Util.detect.init();
794 
795 jsgtk.Util.EXTRAPIXEL = (jsgtk.Util.detect.OS == "Mac" && jsgtk.Util.detect.browser == "Firefox") ? 1 : 0;
796 
797 Array.remove = function(array, from, to) {
798     var rest = array.slice((to || from) + 1 || array.length);
799     array.length = from < 0 ? array.length + from : from;
800     return array.push.apply(array, rest);
801 };
802 jsgtk.Util.DomDraggableAdapter = {
803 	vDragInit: function(domObj, minY, maxY){
804 		jsgtk.domDrag.init(domObj, null, null, null, minY, maxY,true);
805 	},
806 	hDragInit: function(domObj, minX, maxX){
807 		jsgtk.domDrag.init(domObj, null, minX, maxX, null, null, false, true);
808 	},
809 	dragInit: function(domObj, minX, maxX, minY, maxY){
810 		jsgtk.domDrag.init(domObj, null, minX, maxX, minY, maxY, false, false);
811 	}
812 };
813 function SortableTable (tableEl) {
814 
815 	this.tbody = tableEl.getElementsByTagName('tbody');
816 	this.thead = tableEl.getElementsByTagName('thead');
817 	this.tfoot = tableEl.getElementsByTagName('tfoot');
818 
819     var tBody = this.tbody[0];
820 
821 	this.getInnerText = function (el) {
822 		if (typeof(el.textContent) != 'undefined') return el.textContent;
823 		if (typeof(el.innerText) != 'undefined') return el.innerText;
824 		if (typeof(el.innerHTML) == 'string') return el.innerHTML.replace(/<[^<>]+>/g,'');
825 	};
826 
827 	this.getParent = function (el, pTagName) {
828 		if (el == null) return null;
829 		else if (el.nodeType == 1 && el.tagName.toLowerCase() == pTagName.toLowerCase())
830 			return el;
831 		else
832 			return this.getParent(el.parentNode, pTagName);
833 	};
834 
835 	this.sort = function (cell) {
836 	    var column = cell.cellIndex;
837 	    var itm = this.getInnerText(tBody.rows[1].cells[column]);
838 		var sortfn = this.sortCaseInsensitive;
839 
840 		if (itm.match(/\d\d[-]+\d\d[-]+\d\d\d\d/)) sortfn = this.sortDate; // date format mm-dd-yyyy
841 		if (itm.replace(/^\s+|\s+$/g,"").match(/^[\d\.]+$/)) sortfn = this.sortNumeric;
842 
843 		this.sortColumnIndex = column;
844 
845 	    var newRows = [];
846 	    var emptyRows = [];
847 	    for (j = tBody.rows.length; j--;) {
848 	        var row = tBody.rows[j];
849             var className = row.className.split(" ");
850 
851 	        var emptyRowId = new RegExp("^" + "empty_");
852             if(!row.id.match(emptyRowId)) newRows.push(row);
853             else emptyRows.push(row);
854 		}
855 
856 		newRows.sort(sortfn);
857 
858 		if (cell.getAttribute("sortdir") == 'down') {
859 			newRows.reverse();
860 			cell.setAttribute('sortdir','up');
861 		} else {
862 			cell.setAttribute('sortdir','down');
863 		}
864 
865         var docFragment = document.createDocumentFragment();
866 
867 		for (i = newRows.length;i--;) {
868 		    docFragment.appendChild(newRows[i]);
869 		}
870 		tBody.appendChild(docFragment);
871 
872 		for (i=0;i<emptyRows.length;i++) {
873 		    docFragment.appendChild(emptyRows[i])
874 		}
875 		tBody.appendChild(docFragment);
876 
877 
878 	    for (j = 0; j < tBody.rows.length; j++) {
879 	        var row = tBody.rows[j];
880             var className = row.className.split(" ");
881 
882             if(j % 2 === 0) className[1] = "gtk_listview_table_body_tr_even";
883             else className[1] = "gtk_listview_table_body_tr_odd";
884 
885             row.className = className.join(" ");
886 		}
887 
888 	};
889 
890 	this.sortCaseInsensitive = function(a,b) {
891 		aa = thisObject.getInnerText(a.cells[thisObject.sortColumnIndex]).toLowerCase();
892 		bb = thisObject.getInnerText(b.cells[thisObject.sortColumnIndex]).toLowerCase();
893 		if (aa==bb) return 0;
894 		if (aa<bb) return -1;
895 		return 1;
896 	};
897 
898 	this.sortDate = function(a,b) {
899 		aa = thisObject.getInnerText(a.cells[thisObject.sortColumnIndex]);
900 		bb = thisObject.getInnerText(b.cells[thisObject.sortColumnIndex]);
901 		date1 = aa.substr(6,4)+aa.substr(3,2)+aa.substr(0,2);
902 		date2 = bb.substr(6,4)+bb.substr(3,2)+bb.substr(0,2);
903 		if (date1==date2) return 0;
904 		if (date1<date2) return -1;
905 		return 1;
906 	};
907 
908 	this.sortNumeric = function(a,b) {
909 		aa = parseFloat(thisObject.getInnerText(a.cells[thisObject.sortColumnIndex]));
910 		if (isNaN(aa)) aa = 0;
911 		bb = parseFloat(thisObject.getInnerText(b.cells[thisObject.sortColumnIndex]));
912 		if (isNaN(bb)) bb = 0;
913 		return aa-bb;
914 	};
915 
916 	var thisObject = this;
917 	var sortSection = this.thead;
918 
919 	if (this.tbody.length <= 0) return;
920 
921 	if (sortSection && sortSection[0].rows && sortSection[0].rows.length > 0) {
922 		var sortRow = sortSection[0].rows[0];
923 	} else {
924 		return;
925 	}
926 
927 	for (var i=0; i<sortRow.cells.length; i++) {
928 		sortRow.cells[i].sTable = this;
929 		sortRow.cells[i].onclick = function () {
930 			this.sTable.sort(this);
931 			return false;
932 		};
933 	}
934 
935 }
936 pango = {};
937 pango._scriptName = "gtk.js";
938 
939 pango.Path = {
940 	/**
941 	 * Returns the path of Pango.js
942 	 * @return {String}
943 	 */
944     getRootPath: function () {
945         var scriptLocation = "";
946         var scriptName = pango._scriptName;
947 
948         var scripts = document.getElementsByTagName('script');
949         for (var i = 0; i < scripts.length; i++) {
950             var src = scripts[i].getAttribute('src');
951             if (src) {
952                 var index = src.lastIndexOf(scriptName);
953 
954                 if ((index > -1) && (index + scriptName.length == src.length)) {
955                     scriptLocation = src.slice(0, -scriptName.length);
956                     break;
957                 }
958             }
959         }
960 
961         return scriptLocation;
962      }
963 };
964 /**
965  * Store all attributes to make up text
966  * @property {Object} o which store all attributes such as font_family, color, background_color, font_size, font_weight, text_decoration.
967  */
968 pango.Attribute = function(styleObj){
969     	this._styleObj = styleObj || {};
970 	this.fontFamily = this._styleObj.fontFamily || "Arial";
971 	this.color = this._styleObj.color || "white";
972 	this.backgroundColor = this._styleObj.backgroundColor || "white";
973 	this.fontSize = this._styleObj.fontSize || "12px";
974 	this.fontWeight	= this._styleObj.fontWeight || "normal";
975 	this.textDecoration = this._styleObj.textDecoration || "none";
976 	this.border = this._styleObj.border || "0";
977 	this.cursor = this._styleObj.cursor || "default";
978 	this.textTransform = this._styleObj.textTransform || "none";
979 	this.padding = this._styleObj.padding || "0";
980 	this.textAlign = this._styleObj.textAlign || "left";
981 	this.opacity = this._styleObj.opacity || "1";
982 };
983 /**
984  * gtk.Constants
985  * gtk.PACK_START, gtk.PACK_END
986  * Orientation of progressBar
987  * gtk.PROGRESS_LEFT_TO_RIGHT, gtk.PROGRESS_RIGHT_TO_LEFT, gtk.PROGRESS_TOP_TO_BOTTOM, gtk.PROGRESS_BOTTOM_TO_TOP,
988  * The Position Type constants specify
989  * gtk.POS_LEFT,gtk.POS_RIGHT,gtk.POS_TOP, gtk.POS_BOTTOM,
990  * Customize constants
991  * gtk.CELLRENDERER_WIDTH, gtk.CELLRENDERER_HEIGHT, gtk.CELL_HEIGHT, gtk.CELL_WIDTH, gtk.LISTSTORE, gtk.TREESTORE
992  * GTK Window Type Constants
993  * gtk.WINDOW_TOPLEVEL, gtk.WINDOW_POPUP, gtk.WIN_POS_CENTER,
994  * GTK Window Position Constants
995  * gtk.WIN_POS_CENTER
996  * GTK justification constants
997  * gtk.JUSTIFY_LEFT, gtk.JUSTIFY_RIGHT, gtk.JUSTIFY_TOP, gtk.JUSTIFY_BOTTOM, gtk.JUSTIFY_CENTER, gtk.JUSTIFY_FILL
998  * GTK keycode Constants
999  * gtk.ENTER_KEY, gtk.UP_ARROW_KEY, gtk.DOWN_ARROW_KEY, gtk.DELETE_KEY, gtk.TAB_KEY, gtk.BACKSPACE_KEY, gtk.A_KEY, gtk.CAP_A_KEY
1000  */
1001 
1002 gtk.PACK_START = "PACK_START";
1003 gtk.PACK_END = "PACK_END";
1004 
1005 gtk.PROGRESS_LEFT_TO_RIGHT = "leftToRight";
1006 gtk.PROGRESS_RIGHT_TO_LEFT = "rightToLeft";
1007 gtk.PROGRESS_TOP_TO_BOTTOM = "topToBottom";
1008 gtk.PROGRESS_BOTTOM_TO_TOP = "bottomToTop";
1009 
1010 gtk.POS_LEFT = "leftPosition";
1011 gtk.POS_RIGHT = "rightPosition";
1012 gtk.POS_TOP = "topPosition";
1013 gtk.POS_BOTTOM = "bottomPosition";
1014 
1015 gtk.CELLRENDERER_WIDTH = 400;
1016 gtk.CELLRENDERER_HEIGHT = 200;
1017 gtk.CELL_HEIGHT = 20;
1018 gtk.CELL_WIDTH = gtk.CELLRENDERER_WIDTH;
1019 gtk.LISTSTORE = "LIST_STORE";
1020 gtk.TREESTORE = "TREE_STORE";
1021 
1022 gtk.WINDOW_TOPLEVEL = "WINDOW_TOPLEVEL";
1023 gtk.WINDOW_POPUP = "WINDOW_POPUP";
1024 gtk.WIN_POS_CENTER = "WIN_POS_CENTER";
1025 
1026 gtk.WIN_POS_CENTER = "center";
1027 
1028 gtk.JUSTIFY_LEFT   = "left";
1029 gtk.JUSTIFY_RIGHT  = "right";
1030 gtk.JUSTIFY_TOP    = "TOP";
1031 gtk.JUSTIFY_BOTTOM = "BOTTOM";
1032 gtk.JUSTIFY_CENTER = "center";
1033 gtk.JUSTIFY_FILL   = "justify";
1034 
1035 gtk.ENTER_KEY = 13;
1036 gtk.UP_ARROW_KEY = 38;
1037 gtk.DOWN_ARROW_KEY = 40;
1038 gtk.LEFT_ARROW_KEY = 37;
1039 gtk.RIGHT_ARROW_KEY = 39;
1040 gtk.DELETE_KEY = 46;
1041 gtk.TAB_KEY = 9;
1042 gtk.BACKSPACE_KEY = 8;
1043 gtk.A_KEY = 97;
1044 gtk.CAP_A_KEY = 65;
1045 gtk.ESC_KEY = 27;
1046 
1047 gtk.WINDOW_RESTORED = "WINDOW_RESTORED";
1048 gtk.WINDOW_MAXIMIZED = "WINDOW_MAXIMIZED";
1049 gtk.WINDOW_MINIMIZED = "WINDOW_MINIMIZED";
1050 gtk.WINDOW_ERROR = "WINDOW_ERROR";
1051 
1052 gtk.WINDOW_WARNING = "WINDOW_WARNING";
1053 gtk.WINDOW_CONFIRM = "WINDOW_CONFIRM";
1054 gtk.WINDOW_INFO = "WINDOW_INFO";
1055 
1056 gtk.TREE_ITER = "TREE_ITER";
1057 
1058 gtk.SMART_ENTRY_DROPDOWN_FIXED_MODEL = "SMART_ENTRY_DROPDOWN_FIXED_MODEL";
1059 gtk.SMART_ENTRY_DROPDOWN_DYNAMIC_MODEL = "SMART_ENTRY_DROPDOWN_DYNAMIC_MODEL";
1060 
1061 gtk.BLANK_WIDGET = "BLANK_WIDGET";
1062 
1063 
1064 /*//= require <src/javascript/gobject>*/
1065 /*//= require <src/javascript/gobject_gobject> */
1066 /*//= require <src/javascript/gtk_object>*/
1067 /*//= require <src/javascript/gtk_widget>*/
1068 /*//= require <src/javascript/gtk_container>*/
1069 /*//= require <src/javascript/gtk_state_window_maximized>*/
1070 /*//= require <src/javascript/gtk_state_window_minimized>*/
1071 /*//= require <src/javascript/gtk_state_window_restored>*/
1072 /*//= require <src/javascript/gtk_window_base>*/
1073 /*//= require <src/javascript/gtk_window>*/
1074 /*//= require <src/javascript/gtk_hbox>*/
1075 /*//= require <src/javascript/gtk_hbox_factory>*/
1076 /*//= require <src/javascript/gtk_hbox_homogenoues>*/
1077 /*//= require <src/javascript/gtk_hbox_none_homogenoues>*/
1078 /*//= require <src/javascript/gtk_vbox>*/
1079 /*//= require <src/javascript/gtk_vbox_factory>*/
1080 /*//= require <src/javascript/gtk_vbox_homogenoues>*/
1081 /*//= require <src/javascript/gtk_vbox_none_homogenoues>*/
1082 /*//= require <src/javascript/gtk_paned>*/
1083 /*//= require <src/javascript/gtk_vpaned>*/
1084 /*//= require <src/javascript/gtk_hpaned>*/
1085 /*//= require <src/javascript/gtk_image>*/
1086 /*//= require <src/javascript/gtk_label>*/
1087 /*//= require <src/javascript/gtk_button>*/
1088 /*//= require <src/javascript/gtk_radio_button>*/
1089 /*//= require <src/javascript/gtk_check_button>*/
1090 /*//= require <src/javascript/gtk_entry>*/
1091 /*//= require <src/javascript/gtk_entry_drop_down_controller>*/
1092 /*//= require <src/javascript/gtk_entry_drop_down>*/
1093 /*//= require <src/javascript/gtk_frame>*/
1094 /*//= require <src/javascript/gtk_treepath>*/
1095 /*//= require <src/javascript/gtk_treeiter>*/
1096 /*//= require <src/javascript/gtk_treestore>*/
1097 /*//= require <src/javascript/gtk_treeview>*/
1098 /*//= require <src/javascript/gtk_treeview_controller>*/
1099 /*//= require <src/javascript/gtk_dom>*/
1100 /*//= require <src/javascript/gtk_panel>*/
1101 /*//= require <src/javascript/gtk_notebook>*/
1102 /*//= require <src/javascript/gtk_extra_tabs>*/
1103 /*//= require <src/javascript/gtk_extra_contents>*/
1104 /*//= require <src/javascript/gtk_combobox>*/
1105 /*//= require <src/javascript/gtk_combobox_controller>*/
1106 /*//= require <src/javascript/gtk_treeview_controller>*/
1107 /*//= require <src/javascript/gtk_text_view>*/
1108 /*//= require <src/javascript/gtk_table_factory>*/
1109 /*//= require <src/javascript/gtk_table_base>*/
1110 /*//= require <src/javascript/gtk_table_homogenoues>*/
1111 /*//= require <src/javascript/gtk_table_none_homogenoues>*/
1112 /*//= require <src/javascript/gtk_slider>*/
1113 /*//= require <src/javascript/gtk_smart_entry_factory>*/
1114 /*//= require <src/javascript/gtk_smart_entry_drop_down>*/
1115 /*//= require <src/javascript/gtk_smart_entry_dropdow_fixed_model>*/
1116 /*//= require <src/javascript/gtk_smart_entry_dropdow_fixed_model_controller>*/
1117 /*//= require <src/javascript/gtk_smart_entry_drop_down_dynamic_model>*/
1118 /*//= require <src/javascript/gtk_smart_entry_drop_down_dynamic_model_controller>*/
1119 /*//= require <src/javascript/gtk_smart_entry_drop_down_rendere>*/
1120 /*//= require <src/javascript/gtk_smart_entry_tag_rendere>*/
1121 /*//= require <src/javascript/gtk_smart_entry>*/
1122 /*//= require <src/javascript/gtk_drop_down_view>*/
1123 /*//= require <src/javascript/gtk_drop_down_controller>*/
1124 /*//= require <src/javascript/gtk_entry_tag>*/
1125 /*//= require <src/javascript/gtk_smart_entry_drop_down_label>*/
1126 /*//= require <src/javascript/gtk_smart_entry_drop_down_label_controller>*/
1127 /*//= require <src/javascript/gtk_smart_entry_drop_down_label_model>*/
1128 /*//= require <src/javascript/gtk_item>*/
1129 /*//= require <src/javascript/gtk_menu>*/
1130 /*//= require <src/javascript/gtk_menu_item>*/
1131 /*//= require <src/javascript/gtk_liststore>*/
1132 /*//= require <src/javascript/gtk_listview>*/
1133 /*//= require <src/javascript/gtk_listview_controller>*/
1134 /*//= require <src/javascript/gtk_upload_button>*/
1135 /*//= require <src/javascript/gtk_form>*/
1136 /*//= require <lib/shape/mylabs_svg_vml>*/
1137 /*//= require <lib/shape/shape>*/
1138 /*//= require <src/javascript/gtk_bubble>*/
1139 /*//= require <src/javascript/gtk_popup>*/
1140 /*//= require <src/javascript/gtk_label_store>*/
1141 /*//= require <src/javascript/gtk_justified_label>*/
1142 /*//= require <src/javascript/gtk_justified_label_controller>*/
1143 /*//= require <src/javascript/gtk_popup_window>*/
1144 /*//= require <src/javascript/gtk_popup_window_default>*/
1145 /*//= require <src/javascript/gtk_popup_window_confirm>*/
1146 /*//= require <src/javascript/gtk_popup_window_warning>*/
1147 /*//= require <src/javascript/gtk_popup_window_error>*/
1148 /*//= require <src/javascript/gtk_popup_window_info>*/
1149 /*//= require <src/javascript/gtk_text_editor>*/
1150 /*//= require <src/javascript/gtk_text_editor_toolbar>*/
1151 /*//= require <src/javascript/gtk_liquid_box>*/
1152 /*//= require <src/javascript/gtk_multipanel_container>*/
1153 /*//= require <src/javascript/gtk_unorder_list>*/
1154 /*//= require <src/javascript/gtk_unorder_list_conostroller>*/
1155 /*//= require <src/javascript/gtk_list_model>*/
1156 /*//= require <src/javascript/gtk_accordion>*/
1157 /*//= require <src/javascript/gtk_scroller>*/
1158 /*//= require <src/javascript/gtk_scroller_vertical> */
1159 /*//= require <src/javascript/gtk_null_object>*/
1160 
1161