		var kShadowPadding = 17;
		
		var kDefaultMagnifierSize = 3; // index into the arrays below
		
		var kMagnifierSizes = new Array(0, 100, 200, 300);
		var kMagnifierSizeNames = new Array('off', 'small', 'medium', 'large');
		
		var kControllerPrefix = 'magnifier:&nbsp;';
		var LeftImagePath;
		var RightImagePath;
		var PageWidth;
		var WidthAfterZooming;
		
		function MagnifierPosition()
		{			
			this.shadow.style.left = Math.round(this.xPosition - this.size/2 - kShadowPadding) + "px";
			this.shadow.style.top = Math.round(this.yPosition - this.size/2 - kShadowPadding) + "px";
			
			var magnifierCenterX = Math.round(this.xPosition * this.xMultiplier - this.size/2);
			var	magnifierCenterY = Math.round(this.yPosition * this.yMultiplier - this.size/2);
				
			this.style.backgroundPosition = -magnifierCenterX + "px " +
											-magnifierCenterY + "px";
			
	
			this.style.left = Math.round(this.xPosition - 1 - this.size/2) + "px";								
			this.style.backgroundPosition = -magnifierCenterX + "px " + -magnifierCenterY + "px";						
			
			if (RightImagePath != null)
			{
				if (this.xPosition > PageWidth)
				{
					this.style.backgroundImage = "url(" + RightImagePath + ")";
					this.style.backgroundPosition = -magnifierCenterX + WidthAfterZooming + "px " + -magnifierCenterY + "px";
				}
				else
				{
					this.style.backgroundImage = "url(" + LeftImagePath + ")";
				}
			
			}
			this.style.top = Math.round(this.yPosition - 1 - this.size/2) + "px";									
		}
		
		function ControllerSizeButtonClick(event)
		{
			
				if (!event) event = window.event;
			
				var button = event.currentTarget || event.srcElement;
		
				button.parentNode.magnifier.resize(button.magnifierSize);
			
		}
		
		function MagnifierResize(size)
		{
			
			this.size = kMagnifierSizes[size];
			for (var i=0; i < this.controller.sizeButtons.length; i++)
			{
				if (i == size)
					this.controller.sizeButtons[i].className = "magnifierControllerButtonSelected";
				else
					this.controller.sizeButtons[i].className = "magnifierControllerButton";
			}
			
			if (this.size == 0)
			{
			    //alert(this.style == null);
				this.shadow.style.display = "none";
				this.style.display = "none";
			}
			else
			{
			    var shadow = this.shadow;
				var shadowSize = this.size + 2 * kShadowPadding;
				
				// MSIE 5.x/6.x must be treated specially in order to make them use the PNG alpha channel
				var shadowImageSrc = "/_images/shadow" + size + ".png";
				if (shadow.runtimeStyle)
					shadow.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" +
											     shadowImageSrc +
												 "', sizingMethod='scale')";
				else
				this.shadow.style.backgroundImage = "url(" + shadowImageSrc + ")";
				this.shadow.style.width = shadowSize + "px";
				this.shadow.style.height = shadowSize*0.75 + "px";
				this.shadow.style.display = "block";
				
				if (this.runtimeStyle) // msie counts the border as being part of the width
					this.size += 2; // must compensate
				
				this.style.width = this.size + "px";
				this.style.height = this.size*0.75 + "px";
				this.style.display = "block";
				this.position();
			}
		}
		
		function MagnifierMouseDown(event)
		{
			if (!event) event = window.event;
			
			document.body.magnifier = this;
			this.inDrag = true;
			if (event.pageX)
			{
				this.startX = event.pageX;
				this.startY = event.pageY;
			}
			else if (event.clientX)
			{
				this.startX = event.clientX;
				this.startY = event.clientY;
			}
			else
			{
				alert("don't know how to get position out of event");
				return;
			}
			this.savedCursor = this.style.cursor;
			this.style.cursor = "crosshair";
		}
		
		function MagnifierMouseUp()
		{
			if (this.inDrag)
			{
				this.inDrag = false;
				this.style.cursor = this.savedCursor;
				document.body.magnifier = null;
			}
		}
		
		function MagnifierDrag(event)
		{
			if (!event) event = window.event;
			var magnifier = this.magnifier; // we're actually in the body's onmousemove handler
			
			if (magnifier && magnifier.inDrag)
			{
				var eventX;
				var eventY;
				
				if (event.pageX)
				{
					eventX = event.pageX;
					eventY = event.pageY;
				}
				else if (event.clientX)
				{
					eventX = event.clientX;
					eventY = event.clientY;
				}
				else
				{
					return;
				}
				
				magnifier.xPosition += eventX - magnifier.startX;
				magnifier.yPosition += eventY - magnifier.startY;
					
				
				magnifier.startX = eventX;
				magnifier.startY = eventY;
				
				magnifier.position();
				
			}
		}
		
