You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicemix.apache.org by gn...@apache.org on 2006/10/25 12:59:19 UTC

svn commit: r467601 [6/6] - in /incubator/servicemix/trunk/servicemix-web-console: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/servicemix/ src/main/java/org/apache/servicemix/web/ src/main/java...

Added: incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/plotkit/SweetCanvas.js
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/plotkit/SweetCanvas.js?view=auto&rev=467601
==============================================================================
--- incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/plotkit/SweetCanvas.js (added)
+++ incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/plotkit/SweetCanvas.js Wed Oct 25 03:59:16 2006
@@ -0,0 +1,281 @@
+/*
+    PlotKit Sweet Canvas Renderer
+    =============================
+    Canvas Renderer for PlotKit which looks pretty!
+
+    Copyright
+    ---------
+    Copyright 2005,2006 (c) Alastair Tse <alastair^liquidx.net>
+    For use under the BSD license. <http://www.liquidx.net/plotkit>
+*/
+
+// -------------------------------------------------------------------------
+// Check required components
+// -------------------------------------------------------------------------
+
+try {    
+    if (typeof(PlotKit.CanvasRenderer) == 'undefined')
+    {
+        throw "";    
+    }
+} 
+catch (e) {    
+    throw "SweetCanvas depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.{Layout, Canvas}"
+}
+
+
+if (typeof(PlotKit.SweetCanvasRenderer) == 'undefined') {
+    PlotKit.SweetCanvasRenderer = {};
+}
+
+PlotKit.SweetCanvasRenderer = function(element, layout, options) {
+    if (arguments.length > 0) {
+        this.__init__(element, layout, options);
+    }
+};
+
+PlotKit.SweetCanvasRenderer.NAME = "PlotKit.SweetCanvasRenderer";
+PlotKit.SweetCanvasRenderer.VERSION = PlotKit.VERSION;
+
+PlotKit.SweetCanvasRenderer.__repr__ = function() {
+    return "[" + this.NAME + " " + this.VERSION + "]";
+};
+
+PlotKit.SweetCanvasRenderer.toString = function() {
+    return this.__repr__();
+};
+
+// ---------------------------------------------------------------------
+// Subclassing Magic
+// ---------------------------------------------------------------------
+
+PlotKit.SweetCanvasRenderer.prototype = new PlotKit.CanvasRenderer();
+PlotKit.SweetCanvasRenderer.prototype.constructor = PlotKit.SweetCanvasRenderer;
+PlotKit.SweetCanvasRenderer.__super__ = PlotKit.CanvasRenderer.prototype;
+
+// ---------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------
+
+PlotKit.SweetCanvasRenderer.prototype.__init__ = function(el, layout, opts) { 
+    var moreOpts = PlotKit.Base.officeBlue();
+    MochiKit.Base.update(moreOpts, opts);
+    PlotKit.SweetCanvasRenderer.__super__.__init__.call(this, el, layout, moreOpts);
+};
+
+// ---------------------------------------------------------------------
+// Extended Plotting Functions
+// ---------------------------------------------------------------------
+
+PlotKit.SweetCanvasRenderer.prototype._renderBarChart = function() {
+    var bind = MochiKit.Base.bind;
+    var shadowColor = Color.blackColor().colorWithAlpha(0.1).toRGBString();
+
+    var prepareFakeShadow = function(context, x, y, w, h) {
+        context.fillStyle = shadowColor;
+        context.fillRect(x-2, y-2, w+4, h+2); 
+        context.fillStyle = shadowColor;
+        context.fillRect(x-1, y-1, w+2, h+1); 
+    };
+
+    var colorCount = this.options.colorScheme.length;
+    var colorScheme =  this.options.colorScheme;
+    var setNames = MochiKit.Base.keys(this.layout.datasets);
+    var setCount = setNames.length;
+
+    var chooseColor = function(name) {
+        for (var i = 0; i < setCount; i++) {
+            if (name == setNames[i])
+                return colorScheme[i%colorCount];
+        }
+        return colorScheme[0];
+    };
+
+    var drawRect = function(context, bar) {
+        var x = this.area.w * bar.x + this.area.x;
+        var y = this.area.h * bar.y + this.area.y;
+        var w = this.area.w * bar.w;
+        var h = this.area.h * bar.h;
+
+        if ((w < 1) || (h < 1))
+            return;        
+
+        context.save();
+
+        context.shadowBlur = 5.0;
+        context.shadowColor = Color.fromHexString("#888888").toRGBString();
+
+        if (this.isIE) {
+            context.save();
+            context.fillStyle = "#cccccc";
+            context.fillRect(x-2, y-2, w+4, h+2); 
+            context.restore();
+        }
+        else {
+            prepareFakeShadow(context, x, y, w, h);
+        }
+
+        context.fillStyle = chooseColor(bar.name).toRGBString();
+        context.fillRect(x, y, w, h);
+
+        context.shadowBlur = 0;
+        context.strokeStyle = Color.whiteColor().toRGBString();
+        context.lineWidth = 2.0;
+
+        context.strokeRect(x, y, w, h);                
+
+        context.restore();
+
+    };
+    this._renderBarChartWrap(this.layout.bars, bind(drawRect, this));
+};
+
+PlotKit.CanvasRenderer.prototype._renderLineChart = function() {
+    var context = this.element.getContext("2d");
+    var colorCount = this.options.colorScheme.length;
+    var colorScheme = this.options.colorScheme;
+    var setNames = MochiKit.Base.keys(this.layout.datasets);
+    var setCount = setNames.length;
+    var bind = MochiKit.Base.bind;
+
+
+    for (var i = 0; i < setCount; i++) {
+        var setName = setNames[i];
+        var color = colorScheme[i%colorCount];
+        var strokeX = this.options.strokeColorTransform;
+
+        // setup graphics context
+        context.save();
+        
+        // create paths
+        var makePath = function() {
+            context.beginPath();
+            context.moveTo(this.area.x, this.area.y + this.area.h);
+            var addPoint = function(context, point) {
+            if (point.name == setName)
+                context.lineTo(this.area.w * point.x + this.area.x,
+                               this.area.h * point.y + this.area.y);
+            };
+            MochiKit.Iter.forEach(this.layout.points, partial(addPoint, context), this);
+            context.lineTo(this.area.w + this.area.x,
+                           this.area.h + this.area.y);
+            context.lineTo(this.area.x, this.area.y + this.area.h);
+            context.closePath();
+        };
+
+        // faux shadow for firefox
+        context.save();
+        if (this.isIE) {
+            context.fillStyle = "#cccccc";
+        }
+        else {
+            context.fillStyle = Color.blackColor().colorWithAlpha(0.2).toRGBString();
+        }
+
+        context.translate(-1, -2);
+        bind(makePath, this)();        
+        context.fill();
+        context.restore();
+
+        context.shadowBlur = 5.0;
+        context.shadowColor = Color.fromHexString("#888888").toRGBString();
+        context.fillStyle = color.toRGBString();
+        context.lineWidth = 2.0;
+        context.strokeStyle = Color.whiteColor().toRGBString();
+
+        bind(makePath, this)();
+        context.fill();
+        bind(makePath, this)();
+        context.stroke();
+
+        context.restore();
+    }
+};
+
+PlotKit.CanvasRenderer.prototype._renderPieChart = function() {
+    var context = this.element.getContext("2d");
+
+    var colorCount = this.options.colorScheme.length;
+    var slices = this.layout.slices;
+
+    var centerx = this.area.x + this.area.w * 0.5;
+    var centery = this.area.y + this.area.h * 0.5;
+    var radius = Math.min(this.area.w * this.options.pieRadius, 
+                          this.area.h * this.options.pieRadius);
+
+    if (this.isIE) {
+        centerx = parseInt(centerx);
+        centery = parseInt(centery);
+        radius = parseInt(radius);
+    }
+
+	// NOTE NOTE!! Canvas Tag draws the circle clockwise from the y = 0, x = 1
+	// so we have to subtract 90 degrees to make it start at y = 1, x = 0
+
+    if (!this.isIE) {
+        context.save();
+        var shadowColor = Color.blackColor().colorWithAlpha(0.2);
+        context.fillStyle = shadowColor.toRGBString();
+        context.shadowBlur = 5.0;
+        context.shadowColor = Color.fromHexString("#888888").toRGBString();
+        context.translate(1, 1);
+        context.beginPath();
+        context.moveTo(centerx, centery);
+        context.arc(centerx, centery, radius + 2, 0, Math.PI*2, false);
+        context.closePath();
+        context.fill();
+        context.restore();
+    }
+
+    context.save();
+    context.strokeStyle = Color.whiteColor().toRGBString();
+    context.lineWidth = 2.0;    
+    for (var i = 0; i < slices.length; i++) {
+        var color = this.options.colorScheme[i%colorCount];
+        context.fillStyle = color.toRGBString();
+
+        var makePath = function() {
+            context.beginPath();
+            context.moveTo(centerx, centery);
+            context.arc(centerx, centery, radius, 
+                        slices[i].startAngle - Math.PI/2,
+                        slices[i].endAngle - Math.PI/2,
+                        false);
+            context.lineTo(centerx, centery);
+            context.closePath();
+        };
+
+        if (Math.abs(slices[i].startAngle - slices[i].endAngle) > 0.0001) {
+            makePath();
+            context.fill();
+            makePath();
+            context.stroke();
+        }
+    }
+    context.restore();
+};
+
+PlotKit.SweetCanvasRenderer.prototype._renderBackground = function() {
+    var context = this.element.getContext("2d");
+   
+    if (this.layout.style == "bar" || this.layout.style == "line") {
+        context.save();
+        context.fillStyle = this.options.backgroundColor.toRGBString();
+        context.fillRect(this.area.x, this.area.y, this.area.w, this.area.h);
+        context.strokeStyle = Color.whiteColor().toRGBString();
+        context.lineWidth = 1.0;
+        for (var i = 0; i < this.layout.yticks.length; i++) {
+            var y = this.layout.yticks[i][0] * this.area.h + this.area.y;
+            var x = this.area.x;
+            context.beginPath();
+            context.moveTo(x, y);
+            context.lineTo(x + this.area.w, y);
+            context.closePath();
+            context.stroke();
+        }
+        context.restore();
+    }
+    else {
+        PlotKit.SweetCanvasRenderer.__super__._renderBackground.call(this);
+    }
+};

