// JavaScript Document
<!-- Hide from scriptless browsers
snapAddEvent(window, 'load', snapInit);

// Global settings
var pageNumber=0;
var lastPageNumber=0;
var pBars=12;
var hasSubmitted = false;

var showButtons=true;
var startPoint;
var endPoint;
var timerStarted = false;
var allowStore=true;
var g_subm = false;
// Leave alone
var dependents=new Array();
var codeLabels=new Array();
var pageContents=new Array();
var askedCalc=new Array();
var askedCache=new Array();
var exclusive=new Array();
var forceReply=new Array();
var validateList=new Array();
var codeMaskList=new Array();
var autoAnsList=new Array();
var doAutoAnsList=new Array();
var gridFirstList=new Array();
var showButtonOptions=new Array();
var cacheNumCodes=new Array();
var cacheIsOpen=new Array();
var cacheIsClosed=new Array();
var cacheIsDropdown=new Array();
var cacheIsGrid=new Array();
var totalList=new Array();
var cacheSelectOptions=new Array();
var pageArray=null;
var textSubLookup=null;

////////////////////////////////////////////////////////////////////////////////
// System
function snapInit()
{
	snapQueryString();
	lastPageNumber=snapCountNumPages();

	for (var p=1; p<=lastPageNumber; p++)
	{
		snapInclude(snapObject('p_p'+p), false);
	}
	linkButton('b_next', snapNextPage);
	linkButton('b_back', snapBackPage);
	linkButton('b_submit', snapSubmitPage);
	linkButton('b_reset', snapResetPage);
	linkButton('b_restart', snapResetAll);
	linkButton('b_print', snapPrint);
	showButtonOptions['b_back']='pageNumber>=2&&pageNumber<=lastPageNumber';
	showButtonOptions['b_reset']='pageNumber>=1&&pageNumber<=lastPageNumber';
	showButtonOptions['b_next']='pageNumber>=1&&pageNumber<=lastPageNumber-1';
	showButtonOptions['b_submit']='pageNumber>=lastPageNumber&&pageNumber<=lastPageNumber';


	// List off routing specifications by question id
	askedCalc['V60']='ansAsNum("V9")>0&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<50000)))';
	askedCalc['V62']='ansAsNum("V9")>0&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<50000)))';
	askedCalc['V63']='ansAsNum("V9")>0&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<50000)))';
	askedCalc['V64']='ansAsNum("V9")>0&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<50000)))';
	askedCalc['V65']='ansAsNum("V9")>0&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<50000)))';
	askedCalc['V66']='ansAsNum("V9")>0&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<50000)))';
	askedCalc['V67']='ansAsNum("V9")>0&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<50000)))';
	askedCalc['V68']='ansAsNum("V9")>0&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<50000)))';
	askedCalc['V69']='ansAsNum("V9")>0&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<50000)))';
	askedCalc['V73']='ansAsNum("V9")>=50000&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<=99999)))';
	askedCalc['V74']='ansAsNum("V9")>=50000&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<=99999)))';
	askedCalc['V75']='ansAsNum("V9")>=50000&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<=99999)))';
	askedCalc['V76']='ansAsNum("V9")>=50000&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<=99999)))';
	askedCalc['V77']='ansAsNum("V9")>=50000&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<=99999)))';
	askedCalc['V78']='ansAsNum("V9")>=50000&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<=99999)))';
	askedCalc['V79']='ansAsNum("V9")>=50000&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<=99999)))';
	askedCalc['V80']='ansAsNum("V9")>=50000&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<=99999)))';
	askedCalc['V81']='ansAsNum("V9")>=50000&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<=99999)))';
	askedCalc['V12']='ansAsNum("V9")>0&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<50000)))';
	askedCalc['V36']='ansAsNum("V9")>=50000&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<=99999)))';
	askedCalc['V21']='ans("V12")==2';
	askedCalc['V54']='ans("V36")==2';
// List of variables that have one or more dependents
	dependents['V9']=new Array("V63","V36","V64","V65","V66","V67","V68","V69","V12","V18","V24","V60","V62","V73","V74","V75","V76","V77","V78","V79","V80","V81","V54","V21");
	dependents['V12']=new Array("V21");
	dependents['V36']=new Array("V54");


	// List of variables that have exclusive codes


	// List of variables that must be answered
	forceReply['V9']='Q1';
	forceReply['V28']='Q2';
	forceReply['V29']='Q3';
	forceReply['V30']='Q4';
	forceReply['V31']='Q5';
	forceReply['V32']='Q6';
	forceReply['V33']='Q7';

	validateList['V9']='isValidNum("V9_1", true, "Q1")';
	validateList['V60']='isValidNum("V60_1", true, "Q9a")';
	validateList['V62']='isValidNum("V62_1", true, "Q9b")';
	validateList['V63']='isValidNum("V63_1", true, "Q9c")';
	validateList['V64']='isValidNum("V64_1", true, "Q9d")';
	validateList['V65']='isValidNum("V65_1", true, "Q9e")';
	validateList['V66']='isValidNum("V66_1", true, "Q9f")';
	validateList['V67']='isValidNum("V67_1", true, "Q9g")';
	validateList['V68']='isValidNum("V68_1", true, "Q9h")';
	validateList['V69']='isValidNum("V69_1", true, "Q9i")';
	validateList['V73']='isValidNum("V73_1", true, "Q10a")';
	validateList['V74']='isValidNum("V74_1", true, "Q10b")';
	validateList['V75']='isValidNum("V75_1", true, "Q10c")';
	validateList['V76']='isValidNum("V76_1", true, "Q10d")';
	validateList['V77']='isValidNum("V77_1", true, "Q10e")';
	validateList['V78']='isValidNum("V78_1", true, "Q10f")';
	validateList['V79']='isValidNum("V79_1", true, "Q10g")';
	validateList['V80']='isValidNum("V80_1", true, "Q10h")';
	validateList['V81']='isValidNum("V81_1", true, "Q10i")';

	
	// Totalise Values

	// identify which questions are on each page
	pageContents[1]=new Array("V41","V9","V49","V28","V29","V30","V31","V32","V33");
	pageContents[2]=new Array("V60","V62","V63","V64","V65","V66","V67","V68","V69","V73","V74","V75","V76","V77","V78","V79","V80","V81","V12","V36","V21","V54","V51");


	// check question responses when they change
	for(var i=1; i<=lastPageNumber; i++)
	{
		 if (pageContents[i])
		{
			var pageItems = pageContents[i];
			for(var j=0; j<pageItems.length; j++)
			{
				snapHookEvents(pageItems[j]);
			}
		}
	}

	// List of variables with code rotation


	// List of grid variables with their first grid item
	gridFirstList['V62']='V60';
	gridFirstList['V63']='V60';
	gridFirstList['V64']='V60';
	gridFirstList['V65']='V60';
	gridFirstList['V66']='V60';
	gridFirstList['V67']='V60';
	gridFirstList['V68']='V60';
	gridFirstList['V69']='V60';
	gridFirstList['V74']='V73';
	gridFirstList['V75']='V73';
	gridFirstList['V76']='V73';
	gridFirstList['V77']='V73';
	gridFirstList['V78']='V73';
	gridFirstList['V79']='V73';
	gridFirstList['V80']='V73';
	gridFirstList['V81']='V73';


	for(var x in gridFirstList)
	{
		var gridName=gridFirstList[x]+"_GRID";
		if(askedCalc[gridName]==null)
			askedCalc[gridName]="asked(\""+gridFirstList[x]+"\")";
		askedCalc[gridName]+="||asked(\""+x+"\")";
	}

	// List of variables that have a mask applied to their answers

	
	// Prepare the first page
	var pleaseWait = snapObject("snapIntro");
	if (pleaseWait != null)
	{  var aParent=pleaseWait.parentNode;
		if (aParent != null)
			aParent.removeChild(pleaseWait);
	}

 
	snapApplyInitialSubstitutions();
	snapInclude(snapObject('snapbuttons'), true, 'block');
	snapInclude(snapObject('snapDiv'), true, 'block');
	if (lastPageNumber > 1) snapInclude(snapObject('b_progress'), true);

	snapNextPage();
}
function linkButton(name, func)
{  var button = snapObject(name);
	var done = false;
	if (button && button.parentNode)
	{  var bParent = button.parentNode;
		if (bParent && bParent.tagName && ("a" == bParent.tagName.toLowerCase()))
		{  done = true;
			snapAddEvent(bParent, 'keypress',func);
			snapAddEvent(bParent, 'click',func);
		}
	}
	if (!done)
	{  snapAddEvent(button, 'click',func);
	}
}
function snapQueryString()
{
	var query=unescape(location.search.substring(1));
	var pairs=query.split("&");
	for(var i=0; i<pairs.length;i++)
	{	var pos=pairs[i].indexOf('=');
		if (pos>0)
		{	var argName=pairs[i].substring(0,pos);
			var value=pairs[i].substring(pos+1);
			if ((argName=="id") || (argName=="u"))
			{snapSetOpenReply("0",value);
			}
			else if (argName=="p")
			{snapSetOpenReply("0",value);
			}
			else if (argName=="s")
			{snapSetOpenReply("0",value);
			}
		}
	}
}