function ChangeHidden()
{
	var In;
	var ImageSrc;
	if (document.getElementById("btnZoom").src.indexOf("_in_") == -1)
	{
			document.getElementById("btnZoom").src = "images/shared/zoom_in_off.gif";
			document.getElementById("btnZoom").alt = "Start Zooming";
			In = "true";
		}
		else
		{
			document.getElementById("btnZoom").src = "images/shared/zoom_out_off.gif";
			document.getElementById("btnZoom").alt = "End Zooming";
			In = "false";
		}
		if (window.frames["iframeCatalog"].window.document.getElementById("hidMagnifierLoaded") != null)
		{
			window.frames["iframeCatalog"].window.document.getElementById("hidMagnifierLoaded").value = In;
		}
		window.frames["iframeCatalog"].window.document.getElementById("imgHidden").src=document.getElementById("btnZoom").src;

}
		
		function LoadMag(baseID, leftImage, rightImage, zoomedWidth, zoomedHeight, IsSubDir)
		{
		var zoomedURL = leftImage;
		
		LeftImagePath = leftImage;
		RightImagePath = rightImage;
		
			if (document.getElementById("hidMagnifierLoaded").value == "true")
			{
				if (document.getElementById("btnZoom") != null)
				{
				    document.getElementById("btnZoom").src = "../images/shared/zoom_in_on.gif";
				    document.getElementById("btnZoom").alt = "Start Zooming";
				    document.getElementById("hidMagnifierLoaded").value = "";
				}
				document.getElementById("bindingMagnifier").resize(0);
			}
			else
			{
				if (document.getElementById("btnZoom") != null)
				{
				    document.getElementById("btnZoom").src = "../images/shared/zoom_out_on.gif";
				    document.getElementById("btnZoom").alt = "End Zooming";
				    document.getElementById("hidMagnifierLoaded").value = "true";
				}
				loadMagnifier(baseID, zoomedURL, zoomedWidth, zoomedHeight);
			}
		}
	
		function loadMagnifier(baseID, zoomedURL, zoomedWidth, zoomedHeight)
		{
			// get the zoomed image (load as early as possible)
			var zoomedImage = document.createElement("img");
			zoomedImage.src = zoomedURL;

			var base = document.getElementById(baseID);
			var magnifier = document.createElement("div");
		
			// get the regular image
			var normalImage = null;
			
			for (var i=0; i < base.childNodes.length; i++)
			{
				if (base.childNodes[i].tagName &&
						base.childNodes[i].tagName.toLowerCase() == "img")
					{
						normalImage = base.childNodes[i];
						break;
					}
			}
			
			if (normalImage == null)
			{
				alert("couldn't find normal image for magnifier " + baseID);
				return;
			}
			
			PageWidth = normalImage.width;
			WidthAfterZooming = zoomedWidth;
			magnifier.xMultiplier = zoomedWidth/normalImage.width;
			magnifier.yMultiplier = zoomedHeight/normalImage.height;
			
			magnifier.size = kMagnifierSizes[kDefaultMagnifierSize];
			magnifier.xPosition = normalImage.width - magnifier.size/2 - 10;
			magnifier.yPosition = normalImage.height - magnifier.size/2 - 100;
			
			magnifier.id = baseID + "Magnifier";
			magnifier.className = "magnifier";
			
			// styles (only dynamic ones, rest are part of the class)
			magnifier.style.backgroundImage = "url(" + zoomedURL + ")";
			
			// functions
			magnifier.onmousedown = MagnifierMouseDown;
			magnifier.onmouseup = MagnifierMouseUp;
			document.body.onmousemove = MagnifierDrag; // we attach this handler to the body because if the user moves
													   // the mouse fast enough, it'll go outside the boundaries of the
													   // magnifier, and then the magnifier's mousemove handler won't fire

			magnifier.position = MagnifierPosition;
			magnifier.resize = MagnifierResize;
			
			// controller
			var controller = document.createElement("span");
			
			controller.id = baseID + "MagnifierController";
			controller.className = "magnifierController";
			
			var controllerPrefix = document.createElement("span");
			controllerPrefix.innerHTML = kControllerPrefix;
			controllerPrefix.className = "magnifierControllerPrefix";
			controller.sizeButtons = new Array(kMagnifierSizes.length);

			for (var i=0; i < kMagnifierSizes.length; i++)
			{
				var button = document.createElement("span");
				button.innerHTML = kMagnifierSizeNames[i];
				button.className = "magnifierControllerButton";
				button.onclick = ControllerSizeButtonClick;
				button.magnifierSize = i;
				
				controller.sizeButtons[i] = button;
			}
			
			// shadow
			var shadow = document.createElement("div");
			
			shadow.id = baseID + "MagnifierShadow";
			shadow.className = "magnifierShadow";
			
			// point objects at each other
			magnifier.controller = controller;
			controller.magnifier = magnifier;
			magnifier.shadow = shadow;
			
			base.appendChild(shadow);
			base.appendChild(magnifier);
			magnifier.resize(kDefaultMagnifierSize); // also positions
		}