Added: incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/plotkit/SweetSVG.js
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/plotkit/SweetSVG.js?view=auto&rev=467601
==============================================================================
--- incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/plotkit/SweetSVG.js (added)
+++ incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/plotkit/SweetSVG.js Wed Oct 25 03:59:16 2006
@@ -0,0 +1,196 @@
+/*
+    PlotKit Sweet SVG Renderer
+    ==========================
+    SVG Renderer for PlotKit which looks pretty!
+
+    Copyright
+    ---------
+    Copyright 2005,2006 (c) Alastair Tse <alastair^liquidx.net>
+    For use under the BSD license. <http://www.liquidx.net/plotkit>
+*/
+
+
+// -------------------------------------------------------------------------
+// Check required components
+// -------------------------------------------------------------------------
+
+try {    
+    if (typeof(PlotKit.SVGRenderer) == 'undefined')
+    {
+        throw "";    
+    }
+} 
+catch (e) {    
+    throw "SweetSVG depends on MochiKit.{Base,Color,DOM,Format} and PlotKit.{Layout, SVG}"
+}
+
+
+if (typeof(PlotKit.SweetSVGRenderer) == 'undefined') {
+    PlotKit.SweetSVGRenderer = {};
+}
+
+PlotKit.SweetSVGRenderer = function(element, layout, options) {
+    if (arguments.length > 0) {
+        this.__init__(element, layout, options);
+    }
+};
+
+PlotKit.SweetSVGRenderer.NAME = "PlotKit.SweetSVGRenderer";
+PlotKit.SweetSVGRenderer.VERSION = PlotKit.VERSION;
+
+PlotKit.SweetSVGRenderer.__repr__ = function() {
+    return "[" + this.NAME + " " + this.VERSION + "]";
+};
+
+PlotKit.SweetSVGRenderer.toString = function() {
+    return this.__repr__();
+};
+
+// ---------------------------------------------------------------------
+// Subclassing Magic
+// ---------------------------------------------------------------------
+
+PlotKit.SweetSVGRenderer.prototype = new PlotKit.SVGRenderer();
+PlotKit.SweetSVGRenderer.prototype.constructor = PlotKit.SweetSVGRenderer;
+PlotKit.SweetSVGRenderer.__super__ = PlotKit.SVGRenderer.prototype;
+
+// ---------------------------------------------------------------------
+// Constructor
+// ---------------------------------------------------------------------
+
+PlotKit.SweetSVGRenderer.prototype.__init__ = function(element, layout, options) { 
+    var moreOpts = PlotKit.Base.officeBlue();
+    MochiKit.Base.update(moreOpts, options);
+    PlotKit.SweetSVGRenderer.__super__.__init__.call(this, element, layout, moreOpts);
+    //this._addDropShadowFilter();
+};
+
+PlotKit.SweetSVGRenderer.prototype._addDropShadowFilter = function() {
+    var filter = this.createSVGElement("filter", {x: 0, y: 0, "id":"dropShadow"});
+    var goffset = this.createSVGElement("feOffset",
+        {"in": "SourceGraphic", "dx": 0, "dy": 0, "result": "topCopy"});
+    var blur = this.createSVGElement("feGaussianBlur",
+        {"in": "SourceAlpha", "StdDeviation": 2, "result": "shadow"});
+    var soffset = this.createSVGElement("feOffset",
+        {"in": "shadow", "dx": -1, "dy": -2, "result":"movedShadow"});
+    var merge = this.createSVGElement("feMerge");
+    var gmerge = this.createSVGElement("feMergeNode", {"in":"topCopy"});
+    var smerge = this.createSVGElement("feMergeNode", {"in":"movedShadow"});
+    
+    merge.appendChild(gmerge);
+    merge.appendChild(smerge);
+    filter.appendChild(goffset);
+    filter.appendChild(blur);
+    filter.appendChild(soffset);
+    filter.appendChild(merge);
+    this.defs.appendChild(filter);
+};
+
+// ---------------------------------------------------------------------
+// Extended Plotting Functions
+// ---------------------------------------------------------------------
+
+PlotKit.SweetSVGRenderer.prototype._renderBarChart = function() {
+    var bind = MochiKit.Base.bind;
+    var shadowColor = Color.blackColor().toRGBString();
+    var shadowStyle = "fill:" + shadowColor + ";fill-opacity:0.15";
+    var strokeStyle = "stroke-width: 2.0; stroke:" + Color.whiteColor().toRGBString();
+    
+    var drawRect = function(attrs, bar) {
+        var x = this.area.w * bar.x + this.area.x;
+        var y = this.area.h * bar.y + this.area.y;
+        var w = this.area.w * bar.w;
+        var h = this.area.h * bar.h;
+
+        if ((w < 1) || (h < 1))
+            return;        
+
+        //attrs["filter"] = "url(#dropShadow)";
+        attrs["style"] = strokeStyle;
+        this._drawRect(x - 2, y - 1, w+4, h+2, {"style":shadowStyle});
+        this._drawRect(x, y, w, h, attrs);
+    };
+    this._renderBarOrLine(this.layout.bars, bind(drawRect, this));
+
+};
+
+PlotKit.SweetSVGRenderer.prototype._renderLineChart = function() {
+    var bind = MochiKit.Base.bind;
+    var shadowColor = Color.blackColor().toRGBString();
+    var shadowStyle = "fill:" + shadowColor + ";fill-opacity:0.15";
+    var strokeStyle = "stroke-width: 2.0; stroke:" + Color.whiteColor().toRGBString();
+
+    var addPoint = function(attrs, point) {
+        this._tempPointsBuffer += (this.area.w * point.x + this.area.x) + "," +
+                                 (this.area.h * point.y + this.area.y) + " ";
+    };
+
+    var startLine = function(attrs) {
+        this._tempPointsBuffer = "";
+        this._tempPointsBuffer += (this.area.x) + "," + (this.area.y+this.area.h) + " ";
+    };
+
+    var endLine = function(attrs) {
+        this._tempPointsBuffer += (this.area.w + this.area.x) + ","  +(this.area.h + this.area.y);
+        attrs["points"] = this._tempPointsBuffer;    
+            
+        attrs["stroke"] = "none";
+        attrs["transform"] = "translate(-2, -1)";
+        attrs["style"] = shadowStyle;
+        var shadow = this.createSVGElement("polygon", attrs);
+        this.root.appendChild(shadow);
+        
+        attrs["transform"] = "";
+        attrs["style"] = strokeStyle;
+        var elem = this.createSVGElement("polygon", attrs);
+        this.root.appendChild(elem);
+        
+       
+    };
+
+    this._renderBarOrLine(this.layout.points, 
+                             bind(addPoint, this), 
+                             bind(startLine, this), 
+                             bind(endLine, this));
+};
+
+PlotKit.SweetSVGRenderer.prototype._renderPieChart = function() {
+    var centerx = this.area.x + this.area.w * 0.5;
+    var centery = this.area.y + this.area.h * 0.5;
+    var shadowColor = Color.blackColor().toRGBString();
+    var radius = Math.min(this.area.w * this.options.pieRadius, 
+                          this.area.h * this.options.pieRadius);
+    var shadowStyle = "fill:" + shadowColor + ";fill-opacity:0.15";
+    
+    var shadow = this.createSVGElement("circle", 
+        {"style": shadowStyle, "cx": centerx + 1, "cy": centery + 1, "r": radius + 1});
+    this.root.appendChild(shadow);
+                             
+    PlotKit.SweetSVGRenderer.__super__._renderPieChart.call(this);
+};
+    
+
+PlotKit.SweetSVGRenderer.prototype._renderBackground = function() {
+    var attrs = {
+        "fill": this.options.backgroundColor.toRGBString(),
+        "stroke": "none"
+    };
+    
+
+    if (this.layout.style == "bar" || this.layout.style == "line") {
+        this._drawRect(this.area.x, this.area.y, 
+                       this.area.w, this.area.h, attrs);                
+        for (var i = 0; i < this.layout.yticks.length; i++) {
+            this._drawRect(this.area.x,
+                           this.layout.yticks[i][0] * this.area.h + this.area.y,
+                           this.area.w,
+                           1,
+                           {"fill": Color.whiteColor().toRGBString()});
+        }
+    }
+    else {
+        PlotKit.SweetSVGRenderer.__super__._renderBackground.call(this);
+        
+    }
+    
+};