function snapMappedPage(page)
{
	if (pageArray != null)
	{
		if(page>=1 && page<=lastPageNumber)
		{
			page=pageArray[page];			
		}
	}
	return page;
}

// System
function snapHookEvents(question)
{
	var items = snapObjectsByName(question);
	var i;
	var item;
	for (i=0; i<items.length; i++)
	{
		item=items[i];
		if (item.type)
		{
			if (item.type=='checkbox' || item.type=='radio')
				snapAddEvent(item, 'click', snapChangeMade);
			else if (item.type=='select-one' || item.type=='select-multiple')
				snapAddEvent(item, 'change', snapChangeMade);
			else if (item.type=='text' || item.type=='textarea')
				snapAddEvent(item, 'blur', snapChangeMade);
		}
	}
}

// System
function snapAddEvent(obj, evType, fn)
{
	var result=false;
	if (obj)
	{
		if (obj.attachEvent)
		{
			result=obj.attachEvent("on"+evType, fn);
		} else if (obj.addEventListener)
		{
			obj.addEventListener(evType, fn, true);
			result=true;
		}
	}
	return result;
}

// System
function snapGlobalDoc()
{
	return document.forms["SnapForm"].elements;
}

// System
function snapObject(id)
{
	return document.getElementById(id);
}

// System
function snapObjectsByName(name)
{
	return document.getElementsByName(name);
}

// System
function snapObjectsByTagName(tagName)
{
	return document.getElementsByTagName(tagName);
}

// System
function snapEventOrigin(arg)
{
	if (arg.srcElement)
		return arg.srcElement;
	else if (arg.target)
		return arg.target;
	return null;
}

////////////////////////////////////////////////////////////////////////////////
// Page navigation
function snapCountNumPages()
{
	var Result=0;
	var p=1;
	while(snapObject('p_p'+p))
	{
		Result=p;
		p++;
	}
	return Result;
}

function snapSubmitPage(eventOb)
{
	if (snapIgnoreKey(eventOb)) return true;

	var okToSubmit=false;
	if (!hasSubmitted && snapIsIncluded(snapObject('b_submit')))
	{
		var somethingToShow=false;
		var nextPage=pageNumber;
		while(nextPage<=lastPageNumber && snapPageValidationOk(nextPage))
		{
			nextPage++;
			if(nextPage<=lastPageNumber)
			{
				somethingToShow=snapEvalShowPage(nextPage, false);
			}
		}
		if(nextPage > lastPageNumber)
		{
			okToSubmit = true;
			hasSubmitted = true;
			snapShowPage(lastPageNumber);
		}
		if(nextPage<=lastPageNumber)
		{
			snapShowPage(nextPage);
			okToSubmit=false;
		}
	}

	if (okToSubmit)
	{
		fEndTimer();
	}
	else if (eventOb)
	{
		if (eventOb.cancelBubble!=null)  eventOb.cancelBubble = true;
		if (eventOb.returnValue!=null) eventOb.returnValue = false;
		if (eventOb.preventDefault)  eventOb.preventDefault();
	}

	return okToSubmit;
}

function snapIgnoreKey(eventOb)
{
	var ignore= false;
 	if (eventOb && (eventOb.type.toLowerCase()=="keypress") && (eventOb.keyCode != null))
 	{  if ((eventOb.keyCode!=32) && (eventOb.keyCode!=10))
		{  ignore = true;
			if (eventOb.charCode!=null)
			{  if ((eventOb.charCode==32) || (eventOb.charCode==10))
					ignore = false;
			}
		}
	}
	return ignore;
}
// Page navigation
function snapEvalShowPage(Pagenum, force)
{
	var postponedItems = new Array(); //lengthy fix for bug in opera9
	var somethingToShow=snapEvalPageRouting(Pagenum, postponedItems);
	if(somethingToShow || force)
	{
		snapShowPage(Pagenum);
		for (var name in postponedItems)
		{
			snapEvalAskedFor(name);
		}
	}
	postponedItems = null;
	return somethingToShow;
}

// Page navigation
function snapNextPage(eventOb)
{
	if (snapIgnoreKey(eventOb)) return true;
	if (eventOb && eventOb.preventDefault) eventOb.preventDefault();

	var somethingToShow=false;
	var nextPage=pageNumber;
	while(nextPage<lastPageNumber && !somethingToShow && snapPageValidationOk(nextPage))
	{
		nextPage++;
		somethingToShow=snapEvalShowPage(nextPage, nextPage==lastPageNumber);
		if(somethingToShow || nextPage==lastPageNumber)
			snapShowPage(nextPage);
		if (nextPage==lastPageNumber)
		{
    	for(c=0;c<document.forms["SnapForm"].elements.length;c++)
      {
        if(document.forms["SnapForm"].elements[c].name==":EMAIL:")
         emailPos = c;
    	}
        if (ansAsNum("V9")>=50000&&(((ansAsNum("V9")!="")&&(ansAsNum("V9")<=99999))))
             document.forms["SnapForm"].elements[emailPos].value="upgrades@mercatorcorp.com,demoenq@mercator.co.uk";
    	  else
    	       document.forms["SnapForm"].elements[emailPos].value="snap9upgrade@snapsurveys.com,demoenq@mercator.co.uk";
    }
	}
	return false;
}

// Page navigation
function snapBackPage(eventOb)
{
	if (snapIgnoreKey(eventOb)) return true;
	if (eventOb && eventOb.preventDefault) eventOb.preventDefault();

	var somethingToShow=false;
	var nextPage=pageNumber;
	while(nextPage>1 && !somethingToShow)
	{
		nextPage--;
		somethingToShow=snapEvalShowPage(nextPage, (nextPage==1));
	}
	return false;
}

function snapPrint(eventOb)
{
	if (snapIgnoreKey(eventOb)) return true;

	window.print();
}

// Page navigation
function snapResetPage(eventOb)
{
	if (snapIgnoreKey(eventOb)) return true;
	if (eventOb && eventOb.preventDefault) eventOb.preventDefault();

	var aPage=snapMappedPage(pageNumber);
	if (pageContents[aPage])
	{
		var changed = false;
		var pageItems = pageContents[aPage];
		for(var i=0; i<pageItems.length; i++)
		{
			var controls = snapObjectsByName(pageItems[i]);
			if (controls && controls.length > 0)
			{
				for(var j=0; j<controls.length; j++)
				{
					var elem = controls[j];
					if (elem && elem.tagName != null)
					{
						var lTagName = elem.tagName.toLowerCase();
						if (lTagName=="input")
						{
							if ((elem.type!= null) && (elem.type.toLowerCase() == 'text'))
							{
								if (elem.value  && elem.value!="")
								{
									elem.value = "";
									changed = true;
								}
							}
							else if (elem.checked)
							{
								elem.checked = false;
								changed = true;
							}
						}
						else if (lTagName=="textarea")
						{
							if (elem.value  && elem.value!="")
							{
								elem.value = "";
								changed = true;
							}
						}
						else if (lTagName=="select")
						{
							for (var op = 0; op < elem.options.length; op++)
							{
								if (elem.options[op].value > 0 && elem.options[op].selected)
								{
									elem.options[op].selected = false;
									changed = true;
								}
							}
						}
					}
				}
			}
		}
		if (changed)
		{
			snapApplyInitialSubstitutions();
			resetRouting();
			snapEvalPageRouting();
		}
	}

	return false;
}