var jg_ok, jg_ie, jg_fast, jg_dom, jg_moz;

function chkDHTM(x, i)
{
	x = document.body || null;
	jg_ie = x && typeof x.insertAdjacentHTML != "undefined" && document.createElement;
	jg_dom = (x && !jg_ie &&
		typeof x.appendChild != "undefined" &&
		typeof document.createRange != "undefined" &&
		typeof (i = document.createRange()).setStartBefore != "undefined" &&
		typeof i.createContextualFragment != "undefined");
	jg_fast = jg_ie && document.all && !window.opera;
	jg_moz = jg_dom && typeof x.style.MozOpacity != "undefined";
	jg_ok = !!(jg_ie || jg_dom);
}

function pntCnvDom()
{
	var x = this.wnd.document.createRange();
	x.setStartBefore(this.cnv);
	x = x.createContextualFragment(jg_fast? this.htmRpc() : this.htm);
	if(this.cnv) this.cnv.appendChild(x);
	this.htm = "";
}

function pntCnvIe()
{
	if(this.cnv) this.cnv.insertAdjacentHTML("BeforeEnd", jg_fast? this.htmRpc() : this.htm);
	this.htm = "";
}

function pntDoc()
{
	this.wnd.document.write(jg_fast? this.htmRpc() : this.htm);
	this.htm = '';
}

function pntN()
{
	;
}

function mkDiv(x, y, w, h)
{
	this.htm += '<div style="position:absolute;'+
		'left:' + x + 'px;'+
		'top:' + y + 'px;'+
		'width:' + w + 'px;'+
		'height:' + h + 'px;'+
		'clip:rect(0,'+w+'px,'+h+'px,0);'+
		'background: transparent;' + 
		'background-color:' + this.color + ';' +
		'zindex:0;' +
		(!jg_moz? ';overflow:hidden' : '')+
		';"><\/div>';
}

function mkDivIe(x, y, w, h)
{
	this.htm += '%%'+this.color+';'+x+';'+y+';'+w+';'+h+';';
}

function mkDivPrt(x, y, w, h)
{
	this.htm += '<div style="position:absolute;'+
		'border-left:' + w + 'px solid ' + this.color + ';'+
		'left:' + x + 'px;'+
		'top:' + y + 'px;'+
		'width:0px;'+
		'height:' + h + 'px;'+
		'clip:rect(0,'+w+'px,'+h+'px,0);'+
		'background-color:' + this.color +
		(!jg_moz? ';overflow:hidden' : '')+
		';"><\/div>';
}