Added: incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/plotkit/dummy.svg
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/plotkit/dummy.svg?view=auto&rev=467601
==============================================================================
--- incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/plotkit/dummy.svg (added)
+++ incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/plotkit/dummy.svg Wed Oct 25 03:59:16 2006
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+    Copyright
+    ---------
+    Copyright 2005,2006 (c) Alastair Tse <alastair^liquidx.net>
+    For use under the BSD license. <http://www.liquidx.net/plotkit>
+-->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink">
+</svg>

Added: incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/plotkit/iecanvas.htc
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/plotkit/iecanvas.htc?view=auto&rev=467601
==============================================================================
--- incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/plotkit/iecanvas.htc (added)
+++ incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/plotkit/iecanvas.htc Wed Oct 25 03:59:16 2006
@@ -0,0 +1,389 @@
+/*----------------------------------------------------------------------------\
+|                                IE Canvas 1.0                                |
+|-----------------------------------------------------------------------------|
+|                          Created by Emil A Eklund                           |
+|                        (http://eae.net/contact/emil)                        |
+|-----------------------------------------------------------------------------|
+| Implementation of the canvas API for Internet Explorer. Uses VML.           |
+|-----------------------------------------------------------------------------|
+|                      Copyright (c) 2005 Emil A Eklund                       |
+|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -|
+| This program is  free software;  you can redistribute  it and/or  modify it |
+| under the terms of the MIT License.                                         |
+|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -|
+| Permission  is hereby granted,  free of charge, to  any person  obtaining a |
+| copy of this software and associated documentation files (the "Software"),  |
+| to deal in the  Software without restriction,  including without limitation |
+| the  rights to use, copy, modify,  merge, publish, distribute,  sublicense, |
+| and/or  sell copies  of the  Software, and to  permit persons to  whom  the |
+| Software is  furnished  to do  so, subject  to  the  following  conditions: |
+| The above copyright notice and this  permission notice shall be included in |
+| all copies or substantial portions of the Software.                         |
+|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -|
+| THE SOFTWARE IS PROVIDED "AS IS",  WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
+| IMPLIED,  INCLUDING BUT NOT LIMITED TO  THE WARRANTIES  OF MERCHANTABILITY, |
+| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
+| AUTHORS OR  COPYRIGHT  HOLDERS BE  LIABLE FOR  ANY CLAIM,  DAMAGES OR OTHER |
+| LIABILITY, WHETHER  IN AN  ACTION OF CONTRACT, TORT OR  OTHERWISE,  ARISING |
+| FROM,  OUT OF OR  IN  CONNECTION  WITH  THE  SOFTWARE OR THE  USE OR  OTHER |
+| DEALINGS IN THE SOFTWARE.                                                   |
+|- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -|
+|                         http://eae.net/license/mit                          |
+|-----------------------------------------------------------------------------|
+| Dependencies: canvas.js           - For initialization of canvas elements   |
+|-----------------------------------------------------------------------------|
+| 2005-12-27 | Work started.                                                  |
+| 2005-12-29 | First version posted.                                          |
+| 2006-01-03 | Fixed bug in moveTo and lineTo,  arguments where not converted |
+|            | to int which could cause IE to enter an endless loop. Disabled |
+|            | antalias for fillRect to better comply with the Mozilla, Opera |
+|            | and possibly  Safari  implementations where  using fillRect is |
+|            | about the only way to raw non antialiased lines.               |
+|-----------------------------------------------------------------------------|
+| Created 2005-12-27 | All changes are in the log above. | Updated 2006-01-03 |
+\----------------------------------------------------------------------------*/
+
+<public:component>
+	<public:method name="getContext" />
+	<public:attach event="oncontentready" onevent="initCanvas()"/>
+</public:component>
+
+<script language="JScript">
+
+	function getContext() {
+		return element.context;
+	}
+
+	function initCanvas() {
+		element.context = new IECanvasContext();
+		element.style.position = 'relative';
+		element.style.display  = 'block';
+		element.style.overflow = 'hidden';
+	}
+
+
+
+	function IECanvasContext() {
+		this.fillStyle = 'black';
+		this.globalAlpha = 1.0;
+		this.globalCompositeOperation = '';
+		this.lineCap = '';
+		this.lineJoin = '';
+		this.lineWidth = '0';
+		this.miterLimit = '';
+		this.shadowBlur = '';
+		this.shadowColor = '';
+		this.shadowOffsetX = '';
+		this.shadowOffsetY = '';
+		this.strokeStyle = 'black';
+		this._path = '';
+		this._stateStack = new Array();
+		this._offsetX = 0;
+		this._offsetY = 0;
+		this._rotation = 0;
+	};
+
+	IECanvasContext.prototype.save = function() {
+		var o;
+
+		o = new Object();
+		this._copyState(this, o);
+		this._stateStack.push(o);
+	};
+
+	IECanvasContext.prototype.restore = function() {
+		var o, n;
+
+		n = this._stateStack.length - 1;
+		if (n < 0) { return; }
+
+		o = this._stateStack[n];
+		this._copyState(o, this);
+		this._stateStack.splice(n, 1);
+	};
+
+	IECanvasContext.prototype._copyState = function(oFrom, oTo) {
+		oTo.fillStyle     = oFrom.fillStyle;
+		oTo.lineCap       = oFrom.lineCap;
+		oTo.lineJoin      = oFrom.lineJoin;
+		oTo.lineWidth     = oFrom.lineWidth;
+		oTo.miterLimit    = oFrom.miterLimit;
+		oTo.shadowBlur    = oFrom.shadowBlur;
+		oTo.shadowColor   = oFrom.shadowColor;
+		oTo.shadowOffsetX = oFrom.shadowOffsetX;
+		oTo.shadowOffsetY = oFrom.shadowOffsetY;
+		oTo._offsetX      = oFrom._offsetX;
+		oTo._offsetY      = oFrom._offsetY;
+		oTo._rotation     = oFrom._rotation;
+	};
+
+	IECanvasContext.prototype.rotate = function(r) {
+		var MAX = Math.PI * 2;
+
+		this._rotation += r;
+		while (this._rotation > MAX) { this._rotation = MAX - this._rotation; }
+	};
+
+	IECanvasContext.prototype.scale = function() { };
+
+	IECanvasContext.prototype.translate = function(x, y) {
+		this._offsetX += x;
+		this._offsetY += y;
+	};
+
+	IECanvasContext.prototype.bezierCurveTo = function(cp1x, cp1y, cp2x, cp2y, x, y) {
+		if (this._path) { this._path += ' '; }
+
+		this._path += 'qb' + cp1x + ',' + cp1y + ',' + cp2x + ',' + cp2y + ',' + x + ',' + y;
+	};
+
+
+	IECanvasContext.prototype.clip = function() { };
+
+	IECanvasContext.prototype.beginPath = function() {
+		this._path = '';
+	};
+
+	IECanvasContext.prototype.closePath = function() {
+		if (this._path) { this._path += ' '; }
+		this._path += 'x';
+	};
+
+	IECanvasContext.prototype.lineTo = function(x, y) {
+		if (this._path) { this._path += ' '; }
+		this._path += 'l' + parseInt(x) + ',' + parseInt(y);
+	};
+
+	IECanvasContext.prototype.moveTo = function(x, y) {
+		if (this._path) { this._path += ' '; }
+		this._path += 'm' + parseInt(x) + ',' + parseInt(y);
+	};
+
+	IECanvasContext.prototype.stroke = function() {
+		var o, s, cosa, sina, cx, cy, x, y;
+
+		if (!this._path) { return; }
+
+		this._path += ' e';
+
+		o = element.ownerDocument.createElement('v:shape');
+		o.fillColor = 'none';
+		o.filled = false;
+		o.strokeColor = this.strokeStyle;
+		o.stroked = true;
+		o.weight = this.lineWidth;
+		o.coordsize = element.offsetWidth + ',' + element.offsetHeight;
+		o.style.position = 'absolute';
+		o.style.left = this._offsetX;
+		o.style.top = this._offsetY;
+		o.style.width = element.offsetWidth;
+		o.style.height = element.offsetHeight;
+		o.path = this._path;
+
+		s = element.ownerDocument.createElement('v:stroke');
+		s.opacity = this.globalAlpha;
+		o.appendChild(s);
+
+		if (this._rotation) {
+			r = element.ownerDocument.createElement('v:group');
+			r.style.position = 'absolute';
+			r.style.left = 0;
+			r.style.top = 0;
+			r.style.width = element.offsetWidth;
+			r.style.height = element.offsetHeight;
+			r.coordsize = o.coordsize;
+			r.style.rotation = Math.round((this._rotation * 180) / Math.PI);
+			r.style.rotationCenter = '0,0';
+			r.appendChild(o);
+			element.appendChild(r);
+
+			cosa = Math.cos(this._rotation);
+			sina = Math.sin(this._rotation);
+			cx = element.offsetWidth / 2;
+			cy = element.offsetHeight / 2;
+
+			x = ( cx*(1-cosa) + cy*sina);
+			y = (-cx*sina     + cy*(1-cosa));
+
+			r.style.left = x * -1;
+			r.style.top = y * -1;
+		}
+		else { element.appendChild(o); }
+	};
+
+	IECanvasContext.prototype.fill = function() {
+		var o, f, r;
+
+		if (!this._path) { return; }
+
+		this._path += ' e';
+
+		o = element.ownerDocument.createElement('v:shape');
+		o.fillColor = this.fillStyle;
+		o.strokeColor = this.strokeStyle;
+		o.stroked = false;
+		o.weight = this.lineWidth;
+		o.coordsize = element.offsetWidth + ',' + element.offsetHeight;
+		o.style.position = 'absolute';
+		o.style.left = this._offsetX;
+		o.style.top = this._offsetY;
+		o.style.width = element.offsetWidth;
+		o.style.height = element.offsetHeight;
+		o.path = this._path;
+
+		f = element.ownerDocument.createElement('v:fill');
+		f.opacity = this.globalAlpha;
+		o.appendChild(f);
+
+		if (this._rotation) {
+			r = element.ownerDocument.createElement('v:group');
+			r.style.position = 'absolute';
+			r.style.left = 0;
+			r.style.top = 0;
+			r.style.width = element.offsetWidth;
+			r.style.height = element.offsetHeight;
+			r.coordsize = o.coordsize;
+			r.style.rotation = Math.round((this._rotation * 180) / Math.PI);
+			r.style.rotationCenter = '0,0';
+			r.appendChild(o);
+			element.appendChild(r);
+
+			cosa = Math.cos(this._rotation);
+			sina = Math.sin(this._rotation);
+			cx = (element.offsetWidth) / 2;
+			cy = (element.offsetHeight) / 2;
+			x = ( cx*(1-cosa) + cy*sina);
+			y = (-cx*sina     + cy*(1-cosa));
+
+			r.style.left = x * -1;
+			r.style.top = y * -1;
+		}
+		else { element.appendChild(o); }
+	};
+
+	IECanvasContext.prototype.arcTo = function(x1, y1, x2, y2, radius) {
+		// not implemented in gecko, not implemented here
+	};
+
+	IECanvasContext.prototype.quadraticCurveTo = function(cpx, cpy, x, y) {
+		if (this._path) { this._path += ' '; }
+
+		this._path += 'qb' + cpx + ',' + cpy + ',' + x + ',' + y;
+	};
+
+	IECanvasContext.prototype.arc = function(x, y, radius, startAngle, endAngle, clockwise) {
+		var xi, yi, x1, y1, x2, y2, x3, y3, x4, y4;
+
+		if (this._path) { this._path += ' '; }
+
+		xi = parseFloat(x);
+		yi = parseFloat(y);
+
+        x1 = xi - radius;
+        y1 = yi - radius;
+        
+        x2 = xi + radius;
+        y2 = yi + radius;
+
+        if (clockwise) {
+            x3 = xi + (Math.cos(startAngle) * radius);
+            y3 = yi + (Math.sin(startAngle) * radius);
+
+            x4 = xi + (Math.cos(endAngle) * radius);
+            y4 = yi + (Math.sin(endAngle) * radius);
+        }
+        else {
+            x3 = xi + (Math.cos(endAngle) * radius);
+            y3 = yi + (Math.sin(endAngle) * radius);
+
+            x4 = xi + (Math.cos(startAngle) * radius);
+            y4 = yi + (Math.sin(startAngle) * radius);
+        }
+
+		x3 = Math.round(x3);
+		y3 = Math.round(y3);
+		x4 = Math.round(x4);
+		y4 = Math.round(y4);
+
+		this._path += 'ar' + x1 + ',' + y1 + ',' + x2 + ',' + y2 + ',' + x3 + ',' + y3 + ',' + x4 + ',' + y4;
+	};
+
+
+	IECanvasContext.prototype.rect = function(x, y, w, h) {
+		var x1, y1, x2, y2;
+
+		x2 = x + w;
+		y2 = y + h;
+
+		x1 = Math.round(x);
+		y1 = Math.round(y);
+		x2 = Math.round(x2);
+		y2 = Math.round(y2);
+
+		this._path += 'm' + x1 + ',' + y1;
+		this._path += ' l' + x2 + ',' + y1;
+		this._path += ' l' + x2 + ',' + y2;
+		this._path += ' l' + x1 + ',' + y2;
+		this._path += ' x'
+	};
+
+	IECanvasContext.prototype.strokeRect = function(x, y, w, h) {
+		var o, s;
+
+		o = element.ownerDocument.createElement('v:rect');
+		o.fillColor = 'none';
+		o.filled = false;
+		o.strokeColor = this.strokeStyle;
+		o.stroked = true;
+		o.weight = this.lineWidth;
+		o.style.position = 'absolute';
+		o.style.left = this._offsetX + x;
+		o.style.top = this._offsetY + y;
+		o.style.width = w;
+		o.style.height = h;
+
+		s = element.ownerDocument.createElement('v:fill');
+		s.opacity = this.globalAlpha;
+		o.appendChild(s);
+
+		element.appendChild(o);
+	};
+
+	IECanvasContext.prototype.clearRect = function(x, y, w, h) { };
+
+
+	IECanvasContext.prototype.fillRect = function(x, y, w, h) {
+		var o, f;
+		
+		if ((x == 0) && (y == 0) && (w == element.offsetWidth) && (h == element.offsetHeight) && (this._offsetX == 0) && (this._offsetY == 0) && (this.globalAlpha == 1)) {
+			while (element.firstChild) { element.removeChild(element.lastChild); }
+		}
+
+		o = element.ownerDocument.createElement('v:rect');
+		o.fillColor = this.fillStyle;
+		o.filled = true;
+		o.stroked = false;
+		o.weight = 0;
+		o.style.position = 'absolute';
+		o.style.left = this._offsetX + x;
+		o.style.top = this._offsetY + y;
+		o.style.width = w;
+		o.style.height = h;
+		o.style.antialias = 'false';
+
+		f = element.ownerDocument.createElement('v:fill');
+		f.opacity = this.globalAlpha;
+		o.appendChild(f);
+
+		element.appendChild(o);
+	};
+
+	IECanvasContext.prototype.addColorStop = function() { };
+	IECanvasContext.prototype.createLinearGradient = function() { };
+	IECanvasContext.prototype.createPattern = function() { };
+	IECanvasContext.prototype.createRadialGradient = function() { };
+
+	IECanvasContext.prototype.drawImage = function() { };
+	IECanvasContext.prototype.drawImageFromRect = function() { };
+
+</script>