function snapResetAll(eventOb)
{
	if (snapIgnoreKey(eventOb)) return true;
	document.forms["SnapForm"].reset();
	snapApplyInitialSubstitutions();
	resetRouting();
	snapEvalPageRouting();
	snapShowPage(1);
}
// Page navigation
function snapShowPage(target)
{
	if (target>=1 && target<=lastPageNumber)
	{
		snapInclude(snapObject("p_p"+snapMappedPage(pageNumber)), false);
		snapInclude(snapObject("p_p"+snapMappedPage(target)), true, 'block');
		pageNumber=target;
		snapFocusPage(pageNumber);
	}
	if(lastPageNumber>0)
	{
		// buttons -------------------------------------
		// one snapInclude per button, with condition set acccording to user selection
		for (var butn in showButtonOptions)
		{
			snapIncludeBtn(snapObject(butn), eval(showButtonOptions[butn]));
		}


		// progress bar -------------------------------------
		// can be left in always. Variable 'pBars' indicates number of images
		progress=snapObject("b_progress");
		if (progress)
		{
			var progText = "";
			if (progress.tagName != null && progress.tagName.toLowerCase()=="span")
			{
				progress.firstChild.nodeValue = progText;
			}
			else
			{
				if(progress.src)
				{
					var file=pbRatio(pBars);
					progress.src=progress.src.replace(/\d{2}\.gif/, file+".gif");
				}
				progress.alt=progText;
			}
		}
	}
}

function snapFocusPage(page)
{
	var found = false;
	page=snapMappedPage(page);
	if(page>=1 && page<=lastPageNumber)
	{
		if (pageContents[page])
		{
			var pageItems = pageContents[page];
			for(var j=0; j<pageItems.length && !found; j++)
			{
				if (getAsked(pageItems[j]))
				{
					var code =0;
					var codeOb= null;
					do
					{
						code++;
						codeOb = snapObject(pageItems[j]+'_'+code);
						if (codeOb)
						{
							try
							{
								found = true;
								codeOb.focus();
							}
							catch (e)//hidden control
							{
								found = false;
							}
						}
					}
					while (!found && codeOb != null)
				}
			}
		}
	}
}

// Page navigation
// Invalidate Routing cache for dependents of 'question'
function snapUndoRoutingFor(name)
{
	if (name && dependents[name])
	{
		var undo=dependents[name];
		for (var i=0; i<undo.length; i++)
		{
			var thisVar = undo[i];
			if (askedCache[thisVar]!=null)
				delete askedCache[thisVar];
			if (snapIsGrid(thisVar))
			{
				var gridOwner = thisVar;
				if(gridFirstList[thisVar]!=null)
				{
					gridOwner=gridFirstList[thisVar];
				}
				gridOwner += "_GRID";
				if (askedCache[gridOwner]!=null)
					delete askedCache[gridOwner];
			}
		}
	}
}

function resetRouting()
{
	for (var x in askedCache)
		delete askedCache[x];
}


// Page navigation
// recalculate routing for this given page (or current page if aPage==null)
function snapEvalPageRouting(aPage, postponedItems)
{
	var somethingShown=false;
	if (aPage==null)
		aPage=pageNumber;
	aPage=snapMappedPage(aPage);
	if (aPage>=1 && aPage<=lastPageNumber && pageContents[aPage])
	{
		var pageItems=pageContents[aPage];
		for (var i=0; i<pageItems.length; i++)
		{
			if(snapEvalAskedFor(pageItems[i], postponedItems))
			{	somethingShown=true;
			}
		}
	}
	return somethingShown;
}

// Page navigation
function snapIsPageIncluded(p)
{
}

////////////////////////////////////////////////////////////////////////////////
// Text substitution
function snapApplyInitialSubstitutions()
{
	var all_span = snapObjectsByTagName('span');
	var i;
	for(i=0;i<all_span.length;i++)
	{
		if(all_span[i].id)
		{
			var pos = all_span[i].id.indexOf("_reply");
			if (pos > 0)
			{
				var questionName=all_span[i].id.substr(0, pos);
				if(questionName && snapObject(questionName))
					all_span[i].firstChild.nodeValue=snapVarReply(questionName);
			}
		}
	}
}

// Text substitution
function snapSubstituteText(questionName)
{
   if (textSubLookup == null)
   {
      textSubLookup = new Array();
	   var all_span = snapObjectsByTagName('span');
	   var i;
	   for(i=0;i<all_span.length;i++)
	   {
	      if(all_span[i].id)
	      {
	         var nameLen =  all_span[i].id.indexOf('_reply');
	         if (nameLen > 0)
		      {
		         var newName = all_span[i].id.substr(0, nameLen);
		         if (textSubLookup[newName] == null)
		         {
		            textSubLookup[newName] = new Array();
		         }
		         var subList = textSubLookup[newName];
		         subList[subList.length] = all_span[i];
		      }
		   }
	   }      
   }
   
   if (textSubLookup[questionName] != null)
	{
	   var subList = textSubLookup[questionName];
	   var i;
	   for(i=0;i<subList.length;i++)
	   {
		   if(subList[i].id && (0 == subList[i].id.indexOf(questionName+'_reply')))
		   {
			   subList[i].firstChild.nodeValue=snapVarReply(questionName);
		   }
	   }
	}
}

// Value substitution
function snapEvalTotals(name)
{
	var expr=totalList[name];
	if(expr!=null)
		eval(expr);
}

// Value substitution
function totalise()
{
	var i=0, j=0, sum=0, varFloat=0, blank=true, isZero=false, varString='', srcVar, tarVar;
	var lastValues = new Array();
	var allowNegs=arguments[arguments.length-3]; // allow negative responses
	var roundNums=arguments[arguments.length-2]; // round numbers up/down
	var cleanNum=arguments[arguments.length-1];  // clean data: delete non-numeric chars or delete invalid num
	for (i=0; i<arguments.length-4; i++)			// loop source variables, edit and add to sum
	{
		varString = snapVarReply(arguments[i]);
		if (cleanNum)
			varString = cleanNumber(varString, allowNegs); // clean data
		if (roundNums)
			varString = '' + Math.round(parseFloat(varString)); // round number and cast back to string
		varFloat = parseFloat(varString);
		if ((!allowNegs && varFloat < 0) || isNaN(varFloat))	 // delete invalid number
		{
			varString='';
			varFloat=0;
		}
		sum += varFloat;		// add to running total
		if (varString == '0')
			isZero=true;		// If source var is '0' the total should display '0' not ''
		if (varString != '')
			blank=false;		// If all source vars are blank total should be blank
	}
	if(blank)
		sum='';
	else
		sum=''+sum;

	if(snapIsOpen(arguments[arguments.length-4]))
		snapSetOpenReply(arguments[arguments.length-4], sum);
}

// Value substitution
function cleanNumber(varString, allowNegs)
{
	if(allowNegs)
		newVarString=varString.replace(/^[^+\-0~9]*([+\-]?\d*\.?\d*).*$/, '$1');
	else
		newVarString=varString.replace(/^[^+0~9]*(\+?\d*\.?\d*).*$/, '$1');
	return newVarString;
}

////////////////////////////////////////////////////////////////////////////////
// Variable display
function snapInclude(obj, show, val)
{	var changed = false;
	if (obj)
	{	if (val == null)
		{	val = '';
		}
		if (!show)
		{	val = 'none';
		}
		if (obj.style.display!=val)
		{	obj.style.display = val;
			changed = true;
		}
	}
	return changed;
}
function snapIncludeBtn(obj, show, val)
{
	snapInclude(obj, show, val);
	if (obj && obj.parentNode)
	{  var bParent = obj.parentNode;
		if (bParent && bParent.tagName && ("a" == bParent.tagName.toLowerCase()))
		{
			snapInclude(bParent, show, val);
		}
	}
}

function snapHide(obj, show)
{
	if (obj)
	{
		obj.style.visibility=show?'visible':'hidden';
	}
}

