function TransformXML (strXMLURL, strXSLURL, callback)
{
	if (typeof (strXMLURL) == string)
		LoadXML (strXMLURL, OnXMLLoaded);
	else
		OnXMLLoaded (strXMLURL);
	
	function OnXMLLoaded (req)
	{
		if (!strXSLURL)
		{
			callback (req.responseText, null);
			return;
		}
		
		var xml;
		try
		{
			xml = req.responseXML;
		} catch (e) {}
		
		if (!xml)
			xml = req;
			
		var xsl = _mapTransforms [strXSLURL.toLowerCase ()];
		if (xsl)
			Transform (xml, xsl);
		else
			LoadXML (strXSLURL, function (xsl) { OnXSLLoaded (xml, xsl.responseXML); } );
	}
	
	function Transform (xml, xsl)
	{
		var xmlTransformed = null;
		if (xml)
		{
			if (xsl.transformToFragment)
				xmlTransformed = xsl.transformToFragment (xml, document);
			else
				xmlTransformed = xml.transformNode (xsl);
		}
		callback (xmlTransformed, xml);
	}
}


function GetOffsets (elt)
{
	var offsets = new Point (-document.body.offsetLeft, -document.body.offsetTop);
	while (elt)
	{
		offsets.Add2 (elt.offsetLeft, elt.offsetTop);
		elt = elt.offsetParent;
	}
	return offsets;
}

function GetEventOffsets (evt)
{
	if (document.all)
	{
		var target = GetTarget (evt);
		var offsets = GetOffsets (target);
		offsets.Add2 (evt.offsetX, evt.offsetY);
		return offsets;
	}
	else
	{
		return new Point (evt.pageX, evt.pageY);
	}
}

function GetEventOffsetsFrom (evt, elt)
{
	var offsets = GetEventOffsets (evt);
	offsets.Sub (GetOffsets (elt));
	
	return offsets;
}

function GetTarget (evt)
{
	if (!evt) evt = window.event;
	if (!evt) return null;
	var target = evt.target ? evt.target : evt.srcElement;
	if (target.nodeType == 3)
		return target.parentNode;
	return target;
}


function Point (x, y)
{
	this.x = x || 0;
	this.y = y || 0;

	this.Add = function (pt)
	{
		this.x += pt.x;
		this.y += pt.y;
	}

	this.Sub = function (pt)
	{
		this.x -= pt.x;
		this.y -= pt.y;
	}

	this.Add2 = function (x, y)
	{
		this.x += x;
		this.y += y;
	}
	
	this.toString = function ()
	{
		return "("+this.x+","+this.y+")";
	}
}