Added: incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/standardista-table-sorting.js
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/standardista-table-sorting.js?view=auto&rev=467601
==============================================================================
--- incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/standardista-table-sorting.js (added)
+++ incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/js/standardista-table-sorting.js Wed Oct 25 03:59:16 2006
@@ -0,0 +1,428 @@
+/**
+ * Written by Neil Crosby. 
+ * http://www.workingwith.me.uk/articles/scripting/standardista_table_sorting
+ *
+ * This module is based on Stuart Langridge's "sorttable" code.  Specifically, 
+ * the determineSortFunction, sortCaseInsensitive, sortDate, sortNumeric, and
+ * sortCurrency functions are heavily based on his code.  This module would not
+ * have been possible without Stuart's earlier outstanding work.
+ *
+ * Use this wherever you want, but please keep this comment at the top of this file.
+ *
+ * Copyright (c) 2006 Neil Crosby
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy 
+ * of this software and associated documentation files (the "Software"), to deal 
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 
+ * copies of the Software, and to permit persons to whom the Software is 
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in 
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
+ * SOFTWARE.
+ **/
+var standardistaTableSorting = {
+
+	that: false,
+	isOdd: false,
+
+	sortColumnIndex : -1,
+	lastAssignedId : 0,
+	newRows: -1,
+	lastSortedTable: -1,
+
+	/**
+	 * Initialises the Standardista Table Sorting module
+	 **/
+	init : function() {
+		// first, check whether this web browser is capable of running this script
+		if (!document.getElementsByTagName) {
+			return;
+		}
+		
+		this.that = this;
+		
+		this.run();
+		
+	},
+	
+	/**
+	 * Runs over each table in the document, making it sortable if it has a class
+	 * assigned named "sortable" and an id assigned.
+	 **/
+	run : function() {
+		var tables = document.getElementsByTagName("table");
+		
+		for (var i=0; i < tables.length; i++) {
+			var thisTable = tables[i];
+			
+			if (css.elementHasClass(thisTable, 'sortable')) {
+				this.makeSortable(thisTable);
+			}
+		}
+	},
+	
+	/**
+	 * Makes the given table sortable.
+	 **/
+	makeSortable : function(table) {
+	
+		// first, check if the table has an id.  if it doesn't, give it one
+		if (!table.id) {
+			table.id = 'sortableTable'+this.lastAssignedId++;
+		}
+		
+		// if this table does not have a thead, we don't want to know about it
+		if (!table.tHead || !table.tHead.rows || 0 == table.tHead.rows.length) {
+			return;
+		}
+		
+		// we'll assume that the last row of headings in the thead is the row that 
+		// wants to become clickable
+		var row = table.tHead.rows[table.tHead.rows.length - 1];
+		
+		for (var i=0; i < row.cells.length; i++) {
+		
+			// create a link with an onClick event which will 
+			// control the sorting of the table
+			var linkEl = createElement('a');
+			linkEl.href = '#';
+			linkEl.onclick = this.headingClicked;
+			linkEl.setAttribute('columnId', i);
+			linkEl.title = 'Click to sort';
+			
+			// move the current contents of the cell that we're 
+			// hyperlinking into the hyperlink
+			var innerEls = row.cells[i].childNodes;
+			for (var j = 0; j < innerEls.length; j++) {
+				linkEl.appendChild(innerEls[j]);
+			}
+			
+			// and finally add the new link back into the cell
+			row.cells[i].appendChild(linkEl);
+
+			var spanEl = createElement('span');
+			spanEl.className = 'tableSortArrow';
+			spanEl.appendChild(document.createTextNode('\u00A0\u00A0'));
+			row.cells[i].appendChild(spanEl);
+
+		}
+	
+		if (css.elementHasClass(table, 'autostripe')) {
+			this.isOdd = false;
+			var rows = table.tBodies[0].rows;
+		
+			// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
+			for (var i=0;i<rows.length;i++) { 
+				this.doStripe(rows[i]);
+			}
+		}
+	},
+	
+	headingClicked: function(e) {
+		
+		var that = standardistaTableSorting.that;
+		
+		// linkEl is the hyperlink that was clicked on which caused
+		// this method to be called
+		var linkEl = getEventTarget(e);
+		
+		// directly outside it is a td, tr, thead and table
+		var td     = linkEl.parentNode;
+		var tr     = td.parentNode;
+		var thead  = tr.parentNode;
+		var table  = thead.parentNode;
+		
+		// if the table we're looking at doesn't have any rows
+		// (or only has one) then there's no point trying to sort it
+		if (!table.tBodies || table.tBodies[0].rows.length <= 1) {
+			return false;
+		}
+
+		// the column we want is indicated by td.cellIndex
+		var column = linkEl.getAttribute('columnId') || td.cellIndex;
+		//var column = td.cellIndex;
+		
+		// find out what the current sort order of this column is
+		var arrows = css.getElementsByClass(td, 'tableSortArrow', 'span');
+		var previousSortOrder = '';
+		if (arrows.length > 0) {
+			previousSortOrder = arrows[0].getAttribute('sortOrder');
+		}
+		
+		// work out how we want to sort this column using the data in the first cell
+		// but just getting the first cell is no good if it contains no data
+		// so if the first cell just contains white space then we need to track
+		// down until we find a cell which does contain some actual data
+		var itm = ''
+		var rowNum = 0;
+		while ('' == itm && rowNum < table.tBodies[0].rows.length) {
+			itm = that.getInnerText(table.tBodies[0].rows[rowNum].cells[column]);
+			rowNum++;
+		}
+		var sortfn = that.determineSortFunction(itm);
+
+		// if the last column that was sorted was this one, then all we need to 
+		// do is reverse the sorting on this column
+		if (table.id == that.lastSortedTable && column == that.sortColumnIndex) {
+			newRows = that.newRows;
+			newRows.reverse();
+		// otherwise, we have to do the full sort
+		} else {
+			that.sortColumnIndex = column;
+			var newRows = new Array();
+
+			for (var j = 0; j < table.tBodies[0].rows.length; j++) { 
+				newRows[j] = table.tBodies[0].rows[j]; 
+			}
+
+			newRows.sort(sortfn);
+		}
+
+		that.moveRows(table, newRows);
+		that.newRows = newRows;
+		that.lastSortedTable = table.id;
+		
+		// now, give the user some feedback about which way the column is sorted
+		
+		// first, get rid of any arrows in any heading cells
+		var arrows = css.getElementsByClass(tr, 'tableSortArrow', 'span');
+		for (var j = 0; j < arrows.length; j++) {
+			var arrowParent = arrows[j].parentNode;
+			arrowParent.removeChild(arrows[j]);
+
+			if (arrowParent != td) {
+				spanEl = createElement('span');
+				spanEl.className = 'tableSortArrow';
+				spanEl.appendChild(document.createTextNode('\u00A0\u00A0'));
+				arrowParent.appendChild(spanEl);
+			}
+		}
+		
+		// now, add back in some feedback 
+		var spanEl = createElement('span');
+		spanEl.className = 'tableSortArrow';
+		if (null == previousSortOrder || '' == previousSortOrder || 'DESC' == previousSortOrder) {
+			spanEl.appendChild(document.createTextNode(' \u2191'));
+			spanEl.setAttribute('sortOrder', 'ASC');
+		} else {
+			spanEl.appendChild(document.createTextNode(' \u2193'));
+			spanEl.setAttribute('sortOrder', 'DESC');
+		}
+		
+		td.appendChild(spanEl);
+		
+		return false;
+	},
+
+	getInnerText : function(el) {
+		
+		if ('string' == typeof el || 'undefined' == typeof el) {
+			return el;
+		}
+		
+		if (el.innerText) {
+			return el.innerText;  // Not needed but it is faster
+		}
+
+		var str = el.getAttribute('standardistaTableSortingInnerText');
+		if (null != str && '' != str) {
+			return str;
+		}
+		str = '';
+
+		var cs = el.childNodes;
+		var l = cs.length;
+		for (var i = 0; i < l; i++) {
+			// 'if' is considerably quicker than a 'switch' statement, 
+			// in Internet Explorer which translates up to a good time 
+			// reduction since this is a very often called recursive function
+			if (1 == cs[i].nodeType) { // ELEMENT NODE
+				str += this.getInnerText(cs[i]);
+				break;
+			} else if (3 == cs[i].nodeType) { //TEXT_NODE
+				str += cs[i].nodeValue;
+				break;
+			}
+		}
+		
+		// set the innertext for this element directly on the element
+		// so that it can be retrieved early next time the innertext
+		// is requested
+		el.setAttribute('standardistaTableSortingInnerText', str);
+		
+		return str;
+	},
+
+	determineSortFunction : function(itm) {
+		
+		var sortfn = this.sortCaseInsensitive;
+		
+		if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d\d\d$/)) {
+			sortfn = this.sortDate;
+		}
+		if (itm.match(/^\d\d[\/-]\d\d[\/-]\d\d$/)) {
+			sortfn = this.sortDate;
+		}
+		if (itm.match(/^[£$]/)) {
+			sortfn = this.sortCurrency;
+		}
+		if (itm.match(/^\d?\.?\d+$/)) {
+			sortfn = this.sortNumeric;
+		}
+		if (itm.match(/^[+-]?\d*\.?\d+([eE]-?\d+)?$/)) {
+			sortfn = this.sortNumeric;
+		}
+    		if (itm.match(/^([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$/)) {
+        		sortfn = this.sortIP;
+   		}
+
+		return sortfn;
+	},
+	
+	sortCaseInsensitive : function(a, b) {
+		var that = standardistaTableSorting.that;
+		
+		var aa = that.getInnerText(a.cells[that.sortColumnIndex]).toLowerCase();
+		var bb = that.getInnerText(b.cells[that.sortColumnIndex]).toLowerCase();
+		if (aa==bb) {
+			return 0;
+		} else if (aa<bb) {
+			return -1;
+		} else {
+			return 1;
+		}
+	},
+	
+	sortDate : function(a,b) {
+		var that = standardistaTableSorting.that;
+
+		// y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
+		var aa = that.getInnerText(a.cells[that.sortColumnIndex]);
+		var bb = that.getInnerText(b.cells[that.sortColumnIndex]);
+		
+		var dt1, dt2, yr = -1;
+		
+		if (aa.length == 10) {
+			dt1 = aa.substr(6,4)+aa.substr(3,2)+aa.substr(0,2);
+		} else {
+			yr = aa.substr(6,2);
+			if (parseInt(yr) < 50) { 
+				yr = '20'+yr; 
+			} else { 
+				yr = '19'+yr; 
+			}
+			dt1 = yr+aa.substr(3,2)+aa.substr(0,2);
+		}
+		
+		if (bb.length == 10) {
+			dt2 = bb.substr(6,4)+bb.substr(3,2)+bb.substr(0,2);
+		} else {
+			yr = bb.substr(6,2);
+			if (parseInt(yr) < 50) { 
+				yr = '20'+yr; 
+			} else { 
+				yr = '19'+yr; 
+			}
+			dt2 = yr+bb.substr(3,2)+bb.substr(0,2);
+		}
+		
+		if (dt1==dt2) {
+			return 0;
+		} else if (dt1<dt2) {
+			return -1;
+		}
+		return 1;
+	},
+
+	sortCurrency : function(a,b) { 
+		var that = standardistaTableSorting.that;
+
+		var aa = that.getInnerText(a.cells[that.sortColumnIndex]).replace(/[^0-9.]/g,'');
+		var bb = that.getInnerText(b.cells[that.sortColumnIndex]).replace(/[^0-9.]/g,'');
+		return parseFloat(aa) - parseFloat(bb);
+	},
+
+	sortNumeric : function(a,b) { 
+		var that = standardistaTableSorting.that;
+
+		var aa = parseFloat(that.getInnerText(a.cells[that.sortColumnIndex]));
+		if (isNaN(aa)) { 
+			aa = 0;
+		}
+		var bb = parseFloat(that.getInnerText(b.cells[that.sortColumnIndex])); 
+		if (isNaN(bb)) { 
+			bb = 0;
+		}
+		return aa-bb;
+	},
+
+	makeStandardIPAddress : function(val) {
+		var vals = val.split('.');
+
+		for (x in vals) {
+			val = vals[x];
+
+			while (3 > val.length) {
+				val = '0'+val;
+			}
+			vals[x] = val;
+		}
+
+		val = vals.join('.');
+
+		return val;
+	},
+
+	sortIP : function(a,b) { 
+		var that = standardistaTableSorting.that;
+
+		var aa = that.makeStandardIPAddress(that.getInnerText(a.cells[that.sortColumnIndex]).toLowerCase());
+		var bb = that.makeStandardIPAddress(that.getInnerText(b.cells[that.sortColumnIndex]).toLowerCase());
+		if (aa==bb) {
+			return 0;
+		} else if (aa<bb) {
+			return -1;
+		} else {
+			return 1;
+		}
+	},
+
+	moveRows : function(table, newRows) {
+		this.isOdd = false;
+
+		// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
+		for (var i=0;i<newRows.length;i++) { 
+			var rowItem = newRows[i];
+
+			this.doStripe(rowItem);
+
+			table.tBodies[0].appendChild(rowItem); 
+		}
+	},
+	
+	doStripe : function(rowItem) {
+		if (this.isOdd) {
+			css.addClassToElement(rowItem, 'odd');
+		} else {
+			css.removeClassFromElement(rowItem, 'odd');
+		}
+		
+		this.isOdd = !this.isOdd;
+	}
+
+}
+
+function standardistaTableSortingInit() {
+	standardistaTableSorting.init();
+}
+
+addEvent(window, 'load', standardistaTableSortingInit)
\ No newline at end of file