// Variable display
function snapIsIncluded(obj)
{
	var result=false;
	if (obj)
		result=(obj.style.display!='none');
	return result;
}

////////////////////////////////////////////////////////////////////////////////
// Rotation
function snapRotateGrid(questionList, rotationType)
{
	var aCode;
	var questions = questionList.split(',');
	var questionNodes=new Array();
	var i, j;
	var overallParent;
	var overallOk=true;
	for(i=0;i<questions.length;i++)
	{
		var nodes=snapObject(questions[i]+"_1");
		questionNodes[i]=snapObject(questions[i]+"_1");
		for(j=0;j<2;j++)
		{
			if(questionNodes[i])
			questionNodes[i]=questionNodes[i].parentNode;
		}
		if(questionNodes[i])
		{
			if(i==0)
			{
				overallParent=questionNodes[i].parentNode;
				if(!overallParent)
				{
					overallOk=false;
				}
			} else if(overallParent!=questionNodes[i].parentNode)
			{
				overallOk=false;
			}
		} else
		{
			overallOk=false;
		}
	}
	if(overallOk)
	{
		var newOrder=snapRotationOrder(questions.length, rotationType)
		for(i=0;i<questions.length;i++)
			overallParent.appendChild(questionNodes[newOrder[i]-1]);
	}
}

// Rotation
function snapRotationOrder(numCodes, rotationType)
{
	var codeList=new Array(numCodes);
	var i, j;
	var newCodeNum;

	for(i=0;i<numCodes;i++)
		codeList[i]=i+1;
	if(rotationType=='random')
	{
		for(i=0;i<numCodes;i++)
		{
			do
			{
				newCodeNum=Math.round(Math.random()*numCodes);
			} while(newCodeNum<0 || newCodeNum>=numCodes);
			j=codeList[i];
			codeList[i]=codeList[newCodeNum];
			codeList[newCodeNum]=j;
		}
	} else if(rotationType=='inverse')
	{
		if(Math.random()>=0.5)
		{
			for(i=0;i<numCodes;i++)
				codeList[i]=numCodes-i;
		}
	} else if(rotationType=='forwards' || rotationType=='backwards')
	{
		j=Math.round(Math.random()*numCodes);
		for(i=0;i<numCodes;i++)
			codeList[i]=(i+j)%numCodes+1;
	}
	return codeList;
}

// Rotation
function findArrayValue(array, value)
{
	var i;
	for(i=0;i<array.length;i++)
	{
		if(array[i]==value)
			return i;
	}
	return null;
}

// Rotation
function snapRotateCodesDropdown(question, numCodes, rotationType)
{
	var aCode=snapObject(question+"_1");
	if(aCode && aCode.childNodes)
	{
		if(numCodes>=aCode.childNodes.length)
			numCodes=aCode.childNodes.length-1;
		var targetOrder=snapRotationOrder(numCodes, rotationType);
		var minCode=aCode.childNodes.length;
		for(var i=0; i<numCodes; i++)
		{
			for(var j=0;j<aCode.childNodes.length;j++)
			{
				if(aCode.childNodes[j].value==targetOrder[i])
				{
					if(minCode>j)
						minCode=j;
					aCode.appendChild(aCode.childNodes[j]);
					j=aCode.childNodes.length;
				}
			}
		}
		i+=minCode;
		while(i<aCode.childNodes.length && minCode>=0 && minCode<aCode.childNodes.length)
		{
			aCode.appendChild(aCode.childNodes[minCode]);
			i++;
		}
	}
}

// Rotation
function snapRotateCodes(question, numCodes, rotationType)
{
	if(snapIsDropdown(question))
	{
		snapRotateCodesDropdown(question, numCodes, rotationType);
	} else
	{
		var i, j, k;
		var aCode, aCodeNum, aParent;
		var newCode, newCodeNum, newParent;
		var targetOrder=snapRotationOrder(numCodes, rotationType);
		var actualOrder=new Array(numCodes);
		for (i=0; i<numCodes; i++)
			actualOrder[i]=i+1;

		for (i=0; i<numCodes; i++)
		{
			aCodeNum=actualOrder[i];
			newCodeNum=targetOrder[i];
			if (aCodeNum != newCodeNum)
			{
				j=findArrayValue(actualOrder, newCodeNum);
				aCode=snapObject(question+"c"+aCodeNum);
				newCode=snapObject(question+"c"+newCodeNum);
				if (aCode == null)
					aCode=snapObject(question+"_"+aCodeNum);
				if (newCode == null)
					newCode=snapObject(question+"_"+newCodeNum);

				if(aCode && aCode.parentNode && newCode && newCode.parentNode)
				{
					k=actualOrder[i];
					actualOrder[i]=actualOrder[j];
					actualOrder[j]=k;

					snapSwapObs(aCode, newCode);
					snapSwapObs(snapObject(question+"g"+aCodeNum), snapObject(question+"g"+newCodeNum));
					snapSwapObs(snapObject(question+"v"+aCodeNum), snapObject(question+"v"+newCodeNum));
				}
			}
		}
	}
}

function snapSwapObs(aCode, newCode)
{
	if(aCode &&  newCode)
	{
		var aParent=aCode.parentNode;
		var newParent=newCode.parentNode;
		if (aParent &&newParent)
		{
			aParent.removeChild(aCode);
			newParent.removeChild(newCode);

			aParent.appendChild(newCode);
			newParent.appendChild(aCode);
		}
	}
}

////////////////////////////////////////////////////////////////////////////////
// Variable No Reply
function snapIsNoReply(question)
{
	return snapVarReply(question)=="(no reply)";
}

// Variable No Reply
function snapForceReply(question, realName)
{
	var result=true;
	if(asked(question) && snapIsNoReply(question))
	{
		alert("Please provide an answer for question "+realName+".");
		result=false;
	}
	return result;
}

function snapPageValidationOk(page)
{
	var result=true;
	page=snapMappedPage(page);
	if(page>=1 && page<=lastPageNumber)
	{
		var pageItems = pageContents[page];
		for(var j=0; j<pageItems.length && result; j++)
		{
			if(validateList[pageItems[j]]!=null)
			{
				result=eval(validateList[pageItems[j]]);
			}
			if(result && (forceReply[pageItems[j]]!=null))
			{
				result=snapForceReply(pageItems[j], forceReply[pageItems[j]]);
			}
		}
	}
	return result;
}

function doAutoAns(varName)
{
	if (null != codeMaskList[varName])
	{
		var numCodes=snapNumCodes(varName);
		var autoReplies=0;
		var selObj = null;
		if (snapIsDropdown(varName))
			selObj = snapObject(varName+'_1');
		var changed = false;
		for(var i=1;i<=numCodes;i++)
		{
			var expr=codeMaskList[varName].replace(/code/g, i);
			var showThisCode=eval(expr);
			if (selObj && selObj.options)
			{
				var found = false;
				for (var x = 0; x < selObj.options.length && !found; x++)
				{
					if (selObj.options[x].value == i)
					{
						found = true;
						if (selObj.options[x].selected != null)
						{
							if (showThisCode != selObj.options[x].selected)
							{
								changed = true;
								selObj.options[x].selected = showThisCode;
							}
						}
					}
				}
			}
			else
			{
				var codeOb = snapObject(varName+'_'+i);
				if (codeOb && codeOb.checked != null)
				{ 
					if (showThisCode != codeOb.checked)
					{
						changed = true;
						codeOb.checked = showThisCode;
					}
				}
			}
		}
		if (changed)
			snapOnChange(varName);
	}
}

