function ajax(url, vars, doFunc, funcParams)
{
	var xmlhttp;
	var timeout;
	var data = '';
	var response;
	var first = true;
	if (!doFunc)
	{
		doFunct = emptyFunction;
	}
	// prepare contents to be sent
	for (var v in vars)
	{
		if (first)
		{
			data += escape(v) + '=' + escape(vars[v]);
			first = false;
		}
		else
		{
			data += '&' + escape(v) + '=' + escape(vars[v]);
		}
	}
	// create xmlhttp object
	xmlhttp = window.XMLHttpRequest ?
		new XMLHttpRequest() :
		new ActiveXObject("MSXML2.XMLHTTP.3.0");
	// prepare doFunc's params, inserting params[0]=null
	if (!funcParams)
	{
		funcParams = [];
	}
	for (var i = funcParams.length; i > 0; --i)
	{
		funcParams[i] = funcParams[i - 1];
	}
	funcParams[0] = null;
	// in case of error, this will be called
	timeout = setTimeout(
		function ()
		{
			xmlhttp.abort();
			doFunc.apply(doFunc, funcParams)
		}, 10000);
	// on success/fail, call doFunc
	xmlhttp.onreadystatechange = function()
	{
		// on success
		if (xmlhttp.readyState == 4)
		{
			// no error
			clearTimeout(timeout);
			try
			{
				eval('response = ' + xmlhttp.responseText);
			}
			catch (e)
			{
				response = null;
			}
			funcParams[0] = response;
			doFunc.apply(doFunc, funcParams);
		}
	};
	// finally, POST the data and wait for a response
	xmlhttp.open('POST', url, true);
	xmlhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
	xmlhttp.setRequestHeader('Content-length', data.length);
	xmlhttp.setRequestHeader('Connection', 'close');
	xmlhttp.send(data);
	return xmlhttp;
}