Added: incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/service-assemblies.jsp
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/service-assemblies.jsp?view=auto&rev=467601
==============================================================================
--- incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/service-assemblies.jsp (added)
+++ incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/service-assemblies.jsp Wed Oct 25 03:59:16 2006
@@ -0,0 +1,67 @@
+<%--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+--%>
+<html>
+<head>
+<title>Service Assemblies</title>
+</head>
+<body>
+
+<h2>Deploy service assembly</h2>
+<form method="post" action="deployServiceAssembly.action" enctype="multipart/form-data">
+  <input type="file" name="file" />
+  <input type="submit" value="Deploy" />
+</form> 
+
+<h2>Service Assemblies</h2>
+
+<table id="serviceAssemblies" class="sortable autostripe">
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Status</th>
+      <th>Actions</th>
+    </tr>
+  </thead>
+  <tbody>
+    <c:forEach items="${requestContext.serviceAssemblies}" var="row">
+      <tr>
+        <td><a href="service-assembly.jsp?objectName=${row.objectName}">${row.name}</a></td>
+        <td>${row.status}</td>
+        <td>
+          <table class="align"><tr>
+          <c:if test="${row.status != 'Started'}">
+            <td class="align"><form method="post" action="startServiceAssembly.action"><input type="hidden" name="name" value="${row.name}"/><input type="submit" value="Start"/></form></td>
+          </c:if> 
+          <c:if test="${row.status == 'Started'}">
+            <td class="align"><form method="post" action="stopServiceAssembly.action"><input type="hidden" name="name" value="${row.name}"/><input type="submit" value="Stop"/></form></td>
+          </c:if> 
+          <c:if test="${row.status == 'Stopped'}">
+            <td class="align"><form method="post" action="shutdownServiceAssembly.action"><input type="hidden" name="name" value="${row.name}"/><input type="submit" value="Shutdown"/></form></td>
+          </c:if> 
+          <c:if test="${row.status == 'Shutdown'}">
+            <td class="align"><form method="post" action="uninstallServiceAssembly.action"><input type="hidden" name="name" value="${row.name}"/><input type="submit" value="Uninstall"/></form></td> 
+          </c:if> 
+          </tr></table>
+        </td>
+      </tr>
+    </c:forEach>
+  </tbody>
+</table>
+
+</body>
+</html>
+	