////////////////////////////////////////////////////////////////////////////////
// Variable Not Asked
function snapEvalAskedFor(v, postponedItems)
{
	var somethingShown=true;
	var isGrid = snapIsGrid(v);
	var changed = false;
	if(askedCalc[v] || codeMaskList[v])
	{
		var ask=asked(v);
		ask=(ask==null || ask);
		askedCache[v]=ask;
		somethingShown=ask;
		if(isGrid)
		{
			var gridLine=snapObject(v+'_1');
			while(gridLine!=null && (gridLine.tagName==null || gridLine.tagName.toLowerCase()!='tr'))
				gridLine=gridLine.parentNode;
			if(gridLine!=null)
			{
				snapInclude(gridLine, ask);
			}
			var gridOwner=v;
			if(gridFirstList[v]!=null)
			{
				gridOwner=gridFirstList[v];
				snapInclude(snapObject(v+'_SPACER'), ask);
			}
			var gridName = gridOwner +"_GRID"
			if(askedCalc[gridName])
			{
				var ask=asked(gridName);
				snapInclude(snapObject(gridName), ask);
				snapInclude(snapObject(gridOwner+'_SPACER'), ask);
				somethingShown=ask;
			}
		} else
		{
			if (snapInclude(snapObject(v), ask))
				changed = true;
			snapInclude(snapObject(v+'_SPACER'), ask);
		}
		if (!ask && doAutoAnsList[v])
		{			
			doAutoAns(v);
		}
	}
	if(somethingShown && codeMaskList[v])
	{
		var isCombo = snapIsDropdown(v);
		var numCodes=snapNumCodes(v);
		var i;
		var showThisCode;
		somethingShown=false;
		for(i=1;i<=numCodes;i++)
		{
			var expr=codeMaskList[v].replace(/code/g, i);
			showThisCode=eval(expr);
			if (isCombo)
			{
				if (snapIncludeCombo(v, i, showThisCode, postponedItems))
					changed = true;
			}
			else
			{
				var codeObject = snapObject(v+'c'+i);
				var codeBox = snapObject(v+'_'+i);
				if(codeObject )
					snapInclude(codeObject, showThisCode);
				else
					snapInclude(codeBox, showThisCode);
				snapHide(snapObject(v+'g'+i), showThisCode);
				snapHide(snapObject(v+'v'+i), showThisCode);
				if (!showThisCode)
				{
					if (codeBox && (codeBox.checked))
					{
						codeBox.checked = false;
						changed = true;
					}
				}
			}
			if(showThisCode)
				somethingShown=true;
		}
	}
	if (changed)
		snapOnChange(v);
	return somethingShown;
}

function snapIncludeCombo(name, code, showThisCode, postponedItems)
{
	var changed = false;
	var selOb = snapObject(name + '_1');
	if (selOb && selOb.options && (cacheSelectOptions.splice!=null))
	{
		var found = false;
		if (showThisCode)
		{
			var removedList = cacheSelectOptions[name];
			if (removedList)
			{
				for (var i =0; i < removedList.length && !found; i++)
				{
					if (removedList[i].value != null && removedList[i].value == code)
					{
						found = true;
						if (postponedItems)
						{
							postponedItems[name] = true;
						}
						else
						{
							var option = removedList[i];
							removedList.splice(i, 1);
							var pos = null;
							for (var j =0; j < selOb.options.length && (null == pos); j++)
							{
								if (selOb.options[j].value > option.value || (selOb.options[j].value ==0 && selOb.options[j].text==""))
								{
									pos = selOb.options[j];
								}
							}
							selOb.insertBefore(option, pos );
						}
					}
				}

			}
		}
		else
		{
			for (var i =0; i < selOb.options.length && !found; i++)
			{
				if (selOb.options[i].value == code)
				{
					found = true;
					if (selOb.options[i].selected)
					{
						changed = true;
						try{
						selOb.options[i].selected = false;
						}catch(e)
						{//ie 6 bug?
						}
					}
					if (postponedItems)
					{
						postponedItems[name] = true;
					}
					else
					{
						var option = selOb.options[i];
						selOb.removeChild(option);
						if (!cacheSelectOptions[name])
							cacheSelectOptions[name] = new Array();
						cacheSelectOptions[name].push(option);
					}
				}
			}

		}
	}
	return changed;
}

////////////////////////////////////////////////////////////////////////////////
// Variable exclusive
function snapCheckExclusiveOf(object)
{
	if (object.checked && object.name && exclusive[object.name] && object.id)
	{
		var changed = false;
		var c;
		var excl=exclusive[object.name];
		var code=parseInt(object.id.substr(object.id.indexOf('_')+1), 10);
		var isExclusive=false;
		for (c=0; c<excl.length && !isExclusive; c++)
		{
			if (excl[c]==code)
			isExclusive=true;
		}
		if (isExclusive)
		{
			var codeList=snapObjectsByName(object.name);
			for (c=0; c<codeList.length; c++)
			{
				if (object!=codeList[c] && codeList[c].checked)
				{  codeList[c].checked=false;
					changed = true;
				}
			}
		} else
		{
			for (c=0; c<excl.length; c++)
			{
				code=snapObject(object.name+'_'+excl[c]);
				if (code && code.checked)
				{	code.checked=false;
					changed = true;
				}
			}
		}
		if (changed)
		{
			snapOnChange(object.name);
		}
	}
}

////////////////////////////////////////////////////////////////////////////////
// Variable type

function snapNumCodes(question)
{
	var result=cacheNumCodes[question];
	if(result==null)
	{
		var testCombo = snapObject(question+"_"+1);
		if (testCombo && testCombo.tagName && testCombo.tagName.toLowerCase() == 'select')
		{
			result = testCombo.options.length - 1;
		}
		else
		{
			var c=1;
			result=0;
			while(snapObject(question+"_"+c))
			{
				result=c;
				c++;
			}
		}
		cacheNumCodes[question]=result;
	}
	return result;
}

// Variable type
function snapIsOpen(name)
{
	var result=cacheIsOpen[name];
	if(result==null)
	{
		result=false;
		var aCode;
		aCode=snapObject(name+'_1');
		if(aCode!=null)
			result=(aCode.type=='text' || aCode.type=='textarea');
		cacheIsOpen[name]=result;
	}
	return result;
}

// Variable type
function snapIsClosed(name)
{
	var result=cacheIsClosed[name];
	if(result==null)
	{
		result=false;
		var aCode;
		aCode=snapObject(name+'_1');
		if(aCode!=null)
			result=(aCode.type=='checkbox' || aCode.type=='radio' || aCode.type=='select-one' || aCode.type=='select-multiple');
		cacheIsClosed[name]=result;
	}
	return result;
}

// Variable type
function snapIsDropdown(name)
{
	var result=cacheIsDropdown[name];
	if(result==null)
	{
		result=false;
		var aCode;
		aCode=snapObject(name+'_1');
		if(aCode!=null)
			result=(aCode.type=='select-one' || aCode.type=='select-multiple');
		cacheIsDropdown[name]=result;
	}
	return result;
}

function snapObjectLabel(name, code)
{
	var result=null;
	var all_labels = snapObjectsByTagName('label');
	var i;
	if(gridFirstList[name]!=null)
		name=gridFirstList[name];
	for(i=0;i<all_labels.length && result==null;i++)
	{
		if(all_labels[i].htmlFor && all_labels[i].htmlFor==name+'_'+code)
		{
			result=all_labels[i];
		}
	}
	return result;
}

// Variable type
function snapIsGrid(name)
{
	var result=cacheIsGrid[name];
	if(result==null)
	{
		result = false;
		if(gridFirstList[name]!=null)
		{
			result = true;
		}
		else
		{
			var posGridName = name+"_GRID";
			if (null != snapObject(posGridName))
			{
				result = true;
			}
		}
		cacheIsGrid[name]=result;
	}
	return result;
}

////////////////////////////////////////////////////////////////////////////////
// Variable response
function snapVarReply(name)
{
	var result="(no reply)";
	if (asked(name))
	{  if(snapIsOpen(name))
			result=snapOpenReply(name);
		else if(snapIsClosed(name))
			result=snapClosedReply(name);
	}
	return result;
}

// Variable response
function snapVarValue(name)
{
	var result="";
	var c=1;
	var code=snapObject(name+'_'+c);
	while(code)
	{
		if(code.options)
		{
			for (var i = 0; i < code.options.length; i++)
			{
				var thisOption=code.options[i];
				if(thisOption!=null && thisOption.selected && thisOption.value!=null && thisOption.value.length>0)
				{
					if(result.length>0)
						result+=';';
					result+=thisOption.value;
				}
			}
		} else
		{
			if((code.checked==null || code.checked) && code.value!=null && code.value.length>0)
			{
				if(result.length>0)
					result+=';';
				result+=code.value;
			}
		}
		c++;
		code=snapObject(name+'_'+c);
	}
	return result;
}