var regex =  /%%([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);/g;
function htmRpc()
{
	return this.htm.replace(
		regex,
		'<div style="overflow:hidden;position:absolute;background-color:'+
		'$1;left:$2;top:$3;width:$4;height:$5"></div>\n');
}

function htmPrtRpc()
{
	return this.htm.replace(
		regex,
		'<div style="overflow:hidden;position:absolute;background-color:'+
		'$1;left:$2;top:$3;width:$4;height:$5;border-left:$4px solid $1"></div>\n');
}

function mkLin(x1, y1, x2, y2)
{
	if(x1 > x2)
	{
		var _x2 = x2;
		var _y2 = y2;
		x2 = x1;
		y2 = y1;
		x1 = _x2;
		y1 = _y2;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1),
	x = x1, y = y1,
	yIncr = (y1 > y2)? -1 : 1;

	if(dx >= dy)
	{
		var pr = dy<<1,
		pru = pr - (dx<<1),
		p = pr-dx,
		ox = x;
		while(dx > 0)
		{--dx;
			++x;
			if(p > 0)
			{
				this.mkDiv(ox, y, x-ox, 1);
				y += yIncr;
				p += pru;
				ox = x;
			}
			else p += pr;
		}
		this.mkDiv(ox, y, x2-ox+1, 1);
	}

	else
	{
		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy,
		oy = y;
		if(y2 <= y1)
		{
			while(dy > 0)
			{--dy;
				if(p > 0)
				{
					this.mkDiv(x++, y, 1, oy-y+1);
					y += yIncr;
					p += pru;
					oy = y;
				}
				else
				{
					y += yIncr;
					p += pr;
				}
			}
			this.mkDiv(x2, y2, 1, oy-y2+1);
		}
		else
		{
			while(dy > 0)
			{--dy;
				y += yIncr;
				if(p > 0)
				{
					this.mkDiv(x++, oy, 1, y-oy);
					p += pru;
					oy = y;
				}
				else p += pr;
			}
			this.mkDiv(x2, oy, 1, y2-oy+1);
		}
	}
}

function mkLin2D(x1, y1, x2, y2)
{
	if(x1 > x2)
	{
		var _x2 = x2;
		var _y2 = y2;
		x2 = x1;
		y2 = y1;
		x1 = _x2;
		y1 = _y2;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1),
	x = x1, y = y1,
	yIncr = (y1 > y2)? -1 : 1;

	var s = this.stroke;
	if(dx >= dy)
	{
		if(dx > 0 && s-3 > 0)
		{
			var _s = (s*dx*Math.sqrt(1+dy*dy/(dx*dx))-dx-(s>>1)*dy) / dx;
			_s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
		}
		else var _s = s;
		var ad = Math.ceil(s/2);

		var pr = dy<<1,
		pru = pr - (dx<<1),
		p = pr-dx,
		ox = x;
		while(dx > 0)
		{--dx;
			++x;
			if(p > 0)
			{
				this.mkDiv(ox, y, x-ox+ad, _s);
				y += yIncr;
				p += pru;
				ox = x;
			}
			else p += pr;
		}
		this.mkDiv(ox, y, x2-ox+ad+1, _s);
	}

	else
	{
		if(s-3 > 0)
		{
			var _s = (s*dy*Math.sqrt(1+dx*dx/(dy*dy))-(s>>1)*dx-dy) / dy;
			_s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
		}
		else var _s = s;
		var ad = Math.round(s/2);

		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy,
		oy = y;
		if(y2 <= y1)
		{
			++ad;
			while(dy > 0)
			{--dy;
				if(p > 0)
				{
					this.mkDiv(x++, y, _s, oy-y+ad);
					y += yIncr;
					p += pru;
					oy = y;
				}
				else
				{
					y += yIncr;
					p += pr;
				}
			}
			this.mkDiv(x2, y2, _s, oy-y2+ad);
		}
		else
		{
			while(dy > 0)
			{--dy;
				y += yIncr;
				if(p > 0)
				{
					this.mkDiv(x++, oy, _s, y-oy+ad);
					p += pru;
					oy = y;
				}
				else p += pr;
			}
			this.mkDiv(x2, oy, _s, y2-oy+ad+1);
		}
	}
}

function mkLinDott(x1, y1, x2, y2)
{
	if(x1 > x2)
	{
		var _x2 = x2;
		var _y2 = y2;
		x2 = x1;
		y2 = y1;
		x1 = _x2;
		y1 = _y2;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1),
	x = x1, y = y1,
	yIncr = (y1 > y2)? -1 : 1,
	drw = true;
	if(dx >= dy)
	{
		var pr = dy<<1,
		pru = pr - (dx<<1),
		p = pr-dx;
		while(dx > 0)
		{--dx;
			if(drw) this.mkDiv(x, y, 1, 1);
			drw = !drw;
			if(p > 0)
			{
				y += yIncr;
				p += pru;
			}
			else p += pr;
			++x;
		}
	}
	else
	{
		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy;
		while(dy > 0)
		{--dy;
			if(drw) this.mkDiv(x, y, 1, 1);
			drw = !drw;
			y += yIncr;
			if(p > 0)
			{
				++x;
				p += pru;
			}
			else p += pr;
		}
	}
	if(drw) this.mkDiv(x, y, 1, 1);
}


function mkRect(x, y, w, h)
{
	var s = this.stroke;
	this.mkDiv(x, y, w, s);
	this.mkDiv(x+w, y, s, h);
	this.mkDiv(x, y+h, w+s, s);
	this.mkDiv(x, y+s, s, h-s);
}

function mkRectDott(x, y, w, h)
{
	this.drawLine(x, y, x+w, y);
	this.drawLine(x+w, y, x+w, y+h);
	this.drawLine(x, y+h, x+w, y+h);
	this.drawLine(x, y, x, y+h);
}

function jsgFont()
{
	this.PLAIN = 'font-weight:normal;';
	this.BOLD = 'font-weight:bold;';
	this.ITALIC = 'font-style:italic;';
	this.ITALIC_BOLD = this.ITALIC + this.BOLD;
	this.BOLD_ITALIC = this.ITALIC_BOLD;
}
var Font = new jsgFont();

function jsgStroke()
{
	this.DOTTED = -1;
}
var Stroke = new jsgStroke();

function jsGraphics(cnv, wnd)
{
	this.setColor = new Function('arg', 'this.color = arg.toLowerCase();');

	this.setStroke = function(x)
	{
		this.stroke = x;
		if(!(x+1))
		{
			this.drawLine = mkLinDott;
			//this.mkOv = mkOvDott;
			this.drawRect = mkRectDott;
		}
		else if(x-1 > 0)
		{
			this.drawLine = mkLin2D;
			//this.mkOv = mkOv2D;
			this.drawRect = mkRect;
		}
		else
		{
			this.drawLine = mkLin;
			//this.mkOv = mkOv;
			this.drawRect = mkRect;
		}
	};

	this.setPrintable = function(arg)
	{
		this.printable = arg;
		if(jg_fast)
		{
			this.mkDiv = mkDivIe;
			this.htmRpc = arg? htmPrtRpc : htmRpc;
		}
		else 
		{
			this.mkDiv = arg? mkDivPrt : mkDiv;
		}	
		this.mkDiv = arg? mkDivPrt : mkDiv;
		//this.mkDivRelative = mkDivRelative;
	};

	this.setFont = function(fam, sz, sty)
	{
		this.ftFam = fam;
		this.ftSz = sz;
		this.ftSty = sty || Font.PLAIN;
	};

	

	

	
	
	this.clear = function()
	{
		this.htm = "";
		if(this.cnv) this.cnv.innerHTML = "";
	};

	this.setStroke(1);
	this.setFont("verdana,geneva,helvetica,sans-serif", "12px", Font.PLAIN);
	this.color = "#000000";
	this.htm = "";
	this.wnd = wnd || window;

	if(!jg_ok) chkDHTM();
	if(jg_ok)
	{
		if(cnv)
		{
			if(typeof(cnv) == "string")
				this.cont = document.all? (this.wnd.document.all[cnv] || null)
					: document.getElementById? (this.wnd.document.getElementById(cnv) || null)
					: null;
			else if(cnv == window.document)
				this.cont = document.getElementsByTagName("body")[0];
			// If cnv is a direct reference to a canvas DOM node
			// (option suggested by Andreas Luleich)
			else this.cont = cnv;
			// Create new canvas inside container DIV. Thus the drawing and clearing
			// methods won't interfere with the container's inner html.
			// Solution suggested by Vladimir.
			this.cnv = document.createElement("div");
			this.cont.appendChild(this.cnv);
			this.paint = jg_dom? pntCnvDom : pntCnvIe;
		}
		else
			this.paint = pntDoc;
	}
	else
		this.paint = pntN;

	this.setPrintable(false);
}

Array.prototype.mkLinVirt = function(x1, y1, x2, y2)
{
	var dx = Math.abs(x2-x1), dy = Math.abs(y2-y1),
	x = x1, y = y1,
	xIncr = (x1 > x2)? -1 : 1,
	yIncr = (y1 > y2)? -1 : 1,
	p,
	i = 0;
	if(dx >= dy)
	{
		var pr = dy<<1,
		pru = pr - (dx<<1);
		p = pr-dx;
		while(dx > 0)
		{--dx;
			if(p > 0)    //  Increment y
			{
				this[i++] = x;
				y += yIncr;
				p += pru;
			}
			else p += pr;
			x += xIncr;
		}
	}
	else
	{
		var pr = dx<<1,
		pru = pr - (dy<<1);
		p = pr-dy;
		while(dy > 0)
		{--dy;
			y += yIncr;
			this[i++] = x;
			if(p > 0)    //  Increment x
			{
				x += xIncr;
				p += pru;
			}
			else p += pr;
		}
	}
	for(var len = this.length, i = len-i; i;)
		this[len-(i--)] = x;
};

function CompInt(x, y)
{
	return(x - y);
}