Added: incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/service-assembly.jsp
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/service-assembly.jsp?view=auto&rev=467601
==============================================================================
--- incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/service-assembly.jsp (added)
+++ incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/service-assembly.jsp Wed Oct 25 03:59:16 2006
@@ -0,0 +1,71 @@
+<%--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+--%>
+<html>
+<head>
+<title>Service Assembly</title>
+</head>
+<body>
+
+<h2>Service Assembly ${requestContext.serviceAssembly.name}</h2>
+
+<fieldset>
+  <legend>Service Assembly detail</legend>
+  <table>
+    <tbody>
+      <tr>
+        <th>Name</th>
+        <td><div class="field">${requestContext.serviceAssembly.name}</div></td>
+      </tr>
+      <tr>
+        <th>Description</th>
+        <td><div class="field">${requestContext.serviceAssembly.description}</div></td>
+      </tr>
+      <tr>
+        <th>Status</th>
+        <td><div class="field">${requestContext.serviceAssembly.status}</div></td>
+      </tr>
+    </tbody>
+  </table>
+</fieldset>
+
+<fieldset>
+  <legend>Service Units</legend>
+  <table id="serviceAssemblyServiceUnits" class="sortable autostripe">
+    <thead>
+        <tr>
+            <th>Name</th>
+            <th>Component</th>
+        </tr>
+    </thead>
+    <tbody>
+      <c:forEach items="${requestContext.serviceAssembly.serviceUnits}" var="row">
+        <tr>
+          <td>
+            <a href="service-unit.jsp?name=${row.name}">${row.name}</a>
+          </td>
+          <td>
+            <a href="component.jsp?name=${row.component.name}">${row.component.name}</a>
+          </td>
+        </tr>
+      </c:forEach>
+    </tbody>
+  </table>
+</fieldset>
+
+</body>
+</html>
+	