// Variable response
function snapClosedAns(name)
{
	var result=null;
	if(asked(name))
	{
		result=snapVarValue(name);
	}
	if(result==null)
		result="";
	return result;
}

// Variable response
function snapClosedReply(name)
{
	var result="(no reply)";
	var response=snapVarValue(name);
	if(response.length>0)
	{
		var responses=response.split(";");
		var i;
		result="";
		for(i=0;i<responses.length;i++)
		{
			if(i>0)
			{
				if(i<responses.length-1)
					result+=", ";
				else
					result+=" and ";
			}
			codeLabel=snapCodeLabel(name, responses[i]);
			result+=codeLabel;
		}
	}
	return result;
}

// Variable response
function snapCodeLabel(name, code)
{
	var result=code;
	if(snapIsDropdown(name))
	{
		var labelNode=snapObject(name+'_1');
		var i;
		for(i=0;i<labelNode.childNodes.length;i++)
		{
			if(code==labelNode.childNodes[i].value && labelNode.childNodes[i].firstChild!=null)
				result=labelNode.childNodes[i].firstChild.nodeValue;
		}
	} else
	{
		var all_labels = snapObjectsByTagName('label');
		var i;
		if(gridFirstList[name]!=null)
			name=gridFirstList[name];
		for(i=0;i<all_labels.length;i++)
		{
			if(all_labels[i].htmlFor && all_labels[i].htmlFor==name+'_'+code)
			{
				if (all_labels[i].innerText)
					result=all_labels[i].innerText;
				else if (all_labels[i].textContent )
					result=all_labels[i].textContent;
				else if (all_labels[i].firstChild && (null != all_labels[i].firstChild.nodeValue))
					result=all_labels[i].firstChild.nodeValue;
				else if (all_labels[i].innerHTML)
					result=all_labels[i].innerHTML;
			}
		}
	}
	return result;
}

// Variable response
function snapOpenAns(name)
{
	var reply=""
	if(asked(name))
	{
		var glovar=snapObject(name+'_1');
		if(glovar != null && glovar.value!=null)
			reply=glovar.value;
	}
	return reply;
}

// Variable response
function snapOpenReply(name)
{
	var reply=""
	var glovar=snapObject(name+'_1');
	if(glovar != null)
	{
		reply=glovar.value;
		if(reply!=null)
		{
			while(reply.length>0 && reply.charAt(reply.length-1)==' ')
				reply=reply.substr(0, reply.length-1);
			while(reply.length>0 && reply.charAt(0)==' ')
				reply=reply.substr(1, reply.length-1);
		}
	}
	if(reply==null || reply.length==0)
		reply="(no reply)";
	return reply;
}

// Variable response
function snapSetOpenReply(name, value)
{
	var glovar=snapObject(name+'_1');
	if(glovar != null && glovar.value!=null)
		glovar.value=value;
}

// Variable response
function snapChangeMade(arg)
{
	var origin = snapEventOrigin(arg);
	if (origin)
	{
		snapCheckValueOf(origin);
		snapOnChange(origin.name);
	}
}
function snapOnChange(name)
{
	if (name)
	{
		snapUndoRoutingFor(name);
		snapResponse(name);
		snapEvalTotals(name);
		snapSubstituteText(name);
		snapEvalPageRouting();
	}
}



// Variable response
// Check syntax of open-ended variables / check exclusive code settings for others
function snapCheckValueOf(object)
{
	if (object.type=='checkbox')
		snapCheckExclusiveOf(object);
	else if ((object.tagName != null) && (object.tagName.toLowerCase()=='select'))
		snapSelectExclusiveOf(object);
}

function	snapSelectExclusiveOf(object)
{  if (object.name && exclusive[object.name] && object.id)
	{  try{  nota_dd(object, exclusive[object.name]);
	   }catch(e){//nota_dd may not exist
	   }
	}
}


// Variable response
function snapResponse(name)
{
	var reply='';
	var code;
	if (codeLabels[name])
	{
		var labels=eval('new Array('+codeLabels[name]+')');
		var xref=new Array();
		var i;
		var x=0;
		for (i=0, x=0; i<labels.length; i++)
		{
			code=snapObject(name+'_'+(i+1));
			if (code && code.checked)
				xref[x++]=i;
		}
		if (xref.length>0)
		{
			reply=labels[xref[0]];
			if (xref.length>1)
			{
				for (i=1; i<xref.length-1; i++)
					reply = reply+', '+labels[xref[i]];
				reply = reply+' and '+labels[xref[i]];
			}
		}
	} else
	{
		code=snapObject(name+'_1');
		if (code)
			reply=code.value;
	}
	if (reply.length)
	{
		var places=snapObjectsByName(name+'_reply');
		for (i=0; i<places.length; i++)
		{
			places[i].firstChild.nodeValue=reply;
		}
	}

}

////////////////////////////////////////////////////////////////////////////////
// Used by snapparj
function getAsked(name)
{
	var isAsked = true;
	if(!name || name=="")
	{
		isAsked=false;
	} else if(askedCalc[name])
	{
		isAsked=eval(askedCalc[name]);
	}
	if (isAsked && (null != codeMaskList[name]))
	{
		var numCodes=snapNumCodes(name);
		var autoReplies=0;
		if (autoAnsList[name])
		{
			doAutoAnsList[name] = false;
			autoReplies = autoAnsList[name];
		}
		var showing = 0;
		for(var i=1;i<=numCodes && (showing <= autoReplies);i++)
		{
			var expr=codeMaskList[name].replace(/code/g, i);
			var showThisCode=eval(expr);
			if (showThisCode)
				showing++;
		}
		if (showing <= autoReplies)
		{
			isAsked = false;
			if (autoReplies > 0)
				doAutoAnsList[name] = true;
		}
	}

	return isAsked;
}

// Used by snapparj
function asked(name)
{
	if (null == askedCache[name])
	{
		askedCache[name]=getAsked(name);
	}
	return askedCache[name];
}

// Used by snapparj
function noreply(name)
{
	var isNR = false;
	if (asked(name))
	{
		if (ans(name) == "")
		{
			isNR = true;
		}
	}
	return isNR;
}

// Used by snapparj
function ans(name)
{
	var answer="";
	if(snapIsOpen(name))
		answer=snapOpenAns(name);
	else if(snapIsClosed(name))
		answer=snapClosedAns(name);
	return answer;
}

// Used by snapparj
function ansAsNum(name)
{
	return parseFloat(ans(name));
}

// Used by snapparj
function cVR(name,value)
{
	var result=false;
	if (asked(name))
	{
		var glovar=snapObject(name);
		if(glovar != null)
		{
			var testValue=snapVarValue(name);
			if((";"+testValue+";").indexOf(";"+value+";")>=0)
			{
				result=true;
			}
		}
	}
	return result;
}

// Used by snapparj
function cVV(name1,name2)
{
	var result=false;
	if (asked(name1) && asked(name2) && !noreply(name1) && !noreply(name2))
	{
		var r1=";"+ans(name1)+";"
		var r2=";"+ans(name2)+";"
		while(r2.length>2&&!result)
		{
			var i=r2.substring(1).indexOf(";")+1;
			if(r1.indexOf(r2.substring(0,i+1))>=0)
				result=true;
			else
				r2=r2.substring(i);
		}
	}
	return result;
}

// Used by snapparj
function cVM(name)//(, ...)
{
	var result=false;
	var numArgs = arguments.length;
	if (1 < numArgs)
	{
		var answer = ans(name);
		if (answer!="")
		{
			answer = ";"+answer+";";
			for (i = 1; (i < numArgs) && !result; i++)
			{
				if (0 <= answer.indexOf(";"+arguments[i]+";"))
				{
					result = true;
				}
			}
		}
	}
	return result;
}

// Used by snapparj
function cInRange(value, minValue, maxValue)
{
	var result=(value!=null && (maxValue!=NaN) && (minValue!=NaN) && (value>=minValue && value<=maxValue)||(value>=maxValue && value<=minValue));
	return result;
}

////////////////////////////////////////////////////////////////////////////////