Added: incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/service-unit.jsp
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/service-unit.jsp?view=auto&rev=467601
==============================================================================
--- incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/service-unit.jsp (added)
+++ incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/service-unit.jsp Wed Oct 25 03:59:16 2006
@@ -0,0 +1,47 @@
+<%--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+--%>
+<html>
+<head>
+<title>Service Unit</title>
+</head>
+<body>
+
+<h2>Service Unit ${requestContext.serviceUnit.name}</h2>
+
+<fieldset>
+  <legend>Service Unit detail</legend>
+  <table>
+    <tbody>
+      <tr>
+        <th>Name</th>
+        <td><div class="field">${requestContext.serviceUnit.name}</div></td>
+      </tr>
+      <tr>
+        <th>Component</th>
+        <td><div class="field"><a href="component.jsp?name=${requestContext.serviceUnit.component.name}">${requestContext.serviceUnit.component.name}</a></div></td>
+      </tr>
+      <tr>
+        <th>Service Assembly</th>
+        <td><div class="field"><a href="service-assembly.jsp?name=${requestContext.serviceUnit.serviceAssembly.name}">${requestContext.serviceUnit.serviceAssembly.name}</a></div></td>
+      </tr>
+    </tbody>
+  </table>
+</fieldset>
+
+</body>
+</html>
+	

Added: incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/service-units.jsp
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/service-units.jsp?view=auto&rev=467601
==============================================================================
--- incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/service-units.jsp (added)
+++ incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/service-units.jsp Wed Oct 25 03:59:16 2006
@@ -0,0 +1,43 @@
+<%--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+--%>
+<html>
+<head>
+<title>Service Units</title>
+</head>
+<body>
+<h2>Service Units</h2>
+
+<table id="serviceUnits" class="sortable autostripe">
+  <thead>
+    <tr>
+      <th>Name</th>
+      <th>Component</th>
+    </tr>
+  </thead>
+  <tbody>
+    <c:forEach items="${requestContext.serviceUnits}" var="row">
+      <tr>
+        <td><a href="service-unit.jsp?objectName=${row.objectName}">${row.name}</a></td>
+        <td><a href="component.jsp?objectName=${row.component.objectName}">${row.component.name}</a></td>
+      </tr>
+    </c:forEach>
+  </tbody>
+</table>
+
+</body>
+</html>
+	

Added: incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/shared-libraries.jsp
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/shared-libraries.jsp?view=auto&rev=467601
==============================================================================
--- incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/shared-libraries.jsp (added)
+++ incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/shared-libraries.jsp Wed Oct 25 03:59:16 2006
@@ -0,0 +1,48 @@
+<%--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+--%>
+<html>
+<head>
+<title>Shared Libraries</title>
+</head>
+<body>
+
+<h2>Install shared library</h2>
+<form method="post" action="installSharedLibrary.action" enctype="multipart/form-data">
+  <input type="file" name="file" />
+  <input type="submit" value="Install" />
+</form> 
+
+<h2>Shared Libraries</h2>
+
+<table id="sharedLibraries" class="sortable autostripe">
+  <thead>
+    <tr>
+      <th>Name</th>
+    </tr>
+  </thead>
+  <tbody>
+    <c:forEach items="${requestContext.sharedLibraries}" var="row">
+      <tr>
+        <td><a href="shared-library.jsp?name=${row.name}">${row.name}</a></td>
+      </tr>
+    </c:forEach>
+  </tbody>
+</table>
+
+</body>
+</html>
+	

Added: incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/shared-library.jsp
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/shared-library.jsp?view=auto&rev=467601
==============================================================================
--- incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/shared-library.jsp (added)
+++ incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/shared-library.jsp Wed Oct 25 03:59:16 2006
@@ -0,0 +1,67 @@
+<%--
+    Licensed to the Apache Software Foundation (ASF) under one or more
+    contributor license agreements.  See the NOTICE file distributed with
+    this work for additional information regarding copyright ownership.
+    The ASF licenses this file to You 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.
+--%>
+<html>
+<head>
+<title>Shared Library ${requestContext.sharedLibrary.name}</title>
+</head>
+<body>
+
+<h2>Shared Library ${requestContext.sharedLibrary.name}</h2>
+
+<fieldset>
+  <legend>Shared Library detail</legend>
+  <table>
+    <tbody>
+      <tr>
+        <th>Name</th>
+        <td><div class="field">${requestContext.sharedLibrary.name}</div></td>
+      </tr>
+      <tr>
+        <th>Description</th>
+        <td><div class="field">${requestContext.sharedLibrary.description}</div></td>
+      </tr>
+      <tr>
+        <th>Version</th>
+        <td><div class="field">TODO</div></td>
+      </tr>
+    </tbody>
+  </table>
+</fieldset>
+
+<fieldset>
+  <legend>Components</legend>
+  <table id="sharedLibraryComponents" class="sortable autostripe">
+    <thead>
+        <tr>
+            <th>Name</th>
+        </tr>
+    </thead>
+    <tbody>
+      <c:forEach items="${requestContext.sharedLibrary.components}" var="row">
+        <tr>
+          <td>
+            <a href="component.jsp?name=${row.name}">${row.name}</a>
+          </td>
+        </tr>
+      </c:forEach>
+    </tbody>
+  </table>
+</fieldset>
+
+</body>
+</html>
+	

Added: incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/styles/sorttable.css
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/styles/sorttable.css?view=auto&rev=467601
==============================================================================
--- incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/styles/sorttable.css (added)
+++ incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/styles/sorttable.css Wed Oct 25 03:59:16 2006
@@ -0,0 +1,72 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+table {
+  margin: 0px;
+  padding: 0px;
+  border-collapse: collapse;
+  border-bottom: 1px solid #aaa;
+  border-right: 1px solid #aaa;
+  margin-bottom: 1em;
+
+  margin: 0em auto;
+  border-collapse: collapse;
+}
+
+th {
+  padding: 0em 0.5em;
+  text-align: left;
+  border: 1px solid black;
+  background-color: #cccccc;
+}
+
+tfoot {
+  border-top: 1px solid black;
+}
+
+td {
+  padding: 0em 0.5em;
+  border: 1px solid black; /** border-top: 1px solid black; */
+}
+
+tr {
+  background-color: #ffffff;
+}
+
+tr.odd {
+  background-color: #f3f3f3;
+}
+
+td.numeric,
+  th.numeric {
+  text-align: right;
+}
+
+/** forms using table layout */
+td.label {
+  background-color: #f3f3f3;
+}
+
+table.layout {
+  border-bottom: solid white;
+  border-right: solid white;
+}
+
+td.layout {
+  border-top: 1px solid black;
+  border: solid white;
+}

Added: incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/styles/style.css
URL: http://svn.apache.org/viewvc/incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/styles/style.css?view=auto&rev=467601
==============================================================================
--- incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/styles/style.css (added)
+++ incubator/servicemix/trunk/servicemix-web-console/src/main/webapp/styles/style.css Wed Oct 25 03:59:16 2006
@@ -0,0 +1,269 @@
+/*
+ * This CSS is licensed under the Creative Commons 2.5
+ * http://creativecommons.org/licenses/by/2.5/
+ *
+ * Css originally by mejobloggs  Design by Aran @ stuio7designs.com
+ * Please email me if you use this, as I would love to see how it is being used,
+ * also you can join my linkshare to help you with your google ranking
+ */
+
+body {
+  font-family: trebuchet ms, verdana, arial, tahoma;
+  font-size: 90%;
+  color: #888;
+  background-color: white;
+  line-height: 180%;
+  margin: 0;
+  padding: 0;
+}
+
+/* Set the page width */
+#wrapper-menu-top, #header, #wrapper-content, #wrapper-footer {
+  width: 85%;
+  margin: 0 auto;
+  text-align: left;
+}
+
+#wrapper-menu-top {
+  background: white url( '../images/bg02-white-left.png' ) no-repeat left top;
+}
+
+#menu-top {
+  background: transparent url( '../images/bg02-white-right.png' ) no-repeat right top;
+  overflow: hidden; /* no idea why this works, but it fixes a FF problem */
+  height: 3em;
+}
+
+#menu-top ul {
+  margin: 0 20px;
+  padding: 1em 0 0 0;
+  list-style: none;
+  font-size: 85%;
+  float: left;
+}
+
+#menu-top li {
+  display: inline;
+  float: left;
+}
+
+#menu-top a {
+  float: left;
+  background: url( ../images/menuleft.png ) no-repeat left top;
+  margin: 0;
+  padding: 0 0 0 4px;
+  text-decoration: none;
+  line-height: 1.5em;
+}
+
+#menu-top a span {
+  background: transparent url( ../images/menuright.png ) no-repeat right top;
+  padding: 5px 15px 4px 6px;
+  color: #5b8fbe;
+  display: block;
+  float: left;
+  cursor: pointer; /* IE doesnt display the hand when you roll over the link for some reason. This fixes it */
+}
+
+#menu-top a:hover {
+  background-position: 0% -42px;
+}
+
+#menu-top a:hover span {
+  background-position: 100% -42px;
+}
+
+#menu-left {
+  overflow: hidden; /* no idea why this works, but it fixes a FF problem */
+  padding-top: 5px;
+}
+
+#menu-left ul {
+  margin: 0 20px;
+  padding: 1em 0 0 0;
+  list-style: none;
+  font-size: 85%;
+  float: left;
+}
+
+#menu-left li {
+  display: inline;
+  float: left;
+}
+
+#menu-left a {
+  float: left;
+  background: url( ../images/menuleft.png ) no-repeat left top;
+  margin: 0;
+  padding: 0 0 0 4px;
+  text-decoration: none;
+  line-height: 1.5em;
+}
+
+#menu-left a span {
+  background: transparent url( ../images/menuright.png ) no-repeat right top;
+  padding: 5px 15px 4px 6px;
+  color: #5b8fbe;
+  display: block;
+  float: left;
+  cursor: pointer; /* IE doesnt display the hand when you roll over the link for some reason. This fixes it */
+  width: 110px;
+}
+
+#menu-left a:hover {
+  background-position: 0% -42px;
+}
+
+#menu-left a:hover span {
+  background-position: 100% -42px;
+}
+
+#wrapper-header {
+  background: transparent url( '../images/bg.png' ) top center repeat-x;
+}
+
+#header {
+  background: transparent url( '../images/banner_mountains.jpg' ) no-repeat center top;
+}
+
+#wrapper-header2 {
+  background: transparent url( '../images/bg02-blue-left.png' ) top left no-repeat;
+}
+
+#wrapper-header3 {
+  background: transparent url( '../images/bg02-blue-right.png' ) top right no-repeat;
+  padding: 5px;
+}
+
+#wrapper-header4 {
+  margin: 0px 20px;
+  padding: 0px 0px 0px 250px;
+  font-size: 200%;
+  min-height: 6em;
+  background: white url( '../images/servicemix.jpg' ) center left no-repeat;
+  text-align: center;
+}
+#wrapper-header4 div {
+  vertical-align: bottom;
+}
+#wrapper-header4 div div {
+  padding: 89px 10px 10px 10px;
+}
+
+#header h1 {
+  margin: 0 20px;
+  padding: 0;
+  height: 192px;
+  line-height: 3em;
+  color: #ccc;
+  font-size: 130%;
+}
+
+#wrapper-content {
+  background: white url( '../images/bg02-white-left.png' ) no-repeat left top;
+  min-height: 214px;
+}
+
+* html #wrapper-content {
+  height: 1%;
+}
+
+#content {
+  background: transparent url( '../images/bg02-white-right.png' ) no-repeat right top;
+  padding: 5px 25px 5px 210px;
+  display: block;
+  text-align: left;
+  min-height: 214px;
+}
+
+#wrapper-menu-page {
+  float: left;
+  width: 180px;
+  margin: 20px 30px 3em 2em;
+  background: transparent url( '../images/menu.png' ) no-repeat;
+  text-align: center;
+  line-height: 140%;
+  font-family: "Lucida Grande", "Lucida Sans Unicode", arial, sans-serif;
+}
+
+* html #wrapper-menu-page {
+  margin-right: 15px;
+}
+
+#menu-page {
+  padding-top: 5px;
+}
+
+#menu-page ul {
+  margin: 0;
+  padding: 0;
+  list-style: none;
+  font-size: 90%;
+}
+
+#menu-page h3 {
+  font-size: 75%;
+  text-transform: uppercase;
+  margin: 1em 0 0.3em 0;
+  color: #5b8fbe;
+  font-weight: normal;
+  letter-spacing: 0.15em;
+}
+
+#menu-page a:link, #menu-page a:visited {
+  color: #888;
+}
+
+#menu-page a:hover {
+  color: #5b8fbe;
+}
+
+#wrapper-footer {
+  margin-top: 1em;
+  text-align: center;
+}
+
+#footer {
+  margin: 0 20px;
+  background-color: #e5f0fc;
+  border: 1px solid #ccc;
+  border-bottom: 0;
+  clear: both;
+}
+
+h2 {
+  font-size: 110%;
+}
+
+h3 {
+  font-size: 100%;
+}
+
+a:link, a:visited {
+  color: #5b8fbe;
+  text-decoration: none;
+}
+
+a:hover {
+  color: #666;
+  text-decoration: none;
+}
+
+
+table.align {
+  padding: 0px;
+  border: none;
+}
+
+td.align {
+  padding: 0px;
+  border: none;
+}
+
+#error {
+  line-height: 100%;
+  border-style: solid; 
+  border-width: 1px;
+  padding: 1em;
+  overflow: scroll;
+}