function codeReply(name,nameCodes)
{
	var reply="";
	var glovar=snapObject(name);
	if(glovar != null)
	{
		var first=true;
		var mValue=glovar.value+";";
		while(mValue.length>1)
		{
			var cPos=mValue.indexOf(";");
			if(!first)
			{
				if(cPos==mValue.length-1)
					reply+=" and ";
				else
					reply+=", ";
			}
			reply+=nameCodes[parseInt(mValue.substring(0,cPos), 10)-1];
			first=false;
			mValue=mValue.substring(cPos+1);
		}
	}
	if(reply.length==0)
		reply="(no reply)";
	return reply;
}


////////////////////////////////////////////////////////////////////////////////
// Timer
function fStartTimer(uk)
{
	if (!timerStarted)
	{
		startPoint = new Date();

		var hours = startPoint.getHours();
		var mins = "00" + startPoint.getMinutes();
		var timeValue = ""+hours+":"+mins.substr(mins.length - 2);

		var days = startPoint.getDate();
		var months = startPoint.getMonth() + 1;
		var years = "00" + startPoint.getYear().toString();
		years = years.substr(years.length - 2);
		var dateValue;
		if (uk)
			dateValue = days + "/" + months + "/" + years;
		else
			dateValue = months + "/" + days + "/" + years;

		snapSetOpenReply("0", timeValue);
		snapSetOpenReply("0", dateValue);

		timerStarted = true;
	}
}

// Timer
function fEndTimer()
{
	if (timerStarted)
	{
		endPoint = new Date();
		var hours = endPoint.getHours();
		var mins = "00" + endPoint.getMinutes();
		var timeValue = ""+hours+":"+mins.substr(mins.length - 2);
		var durationValue=((endPoint - startPoint) / 60000);

		snapSetOpenReply("0", timeValue);
		snapSetOpenReply("0", durationValue);

		if (snapObject("0_1"))
		{
			var days = endPoint.getDate();
			var months = endPoint.getMonth() + 1;
			var years = "00" + startPoint.getYear().toString();
			years = years.substr(years.length - 2);
			var dateValue;
			if (true)//true=uk,false=usa
				dateValue = days + "/" + months + "/" + years;
			else
				dateValue = months + "/" + days + "/" + years;
			snapSetOpenReply("0", dateValue);
		}

		timerStarted = false;
	}
}

// Timer
function getIndex(name,aDoc)
{
	for(c=0;c<aDoc.length;c++)
	{
		if(aDoc[c].name==name)
		return c;
	}
	return -1;
}

////////////////////////////////////////////////////////////////////////////////
// Progress Bar
function pbRatio(OutOf)
{
	var result=1;
	if (pageNumber >= lastPageNumber)
		result = OutOf;
	else if (pageNumber <= 1)
		result =1;
	else if (OutOf <= 2)
		result = Math.round(OutOf*pageNumber/lastPageNumber);
	else
		result = 2 + Math.floor((OutOf-2)*(pageNumber-1)/(lastPageNumber-1));
	if (1>result)
		result="01";
	else if (10 > result)
		result = "0" + result;
	else
		result = "" + result;
	return result;
}

////////////////////////////////////////////////////////////////////////////////
// Validation
function isValidNum(name,allowNegatives,realName)
{
	var isValid=true;
	var locVar=snapObject(name);
	if (locVar != null)
	{
		var numstr=locVar.value;
		if (allowNegatives+""=="undefined" || allowNegatives+""=="null")
			allowNegatives = true;
		numstr+="";
		for(i=0;i<numstr.length;i++)
		{
			if (!((numstr.charAt(i)>="0")&&(numstr.charAt(i)<="9")||((numstr.charAt(i)==".")&&(numstr.charAt(i+1)!="."))||(numstr.charAt(i)=="-")))
				isValid=false;
			else if((numstr.charAt(i)=="-"&&i!=0)||(numstr.charAt(i)=="-"&&!allowNegatives))
				isValid=false;
		}
		if(!isValid)
		{
			locVar.focus();
			alert("Please enter a valid number for question "+realName+".");
		}
	}
	return isValid;
}

// Validation
function RangeCheck(name,realName,min,max,UiCode)
{
	var isValid=true;
	var locVar=snapObject(name);
	if (locVar != null)
	{
		var numstr=""+locVar.value;
		if (0 < numstr.length)
		{
			var number = parseFloat(numstr);
			if(number<min || number>max || isNaN(number))
			{
				isValid = false;
				locVar.focus();
				if ((1 == UiCode) && (min!=max))
				{
					alert("Please give an answer between "+min+" and "+max+" for question "+realName+".");
				} else if (0 != UiCode)
				{
					alert("Please enter a valid number for question "+realName+".");
				}
			}
		}
	}
	return isValid;
}

// Validation
function DateRange(name,realName,min,max,UiCode)
{
	var varDate = getVarDate(name,realName);
	var isValid = ("invalid" != varDate);
	if(isValid && ("" != varDate))
	{
		if((varDate.getTime() < min.getTime())||(varDate.getTime() > max.getTime()))
		{
			isValid = false;
			var locVar=snapObject(name);
			if (locVar != null)
			{
				locVar.focus();
			}
			if ((1 == UiCode) && (min.getTime()!=max.getTime()))
			{
				alert("Please give an answer between "+FormatDate(min)+" and "+FormatDate(max)+" for question "+realName+".");
			} else if (0 != UiCode)
			{
				alert("You've entered an invalid date or date format for question "+realName+".\n");
			}
		}
	}
	return isValid;
}

// Validation
function getVarDate(name,realName)
{
	var indate="";
	var locVar = snapObject(name);
	if (locVar != null)
		indate=locVar.value;
	if(indate==null || indate.length==0)
		return "";
	var punct;
	if(indate.indexOf(".")!=-1)
		punct=".";
	else if(indate.indexOf("-")!=-1)
		punct="-";
	else
		punct="/";
	var day;
	var month;
	var year;
	var warningMessage;
	if (true)//true=uk,false=usa
	{
		day=indate.substring(0,indate.indexOf(punct));
		month=indate.substring(indate.indexOf(punct)+1,indate.lastIndexOf(punct));
		warningMessage = "Please use the DD/MM/YY format.";
	} else
	{
		month=indate.substring(0,indate.indexOf(punct));
		day=indate.substring(indate.indexOf(punct)+1,indate.lastIndexOf(punct));
		warningMessage = "Please use the MM/DD/YY format.";
	}
	year=indate.substring(indate.lastIndexOf(punct)+1,indate.length);
	month = getMonthName(month-1);
	if (year.length == 2)
	{
		if (30 > parseInt(year, 10))
		{
			year = "20"+year;
		} else
		{
			year = "19"+year;
		}
	}
	if (month=="" || year.length != 4 || parseInt(day, 10) > 31)
	{
		locVar.focus();
		alert("You've entered an invalid date or date format for question "+realName+".\n"+warningMessage);
		return "invalid";
	}
	if (day.length == 1)
		day = "0" + day;
	var varDate = new Date(Date.parse(month + " " + day + ", " + year));
	var cmpDate1 = day + "/" + month + "/" + year;
	var month2 = getMonthName(varDate.getMonth());
	day = varDate.getDate();
	if (day.toString().length == 1)
	{
		day = "0" + day;
	}
	var cmpDate2 = day + "/" + month2 + "/" + varDate.getFullYear();
	if (cmpDate1 != cmpDate2)
	{
		locVar.focus();
		alert("You've entered an invalid date or date format for question "+realName+".\n"+warningMessage);
		return "invalid";
	}
	return varDate;
}

// Validation
function isValidDate(name,realName)
{
	var varDate = getVarDate(name,realName);
	return ("invalid" != varDate);
}

// Validation
function TimeRange(name,realName,min,max,UiCode)
{
	var varTime = getVarTime(name,realName);
	var isValid = ("invalid" != varTime);
	if(isValid && ("" != varTime))
	{
		if((varTime.getTime() < min.getTime())||(varTime.getTime() > max.getTime()))
		{
			isValid = false;
			var locVar = snapObject(name);
			if (locVar != null)
				locVar.focus();
			if ((1 == UiCode) && (min.getTime()!=max.getTime()))
			{
				alert("Please give an answer between "+FormatTime(min)+" and "+FormatTime(max)+" for question "+realName+".");
			} else if (0 != UiCode)
			{
				alert("You've entered an invalid time or time format for question "+realName+".\n");
			}
		}
	}
	return isValid;
}

// Validation
function getVarTime(name,realName)
{
	var intime="";
	var locVar = snapObject(name);
	if (locVar != null)
		intime=locVar.value;
	if(intime.length==0)
		return "";
	var punct;
	if(intime.indexOf(".")!=-1)
		punct=".";
	else if(intime.indexOf("-")!=-1)
		punct="-";
	else
		punct=":";
	var hour = "00";
	var minute = "00";
	var second = "00";
	var times = intime.split(punct);
	if(times.length >= 1)
		hour = times[0];
	if(times.length >= 2)
		minute = times[1];
	if(times.length >= 3)
		second = times[2];
	if(parseInt(hour, 10) > 23 || parseInt(minute, 10) > 59 || parseInt(second, 10) > 59)
	{
		locVar.focus();
		alert("You've entered an invalid time or time format for question "+realName+".\n"+"Please use the hh:mm:ss format.");
		return "invalid";
	}
	if (hour.length == 1)
		hour = "0" + hour;
	if (minute.length == 1)
		minute = "0" + minute;
	if (second.length == 1)
		second = "0" + second;
	var varTime = new Date(Date.parse("1/1/1970 " + hour + ":" + minute + ":" + second));
	var cmpTime1 = hour + ":" + minute + ":" + second;
	hour = varTime.getHours();
	minute = varTime.getMinutes();
	second = varTime.getSeconds();
	if (hour.toString().length == 1)
		hour = "0" + hour;
	if (minute.toString().length == 1)
		minute = "0" + minute;
	if (second.toString().length == 1)
		second = "0" + second;
	var cmpTime2 = hour + ":" + minute + ":" + second;
	if (cmpTime1 != cmpTime2)
	{
		locVar.focus();
		alert("You've entered an invalid time or time format for question "+realName+".\n"+"Please use the hh:mm:ss format.");
		return "invalid";
	}
	return varTime;
}

// Validation
function AnswerRange(varName,realName,min, max)
{
	var valid = true;

	var numCodes = snapNumCodes(varName);
	var count = 0;
	if (snapIsDropdown(varName))
	{
		var control = snapObject(varName + '_1');
		if (control && (control.options != null))
		{
			for (var x = 0; (x < control.options.length); x++)
			{
				if (control.options[x].selected && (control.options[x].value>0))
				{  count++;
				}
			}
		}
	}
	else
	{
		for (var x=1; x <= numCodes; x++)
		{
			var codeOb =  snapObject(varName + '_' + x);
			if (codeOb && (codeOb.checked))
			{ count++;
			}
		}
	}

	if (count < min)
	{
		valid = false;
	}
	else if (count > max)
	{
		valid = false;
	}
	if (!valid)
	{
		alert("Question "+realName+" requires between "+min+" and "+max+" replies.");
	}

	return valid;
}
// Validation
function isValidTime(name,realName)
{
	var varTime = getVarTime(name,realName);
	return ("invalid" != varTime);
}
// Validation
function ValidationPattern(name,realName,pattern,patternName)
{
	var Result=true;
	var indate="";
	var locVar = snapObject(name);
	if (locVar != null)
	{
		indate=locVar.value;
		if(indate!=null && indate.length>0 && indate.search)
		{
			Result=(0<=indate.search(pattern));
			if(!Result)
			{
				alert("You've entered an invalid "+patternName+" for question "+realName+".");
			}
		}
	}
	return Result;
}

//masking
function VarToNum(varName)
{
	var result = 0;
	if (snapIsOpen(varName))
	{
		var control = snapObject(varName + '_1');
		if (control && (control.value != null))
		{
			result = parseInt(control.value, 10);
		}
	}
	else if (snapIsDropdown(varName))
	{
		var control = snapObject(varName + '_1');
		if (control && (control.options != null))
		{
			var ok = true;
			for (var x = 0; (x < control.options.length) && ok; x++)
			{
				if (control.options[x].selected)
				{
					if (0 == result)
					{
						result = control.options[x].value;
					}
					else
					{
						result = 0;
						ok = false;
					}
				}
			}
		}
	}
	else if (snapIsClosed(varName))
	{
		var numCodes = snapNumCodes(varName);
		var ok = true;
		for (var x = 1; (x <= numCodes) && ok; x++)
		{
			var control = snapObject(varName + '_' + x);
			if (control && control.checked)
			{
				if (0 == result)
				{
					result = control.value;
				}
				else
				{
					result = 0;
					ok = false;
				}
			}
		}
	}
	if (0 == result)
	{
		result = NaN;
	}
	return result;
}

////////////////////////////////////////////////////////////////////////////////
// Date and Time
function FormatDate(Date)
{
	var dateString = "";
	if (true)
	{
		dateString += Date.getDate()+"/";
		dateString += (1 + Date.getMonth());
	} else
	{
		dateString += (1 + Date.getMonth())+"/";
		dateString += Date.getDate();
	}
	dateString += "/" + Date.getYear();
	return dateString;
}

// Date and Time
function FormatTime(Time)
{
	var timeString = "";
	var tempStr = Time.getHours().toString();
	if (tempStr.length == 1)
		tempStr = "0" + tempStr;
	timeString += tempStr + ":";
	tempStr = Time.getMinutes().toString();
	if (tempStr.length == 1)
		tempStr = "0" + tempStr;
	timeString += tempStr + ":";
	tempStr = Time.getSeconds().toString();
	if (tempStr.length == 1)
		tempStr = "0" + tempStr;
	timeString += tempStr;
	return timeString;
}

// Date and Time
function GetToday()
{
	var Now = new Date;
	var Today = new Date(Now.getYear(), Now.getMonth(), Now.getDate());
	return Today;
}

// Date and Time
function getMonthName(i)
{
	var month = "";
	switch (i)
	{
	case 0: month="January";break;
	case 1: month="February";break;
	case 2: month="March";break;
	case 3: month="April";break;
	case 4: month="May";break;
	case 5: month="June";break;
	case 6: month="July";break;
	case 7: month="August";break;
	case 8: month="September";break;
	case 9: month="October";break;
	case 10: month="November";break;
	case 11: month="December";break;
	}
	return month;
}

// Date and Time
function GetNow()
{
	var Now = new Date;
	Now.setFullYear(1970, 0, 1);
	return Now;
}

////////////////////////////////////////////////////////////////////////////////
// Code Rotation
function getOrder(numCodes)
{
	var arr=new Array(numCodes);
	var numbers=new Array(numCodes);
	for (i=0; i<numCodes; i++)
	{
		numbers[i]=i;
	}
	for (i=numCodes ; i > 0; i--)
	{
		var ran = Math.round(Math.random() * i);
		if (ran == i)
			ran = 0;
		arr[i -1] = numbers[ran];
		//numbers.splice(ran, 1);
		for (j = ran; j< (i-1); j++)
			numbers[j] = numbers[j+1];
	}
	return arr;
}

// Code Rotation
function getRotatedOrder(numCodes, forwards)
{
	var arr=new Array(numCodes);
	for (i=0; i<numCodes; i++)
	{
		if (forwards)
		{
			arr[i]= (i - rotationKey)%numCodes;
			if (0 > arr[i])
			arr[i] += numCodes;
		} else
		{
			arr[i]= (i + rotationKey)%numCodes;
		}
	}
	return arr;
}

// Code Rotation
function getInvertedOrder(numCodes)
{
	var arr=new Array(numCodes);
	var inverted = ((rotationKey%2) == 0);
	for (i=0; i<numCodes; i++)
	{
		if (inverted)
		{
			arr[i]=(numCodes - i - 1);
		} else
		{
			arr[i]=i;
		}
	}
	return arr;
}

////////////////////////////////////////////////////////////////////////////////
function getLabel(labelArray, orderArray, code)
{
	return labelArray[orderArray[code]];
}

function getValue(orderArray, code)
{
	var val = orderArray[code] + 1;
	var str = "" + val;
	return str;
}

//hide everything for load

//-->
