






// This is the minified version of json2.js which is located in the same directory as this file using YUI compressor.
if(!this.JSON){this.JSON={}}(function(){function f(n){return n<10?"0"+n:n}if(typeof Date.prototype.toJSON!=="function"){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+"-"+f(this.getUTCMonth()+1)+"-"+f(this.getUTCDate())+"T"+f(this.getUTCHours())+":"+f(this.getUTCMinutes())+":"+f(this.getUTCSeconds())+"Z":null};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf()}}var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==="string"?c:"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})+'"':'"'+string+'"'}function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==="object"&&typeof value.toJSON==="function"){return value.toJSON(key)}if(typeof rep==="function"){value=rep.call(holder,key,value)}switch(typeof value){case"string":return quote(value);case"number":return isFinite(value)?String(value):"null";case"boolean":case"null":return String(value);case"object":if(!value){return"null"}gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==="[object Array]"){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||"null"}v=partial.length===0?"[]":gap?"[\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"]":"["+partial.join(",")+"]";gap=mind;return v}if(rep&&typeof rep==="object"){length=rep.length;for(i=0;i<length;i+=1){k=rep[i];if(typeof k==="string"){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}else{for(k in value){if(Object.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?": ":":")+v)}}}}v=partial.length===0?"{}":gap?"{\n"+gap+partial.join(",\n"+gap)+"\n"+mind+"}":"{"+partial.join(",")+"}";gap=mind;return v}}if(typeof JSON.stringify!=="function"){JSON.stringify=function(value,replacer,space){var i;gap="";indent="";if(typeof space==="number"){for(i=0;i<space;i+=1){indent+=" "}}else{if(typeof space==="string"){indent=space}}rep=replacer;if(replacer&&typeof replacer!=="function"&&(typeof replacer!=="object"||typeof replacer.length!=="number")){throw new Error("JSON.stringify")}return str("",{"":value})}}if(typeof JSON.parse!=="function"){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==="object"){for(k in value){if(Object.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v}else{delete value[k]}}}}return reviver.call(holder,key,value)}text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return"\\u"+("0000"+a.charCodeAt(0).toString(16)).slice(-4)})}if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,""))){j=eval("("+text+")");return typeof reviver==="function"?walk({"":j},""):j}throw new SyntaxError("JSON.parse")}}}());/*--------------- Client SuiteScript Implementation ------------*/

/*--------------- Event Handler implementations for custom code ------------*/
function nlapiPageInit(type)
{
	var origflag = window.isinited;
	try
	{
		setIsInited( window, true );/* --- set page_init flags so that machine calls function correctly. */
		if (document.forms['main_form'].elements.wfPI != null && document.forms['main_form'].elements.wfPI.value.length > 0)
		{
			nsapiCallScript( "pageInit", "internal", document.forms['main_form'].elements.wfPI.value, [type] );
		}
		if (document.forms['main_form'].elements.nsapiPI != null && document.forms['main_form'].elements.nsapiPI.value.length > 0)
		{
			nsapiCallScript( "pageInit", "internal", document.forms['main_form'].elements.nsapiPI.value, [type] );
		}
		if (document.forms['main_form'].elements.nlapiPI != null && document.forms['main_form'].elements.nlapiPI.value.length > 0)
		{
			var scripts = document.forms['main_form'].elements.nlapiPI.value.split(String.fromCharCode(1));
			for (var i = 0; i < scripts.length; i++)
				nsapiCallUserScript( "pageInit", fScriptIds[i], scripts[i], [type] );
		}
	}
	finally	/* restore page_init flags upon completion */
	{
		setIsInited(window, origflag);
	}
}
function nlapiSaveRecord()
{
	var isValid = true;
	try
	{
		if (document.forms['main_form'].elements.wfSR != null && document.forms['main_form'].elements.wfSR.value.length > 0)
		{
			isValid = nsapiCallScript( "saveRecord", "internal", document.forms['main_form'].elements.wfSR.value );
			if ( !isValid )
				return false;
		}
		if (document.forms['main_form'].elements.nsapiSR != null && document.forms['main_form'].elements.nsapiSR.value.length > 0)
		{
			isValid = nsapiCallScript( "saveRecord", "internal", document.forms['main_form'].elements.nsapiSR.value );
			if ( !isValid )
				return false;
		}
		if (document.forms['main_form'].elements.nlapiSR != null && document.forms['main_form'].elements.nlapiSR.value.length > 0)
		{
			var scripts = document.forms['main_form'].elements.nlapiSR.value.split(String.fromCharCode(1));
			for (var i = 0; isValid && i < scripts.length; i++)
				isValid = nsapiCallUserScript( "saveRecord", fScriptIds[i], scripts[i] );
		}
		return isValid;
	}
	finally
	{
		if (isValid)  /* if the save is valid, enabled any disabled main form fields prior to returning */
		{
			for (var fldnam in nsDisabledFields)
			{
				if (nsDisabledFields[fldnam])
					disableField(getFormElement( document.forms['main_form'], fldnam ),false);
				nsDisabledFields[fldnam] = false;
			}
		}
	}
}
function nlapiValidateField(type, fldnam, linenum, column, optionswin)
{
	if (!window.loadcomplete || document.page_is_resetting)
		return false;
	var isValid = true;
    if (type != null && linenum == null && column == null)
        linenum = nlapiGetCurrentLineItemIndex(type);
    var fld = nsapiResolveField(type, fldnam, linenum, column);
    if (fld == null)  // bail (for now) if the field cannot be found
        return isValid;
    if (optionswin != null)
        optwin = optionswin;
    var checkValidOrig = fld.checkvalid;
	try
	{
		fld.checkvalid = false;
		if (document.forms['main_form'].elements.wfVF != null && document.forms['main_form'].elements.wfVF.value.length > 0)
		{
			isValid = nsapiCallScript( "validateField", "internal", document.forms['main_form'].elements.wfVF.value, [type, fldnam, linenum, column] );
			if (!isValid)
				return false;
		}
		if (document.forms['main_form'].elements.nsapiVF != null && document.forms['main_form'].elements.nsapiVF.value.length > 0)
		{
			isValid = nsapiCallScript( "validateField", "internal", document.forms['main_form'].elements.nsapiVF.value, [type, fldnam, linenum, column] );
			if (!isValid)
				return false;
		}
		if (document.forms['main_form'].elements.nlapiVF != null && document.forms['main_form'].elements.nlapiVF.value.length > 0)
		{
			var scripts = document.forms['main_form'].elements.nlapiVF.value.split(String.fromCharCode(1));
			for (var i = 0; isValid && i < scripts.length; i++)
			{
				isValid = nsapiCallUserScript( "validateField", fScriptIds[i], scripts[i], [type, fldnam, linenum, column] );
			}
		}
		return isValid;
	}
	finally
	{
		optwin = null;
		fld.checkvalid = checkValidOrig;
		if (!isValid)
		{
			if (typeof(ftabs) != 'undefined')
			{
				var tab = ftabs[fldnam.toLowerCase()];
				if (tab != null && tab != "main" && !isTabShown(tab))
					ShowTab(tab,true);
			}
			setFieldFocus( fld );
			if (fld.select != null)
				fld.select();
		}
	}
}
function nlapiFieldChanged(type, fldnam, linenum, column, optionswin)
{
    if (!window.loadcomplete || document.page_is_resetting)
		return;
	try
	{
        if (type != null && linenum == null && column == null)
            linenum = nlapiGetCurrentLineItemIndex(type)
        var fld = nsapiResolveField(type, fldnam, linenum, column);
        if (fld == null)  // bail (for now) if the field cannot be found
            return;
        if (optionswin != null)
			optwin = optionswin;

		if (document.forms['main_form'].elements.wfFC != null && document.forms['main_form'].elements.wfFC.value.length > 0)
		{
			nsapiCallScript( "fieldChange", "internal", document.forms['main_form'].elements.wfFC.value, [type, fldnam, linenum, column] )
		}
		if (document.forms['main_form'].elements.nsapiFC != null && document.forms['main_form'].elements.nsapiFC.value.length > 0)
		{
			nsapiCallScript( "fieldChange", "internal", document.forms['main_form'].elements.nsapiFC.value, [type, fldnam, linenum, column] )
		}
		if (document.forms['main_form'].elements.nlapiFC != null && document.forms['main_form'].elements.nlapiFC.value.length > 0)
		{
			var scripts = document.forms['main_form'].elements.nlapiFC.value.split(String.fromCharCode(1));
			for (var i = 0; i < scripts.length; i++)
			{
				nsapiCallUserScript( "fieldChange", fScriptIds[i], scripts[i], [type, fldnam, linenum, column] );
			}
		}
	}
	finally
	{
		optwin = null;
	}
}
function nlapiPostSourcing(type, fldnam, linenum)
{
    if (!window.loadcomplete || document.page_is_resetting)
        return;
    var origflag = window.isinited;
	try
	{	/* --- set inited flags so that machine calls function correctly. */
		setIsInited( window, true );
		linenum = type != null && linenum == null ? nlapiGetCurrentLineItemIndex(type) : linenum;
		if (document.forms['main_form'].elements.wfPS != null && document.forms['main_form'].elements.wfPS.value.length > 0)
		{
			nsapiCallScript( "postSourcing", "internal", document.forms['main_form'].elements.wfPS.value, [type, fldnam, linenum] )
		}
		if (document.forms['main_form'].elements.nsapiPS != null && document.forms['main_form'].elements.nsapiPS.value.length > 0)
		{
			nsapiCallScript( "postSourcing", "internal", document.forms['main_form'].elements.nsapiPS.value, [type, fldnam, linenum] )
		}
		if (document.forms['main_form'].elements.nlapiPS != null && document.forms['main_form'].elements.nlapiPS.value.length > 0)
		{
			var scripts = document.forms['main_form'].elements.nlapiPS.value.split(String.fromCharCode(1));
			for (var i = 0; i < scripts.length; i++)
			{
				nsapiCallUserScript( "postSourcing", fScriptIds[i], scripts[i], [type, fldnam, linenum] );
			}
		}
	}
	finally	/* unset page_init flags. */
	{
		setIsInited( window, origflag );
	}

}
function nlapiLineInit(type)
{
	try
	{
		if (document.forms['main_form'].elements.nsapiLI != null && document.forms['main_form'].elements.nsapiLI.value.length > 0)
		{
			nsapiCallScript( "lineInit", "internal", document.forms['main_form'].elements.nsapiLI.value, [type] )
		}
		if (document.forms['main_form'].elements.nlapiLI != null && document.forms['main_form'].elements.nlapiLI.value.length > 0)
		{
			var scripts = document.forms['main_form'].elements.nlapiLI.value.split(String.fromCharCode(1));
			for (var i = 0; i < scripts.length; i++)
			{
				nsapiCallUserScript( "lineInit", fScriptIds[i], scripts[i], [type] );
			}
		}
	}
	finally
	{
		optwin = null;
	}
}
function nlapiLineCommit(type, linenum)
{
	try
	{
		if (document.forms['main_form'].elements.nsapiLC != null && document.forms['main_form'].elements.nsapiLC.value.length > 0)
		{
			nsapiCallScript( "lineCommit", "internal", document.forms['main_form'].elements.nsapiLC.value, [type, linenum] )
		}
	}
	finally
	{
        optwin = null;
	}
}
function nlapiValidateDelete(type)
{
	try
	{
		var isValid = true;
		if (document.forms['main_form'].elements.nsapiVD != null && document.forms['main_form'].elements.nsapiVD.value.length > 0)
		{
			isValid = nsapiCallScript( "validateDelete", "internal", document.forms['main_form'].elements.nsapiVD.value, [type] )
		}
		if (isValid && document.forms['main_form'].elements.nlapiVD != null && document.forms['main_form'].elements.nlapiVD.value.length > 0)
		{
			var scripts = document.forms['main_form'].elements.nlapiVD.value.split(String.fromCharCode(1));
			for (var i = 0; isValid && i < scripts.length; i++)
			{
				isValid = nsapiCallUserScript("validateDelete", fScriptIds[i], scripts[i], [type]);
			}
		}
		return isValid;
	}
	finally
	{
        optwin = null;
    }
}
function nlapiValidateInsert(type)
{
	try
	{
		var isValid = true;
		if (document.forms['main_form'].elements.nsapiVI != null && document.forms['main_form'].elements.nsapiVI.value.length > 0)
		{
			isValid = nsapiCallScript( "validateInsert", "internal", document.forms['main_form'].elements.nsapiVI.value, [type] )
		}
		if (isValid && document.forms['main_form'].elements.nlapiVI != null && document.forms['main_form'].elements.nlapiVI.value.length > 0)
		{
			var scripts = document.forms['main_form'].elements.nlapiVI.value.split(String.fromCharCode(1));
			for (var i = 0; isValid && i < scripts.length; i++)
			{
				isValid = nsapiCallUserScript("validateInsert", fScriptIds[i], scripts[i], [type]);
			}
		}
		return isValid;
	}
	finally
	{
		optwin = null;
	}
}
function nlapiValidateLine(type)
{
	try
	{
		var isValid = true;
		if (document.forms['main_form'].elements.nsapiVL != null && document.forms['main_form'].elements.nsapiVL.value.length > 0)
		{
			isValid = nsapiCallScript("validateLine", "internal", document.forms['main_form'].elements.nsapiVL.value, [type])
			if (!isValid)
				return false;
		}
		if (isValid && document.forms['main_form'].elements.nlapiVL != null && document.forms['main_form'].elements.nlapiVL.value.length > 0)
		{
			var scripts = document.forms['main_form'].elements.nlapiVL.value.split(String.fromCharCode(1));
			for (var i = 0; isValid && i < scripts.length; i++)
			{
				isValid = nsapiCallUserScript("validateLine", fScriptIds[i], scripts[i], [type]);
			}
		}
		return isValid;
	}
	finally
	{
		optwin = null;
	}
}
function nlapiRecalc(type, localRecalc, operation)
{
	try
	{
		if (localRecalc)
		{
			eval( isEditMachine(type) ? type+'_machine.recalc(!window.loadcomplete)' : type+'RecalcMachine(true)' )
			return;
		}
		operation = operation != null ? operation : "commit";
		if (document.forms['main_form'].elements.nsapiRC != null && document.forms['main_form'].elements.nsapiRC.value.length > 0)
		{
			nsapiCallScript( "recalc", "internal", document.forms['main_form'].elements.nsapiRC.value, [type, operation] )
		}
		if (document.forms['main_form'].elements.nlapiRC != null && document.forms['main_form'].elements.nlapiRC.value.length > 0)
		{
			var scripts = document.forms['main_form'].elements.nlapiRC.value.split(String.fromCharCode(1));
			for ( var i = 0; i < scripts.length; i++ )
			{
				nsapiCallUserScript( "recalc", fScriptIds[i], scripts[i], [type, operation] );
			}
		}
	}
	finally
	{
		optwin = null;
	}
}

/*--------------- Utility Functions for Setting/Getting/Manipulating fields and machines for current record ------------*/
function nlapiSetFieldValue(fldnam,value,firefieldchanged,synchronous)
{
    nsapiAssertTrue(!isSubrecordField(null, fldnam),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
	var unsupported = ' applied unapplied total exchangerate lastmodifieddate createddate datecreated roi openingbalance ';
    if (nsapiIsInternal() || unsupported.indexOf(' '+fldnam.toLowerCase()+' ') == -1)
    {
		var stype = typeof(ftypes) != 'undefined' && ftypes[fldnam.toLowerCase()] != null ? ftypes[fldnam.toLowerCase()] : null;
		if (stype != null && stype.indexOf('currency') >= 0 && !isValEmpty(value) && ("" + value).indexOf('.') == -1 && !isNaN(parseFloat(value)))
			value = pad_decimal_places("" + value, stype.indexOf('currency2') >= 0 ? 2 : get_precision());
		var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms['main_form'];
        if (form == null)
            form = document.forms['qadd_form'];
        var fld = getFormElement( form, fldnam.toLowerCase() );
        if (fld == null)
            fld = getFormElement( form, fldnam.toLowerCase()+"_send" );
        if ( fld != null )
        {
            try
            {
				if (synchronous)
                    setSlavingAsync(false)
				var ids = '', labels = '';
				if ( isPopupSelect( fld ) || isPopupMultiSelect( fld ) || isDisplayOnlySelect( fld ) )
				{
					var selectmap = NLEntryForm_querySelectText( fldnam, null, null, value )
					for ( var i in selectmap )
					{
						ids = selectmap[i] != null ? (ids != '' ? ids+String.fromCharCode(5) : '') + i : ids;
						labels = selectmap[i] != null ? (labels.length > 0 ? labels+String.fromCharCode(5) : '') + selectmap[ i ] : labels;
					}
				}
				else
				{
					ids = value;
					labels = null;
				}
				setFormValue(fld, ids, labels );
				if (document.getElementById(fldnam+"_val") != null)
                {
                    var displayValue = ids;
                    if (stype == "checkbox")
                        displayValue = (ids == "T" ? nsYesString : nsNoString);
                    else if (isNumericField(fld) || isCurrencyField(fld))
                        displayValue = NLNumberToString(ids);
					setInlineTextValue(document.getElementById(fldnam+"_val"), displayValue);
                }

                if (fld.type != "hidden" && nlapiGetField(fldnam).getType() == "radio")
					fld = getSelectedRadio( fld );

                if (fld.type == 'textarea' && fld.spellchecker)
                    fld.spellchecker.initContent();

                nsapiFireOnChange(fld,firefieldchanged);
			}
            finally
            {
                setSlavingAsync(true)
            }
        }
		else if (document.getElementById(fldnam+"_val") != null)	// handle DISPLAYONLY|COMPUTED or inlinehtml fields */
        {
            fld = document.getElementById(fldnam+"_val");
            if (isNumericField(fld) || isCurrencyField(fld))
                value = NLNumberToString(value);
			setInlineTextValue( fld, value );
        }
    }
}
function nlapiSetSelectValue(fldnam, value, label, firefieldchanged, synchronous)
{
    nsapiAssertTrue(!isSubrecordField(null, fldnam),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
    var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms['main_form'];
    var fld = getFormElement( form, fldnam.toLowerCase() );
    if ( fld != null )
    {
        try
        {
            if (synchronous)
                setSlavingAsync(false)
            setFormValue(fld, value, label );
            nsapiFireOnChange(fld,firefieldchanged);
        }
        finally
        {
            setSlavingAsync(true)
        }
    }
}
function nlapiSetMatrixValue(type, name, column, value, firefieldchanged, synchronous)
{
    nsapiAssertTrue(!isSubrecordField(type, name),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
    nsapiCheckArgs( [type, name, column], ['type', 'name', 'column'], 'nlapiSetMatrixValue' );
    if ( hasEncodedMatrixField(type, name, column) )
    {
        var hdr = getFormValue( document.forms['main_form'].elements[type+"header"] )
        var fld = hdr != null ? getFormElement( nvl(document.forms[type+'_form'],document.forms['main_form']), hdr+column ) : null; // sublist could be hidden
        if (fld == null)    // send flag only available when sublist is not hidden
            fld = getFormElement( document.forms[type+'_form'], hdr+column+"_send" );
        if ( fld != null )
        {
            try
            {
                if (synchronous)
                    setSlavingAsync(false)
                setFormValue(fld, value );
                nsapiFireOnChange(fld,firefieldchanged);
            }
            finally
            {
                setSlavingAsync(true)
            }
        }
    }
}
function nlapiSetFieldValues(fldnam,values,firefieldchanged,synchronous)
{
    nsapiAssertTrue(!isSubrecordField(null, fldnam),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
	var fldObj = nlapiGetField(fldnam)
	if ( fldObj == null || fldObj.getType() != "multiselect" )
		return;

	nlapiSetFieldValue(fldnam, values != null ? values.join(String.fromCharCode(5)) : "", firefieldchanged, synchronous);
}
function nlapiSetFieldText(fldnam,txt,firefieldchanged,synchronous)
{
	var fldObj = nlapiGetField(fldnam)
	if ( fldObj == null || fldObj.getType().indexOf("select") == -1 )
		return;

	var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms['main_form'];
    var sel = getFormElement( form, fldnam.toLowerCase() );
    if ( isPopupSelect( sel ) ) /* add trailing backslash to query text to facilitate exact-match queries (EQUALS filter versus STARTSWITH) unless the % trailing wildcard is used */
    {
        var fld = getFormElement( form, fldnam.toLowerCase()+"_display" );
        var startsWithSearch = !isValEmpty( txt ) && txt.charAt( txt.length - 1 ) == '%';
        try
        {   /* strip out user-specified trailing slash or wildcard whenever applicable. */
            fld.value = startsWithSearch || (!isValEmpty( txt ) && txt.charAt( txt.length - 1 ) == '\\') ? txt.substring(0, txt.length - 1) : txt;
            NLPopupSelect_setExactMatchQuery( fld, !startsWithSearch );
            try
            {
                if (synchronous)
                    setSlavingAsync(false)
                nsapiFireOnChange(fld,firefieldchanged);
            }
            finally
            {
                setSlavingAsync(true)
            }
        }
        finally
        {
            NLPopupSelect_setExactMatchQuery( fld, false );
        }
    }
    else if ( fldObj.getType() == "multiselect" )
	{
		var ids = [];
		var texts = txt != null ? (""+txt).split(String.fromCharCode(5)) : []
		for ( var i = 0; i < texts.length; i++ )
			ids[i] = getSelectValueForText(sel,texts[i])
		nlapiSetFieldValues(fldnam,ids,firefieldchanged,synchronous);
	}
    else if ( fldObj.isHidden() )
	{
		if ( isValEmpty(txt) )
			nlapiSetFieldValue(fldnam,txt,firefieldchanged,synchronous);
		else
		{
			var selectmap = NLEntryForm_querySelectValue( fldnam, null, txt )
			nlapiSetFieldValue(fldnam,selectmap != null ? selectmap[txt] : '',firefieldchanged,synchronous);
		}
	}
    else
	{
		nlapiSetFieldValue(fldnam,getSelectValueForText(sel,txt),firefieldchanged,synchronous);
	}
}
function nlapiSetFieldTexts(fldnam,texts,firefieldchanged,synchronous)
{
	var fldObj = nlapiGetField(fldnam)
	if (fldObj == null || fldObj.getType() != "multiselect")
		return null;

	var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms['main_form'];
    var fld = getFormElement( form, fldnam.toLowerCase() );
	if ( !isMultiSelect(fld) && !isPopupMultiSelect(fld) )
		return;

	if ( texts == null || texts.length == 0 )
	{
		nlapiSetFieldValues(fldnam, [], firefieldchanged, synchronous);
	}
	else if ( isPopupMultiSelect( fld ) || isDisplayOnlySelect( fld ) )	/* add trailing backslash to query text to facilitate exact-match queries (EQUALS filter versus STARTSWITH) unless the % trailing wildcard is used */
    {
		try
		{
			if (synchronous)
				setSlavingAsync(false)
			var ids = '', labels = '';
			var selectmap = NLEntryForm_querySelectValue( fldnam, null, texts.join(String.fromCharCode(5)) )
			for ( var i in selectmap )
			{
				ids = selectmap[i] != null ? (ids != '' ? ids+String.fromCharCode(5) : '') + selectmap[ i ] : ids;
				labels = selectmap[i] != null ? (labels != '' ? labels+String.fromCharCode(5) : '') + i : labels;
			}
			setFormValue(fld, ids, labels);
			nsapiFireOnChange(fld,firefieldchanged);
		}
		finally
		{
			setSlavingAsync(true)
		}
	}
    else
	{
		var ids = [];
		for ( var i = 0; i < texts.length; i++ )
			ids[i] = getSelectValueForText(fld,texts[i])
		nlapiSetFieldValues(fldnam,ids,firefieldchanged,synchronous);
	}
}
function nlapiGetFieldValue(fldnam)
{
    nsapiAssertTrue(!isSubrecordField(null, fldnam),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
    var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms['main_form'];
    if (form == null)
        form = document.forms['qadd_form'];
	var stype = typeof(ftypes) != 'undefined' && ftypes[fldnam.toLowerCase()] != null ? ftypes[fldnam.toLowerCase()] : null;
	var fld = getFormElement( form, fldnam.toLowerCase() );
    if (fld == null)
        fld = getFormElement( form, fldnam.toLowerCase()+"_send" );
	var value;
	if (fld == null && document.getElementById(fldnam+"_val") != null)
    {
        fld = document.getElementById(fldnam+"_val");
		value = getInlineTextValue( fld );
        if (isNumericField(fld) || isCurrencyField(fld))
            value = NLStringToNumber(value);
    }
	else
		value = getFormValue(fld);
	return isValEmpty(value) && stype == "checkbox" ? 'F' : value;
}
function nlapiGetFieldValues(fldnam)
{
    nsapiAssertTrue(!isSubrecordField(null, fldnam),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
	var fldObj = nlapiGetField(fldnam)
	if (fldObj == null || fldObj.getType() != "multiselect")
		return null;
    if (fldObj.isHidden())
        return nlapiGetFieldValue(fldnam).split(String.fromCharCode(5))
    var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms['main_form'];
    var fld = getFormElement( form, fldnam.toLowerCase() );
    if (fld == null)
        fld = getFormElement( form, fldnam.toLowerCase()+"_send" );
	return isMultiSelect(fld) || isPopupMultiSelect(fld) ? getFormValue(fld, true) : null;
}
function nlapiGetFieldText(fldnam)
{
	var fldObj = nlapiGetField(fldnam)
	if ( fldObj == null || fldObj.getType().indexOf("select") == -1 )
		return null;
	if (document.getElementById(fldnam+"_displayval") != null)
        return getInlineTextValue(document.getElementById(fldnam+"_displayval"));
    var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms['main_form'];
    var fld = getFormElement( form, fldnam.toLowerCase() );
	if (fld != null)
	{
        if (fldObj.isHidden())
        {
            var val = nlapiGetFieldValue(fldnam);
            if (isValEmpty(val))
                return "";
            else
            {
                var labels = NLEntryForm_querySelectText( fldnam, null, null, val )
                return labels != null ? labels[val] : "";
            }
        }        
        if (fldObj.getType() == "multiselect")
			return getSelectText( fld, true ).join(String.fromCharCode(5))
        return getSelectText(fld);
	}
	return null;
}
function nlapiGetMatrixValue(type, name, column)
{
    nsapiAssertTrue(!isSubrecordField(type, name),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
    nsapiCheckArgs( [type, name, column], ['type', 'name', 'column'], 'nlapiGetMatrixValue' );
    if ( hasEncodedMatrixField(type, name, column) )
    {
        var header = getFormValue( document.forms['main_form'].elements[type+"header"] )
        if ( header != null )
            return getFormValue(getFormElement( nvl(document.forms[type+'_form'],document.forms['main_form']), header+column )); // sublist could be hidden
    }
    return null;
}
function nlapiGetFieldTexts(fldnam)
{
	var fldObj = nlapiGetField(fldnam)
	if (fldObj == null || fldObj.getType() != "multiselect")
		return null;
    if (fldObj.isHidden())
    {
        var val = nlapiGetFieldValue(fldnam);
        if (isValEmpty(val))
            return [];
        else
        {
            var labels = []
            var query = NLEntryForm_querySelectText(fldnam, null, null, val)
            for (var i in query)
                labels.push(query[i])
            return labels;
        }
    }
    else if (document.getElementById(fldnam+"_displayval") != null)
	{
		var x = getInlineTextValue(document.getElementById(fldnam+"_displayval"));
		return isValEmpty(x) ? [] : x.split('\n');
	}
	var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms['main_form'];
    var fld = getFormElement( form, fldnam.toLowerCase() );
    return isMultiSelect(fld) || isPopupMultiSelect(fld) ? getSelectText( fld, true ) : null;
}
function nlapiSetCurrentLineItemValues(type,fldnam,values,firefieldchanged,synchronous)
{
	nlapiSetCurrentLineItemValue(type, fldnam, values != null ? values.join(String.fromCharCode(5)) : "", firefieldchanged, synchronous);
}
function nlapiSetCurrentLineItemValue(type,fldnam,value,firefieldchanged,synchronous)
{
   nsapiAssertTrue(!isSubrecordField(type, fldnam),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
   if (hasEncodedField(type, fldnam))
   {
     	if ( getEncodedFieldType(type, fldnam).indexOf('currency') >= 0 )
       		value = !isValEmpty(value) && (""+value).indexOf('.') == -1 && !isNaN(parseFloat(value)) ? pad_decimal_places( (""+value), getEncodedFieldType(type, fldnam).indexOf('currency2') >= 0 ? 2 : get_precision() ) : value;
	    var linenum = isEditMachine(type) ? "" : emptyIfNull(nlapiGetCurrentLineItemIndex(type));
	  	var fld = getFormElement( document.forms[type.toLowerCase()+'_form'], fldnam.toLowerCase()+linenum );
        try
        {
            if (synchronous)
                setSlavingAsync(false);
			var text = null;
			if ( isPopupSelect( fld ) || isPopupMultiSelect( fld ) )
			{
				var selectmap = NLEntryForm_querySelectText( fldnam, type, linenum, value );
				for ( var i in selectmap )
				{
					text = (text != null ? text+String.fromCharCode(5) : '') + selectmap[ i ];
				}
			}
			setFormValue(fld, value, text );
            nsapiFireOnChange(fld,firefieldchanged);
        }
        finally
        {
            setSlavingAsync(true);
        }
   }
   else if (hasEncodedField(type, "options"))
   {
       if (optwin != null)
       {
           var fld = optwin.document.forms[0].elements[fldnam.toLowerCase()];
           setFormValue(fld,value);
           nsapiFireOnChange(fld,firefieldchanged);
       }
       else
       {
           var optionsfld = document.forms[type.toLowerCase()+'_form'].options;
           optionsfld.value = setnamevaluelistvalue(optionsfld.value,fldnam,value);
           syncnamevaluelist(optionsfld);
       }
   }
}
function nlapiSetCurrentLineItemSelectValue(type,fldnam,value,label,firefieldchanged,synchronous)
{
   nsapiAssertTrue(!isSubrecordField(type, fldnam),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
   if (hasEncodedField(type, fldnam))
   {
	    var linenum = isEditMachine(type) ? "" : emptyIfNull(nlapiGetCurrentLineItemIndex(type));
	  	var fld = getFormElement( document.forms[type.toLowerCase()+'_form'], fldnam.toLowerCase()+linenum );
        try
        {
            if (synchronous)
                setSlavingAsync(false);
			setFormValue(fld, value, label );
            nsapiFireOnChange(fld,firefieldchanged);
        }
        finally
        {
            setSlavingAsync(true);
        }
   }
}
function nlapiSetCurrentLineItemMatrixValue(type,fldnam,column,value,firefieldchanged,synchronous)
{
    nsapiAssertTrue(!isSubrecordField(type, fldnam),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
    nsapiCheckArgs( [type, fldnam, column], ['type', 'fldnam', 'column'], 'nlapiSetCurrentLineItemMatrixValue' );
    if (hasEncodedMatrixField(type, fldnam, column))
        nlapiSetCurrentLineItemValue( type, getMatrixFieldName(type, fldnam, column), value, firefieldchanged, synchronous )
}
function nlapiSetCurrentLineItemText(type,fldnam,txt,firefieldchanged,synchronous)
{
    var sel;
    if (hasEncodedField(type, fldnam))
        sel = getFormElement( document.forms[type.toLowerCase()+'_form'], fldnam.toLowerCase() );
    else if (optwin != null)
        sel = optwin.document.forms[0].elements[fldnam.toLowerCase()];
    else
        return;
    if ( isPopupSelect( sel ) )	/* add trailing backslash to query text to facilitate exact-match queries (EQUALS filter versus STARTSWITH) unless the % trailing wildcard is used */
    {
        var fld = sel.form.elements[fldnam.toLowerCase()+"_display"];
		var startsWithSearch = !isValEmpty( txt ) && txt.charAt( txt.length - 1 ) == '%';
        try
        {   /* strip out user-specified trailing slash or wildcard whenever applicable. */
            fld.value = startsWithSearch || (!isValEmpty( txt ) && txt.charAt( txt.length - 1 ) == '\\') ? txt.substring(0, txt.length - 1) : txt;
            NLPopupSelect_setExactMatchQuery( fld, !startsWithSearch );
            try
            {
                if (synchronous)
                    setSlavingAsync(false)
                nsapiFireOnChange(fld,firefieldchanged);
            }
            finally
            {
                setSlavingAsync(true)
            }
        }
        finally
        {
            NLPopupSelect_setExactMatchQuery( fld, false );
        }
    }
    else
        nlapiSetCurrentLineItemValue(type,fldnam,getSelectValueForText(sel,txt),firefieldchanged, synchronous);
}
function nlapiGetCurrentLineItemValue(type,fldnam)
{
    nsapiAssertTrue(!isSubrecordField(type, fldnam),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
	if (hasEncodedField(type, fldnam))
	{
		if ( isEditMachine(type) )
			return getFormValue(getFormElement( document.forms[type.toLowerCase()+'_form'], fldnam.toLowerCase() ));
		else
		{
			var linenum = nlapiGetCurrentLineItemIndex(type);
			if ( getEncodedFieldType(type, fldnam) == "radio" )
				return getRadioValue( getFormElement( document.forms[type.toLowerCase()+'_form'], fldnam.toLowerCase() ) ) == linenum ? 'T' : 'F';

			if (fldnam.indexOf('_display') > 0)
			{	// insert the line number into the display field name if it is a popup select or popup multiselect
				var hiddenFldName = fldnam.replace('_display','') +  linenum;
				var hiddenFld = getFormElement(document.forms[type.toLowerCase()+'_form'],hiddenFldName);
				if (isPopupSelect(hiddenFld) || isPopupMultiSelect(hiddenFld))
					fldnam = hiddenFldName.toLowerCase() + '_display';
				else
					fldnam = fldnam.toLowerCase()+linenum;
			}
			else
				fldnam = fldnam.toLowerCase()+linenum;

			return getFormValue(getFormElement( document.forms[type.toLowerCase()+'_form'], fldnam));
		}
	}
	else if (hasEncodedField(type, "options"))
    {
        if (optwin != null)
            return optwin.getFormValue(optwin.document.forms[0].elements[fldnam.toLowerCase()]);
        else
            return getnamevaluelistvalue(document.forms[type.toLowerCase()+'_form'].options.value,fldnam);
    }
    else
        return null;
}
function nlapiGetCurrentLineItemMatrixValue(type,fldnam, column)
{
    nsapiAssertTrue(!isSubrecordField(type, fldnam),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
    nsapiCheckArgs( [type, fldnam, column], ['type', 'fldnam', 'column'], 'nlapiGetCurrentLineItemMatrixValue' );
    if (hasEncodedMatrixField(type, fldnam, column))
        return nlapiGetCurrentLineItemValue( type, getMatrixFieldName(type, fldnam, column) )
    else
        return null;
}
function nlapiGetCurrentLineItemText(type,fldnam)
{
	if (hasEncodedField(type, fldnam))
    {
        var linenum = isEditMachine(type) ? '' : nlapiGetCurrentLineItemIndex(type);
		var fld = getFormElement( document.forms[type.toLowerCase()+'_form'], fldnam.toLowerCase()+linenum );
		return fld != null ? getSelectText( fld ) : null;
	}
    else if (hasEncodedField(type, "options"))
    {
        if (optwin != null)
            return optwin.getSelectText(optwin.document.forms[0].elements[fldnam.toLowerCase()]);
        else
            return getnamevaluelistdisplayvalue(document.forms[type.toLowerCase()+'_form'].options.value,fldnam);
    }
    else
        return null;
}
function nlapiFindLineItemValue(type, fldnam, val)
{
    nsapiAssertTrue(!isSubrecordField(type, fldnam),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
    nsapiCheckArgs( [type, fldnam], ['type', 'fldnam'], 'nlapiFindLineItemValue' );
	if (hasEncodedField(type, fldnam))
        return findEncodedValue(type, fldnam, val)
    return -1;
}
function nlapiFindLineItemMatrixValue(type, fldnam, val, column)
{
    nsapiAssertTrue(!isSubrecordField(type, fldnam),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
    nsapiCheckArgs( [type, fldnam, column], ['type', 'fldnam', 'column'], 'nlapiFindLineItemMatrixValue' );
    if (hasEncodedMatrixField(type, fldnam, column))
        fldnam = getMatrixFieldName(type, fldnam, column);
	if (hasEncodedField(type, fldnam))
        return findEncodedValue(type, fldnam, val)
    return -1;
}
function nlapiSourceField(fldnam, fieldspec)
{
    nsapiCheckArgs( [fldnam, fieldspec], ['fldnam', 'fieldspec'], 'nlapiSourceField' );
	var fieldspecArg = fieldspec === false ? false : typeof(fieldspec) == "string" ? "'"+fieldspec+"'" : (fieldspec === true ? true : '');
	if (eval('typeof(Sync'+fldnam+')') == "function")
    {
        var slavingOrig = getSlavingAsync();
        try
        {
            setSlavingAsync(false);
            eval("Sync"+fldnam+"("+fieldspecArg+")");
        }
        finally
        {
            setSlavingAsync(slavingOrig);
        }
    }
}
function nlapiSourceLineItemField(type, fldnam, fieldspec, linenum)
{
    var slavingOrig = getSlavingAsync();
    var linenumArg = isEditMachine( type ) ? "" : ", "+linenum
	var fieldspecArg = fieldspec === false ? false : typeof(fieldspec) == "string" ? "'"+fieldspec+"'" : true;
    try
    {    
        setSlavingAsync(false);
        if (eval('typeof(Sync'+fldnam+type+')') == "function")
            eval("Sync"+fldnam+type+"("+fieldspecArg+linenumArg+")");
        else if (eval('typeof(Sync'+fldnam+')') == "function")
            eval("Sync"+fldnam+"("+fieldspecArg+linenumArg+")");
    }
    finally
    {
        setSlavingAsync(slavingOrig);
    }
}
function nlapiFireOnChange(fldnam)
{
	var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms['main_form'];
	var fld = getFormElement( form, fldnam.toLowerCase() );
	if (fld == null)
		fld = getFormElement( form, fldnam.toLowerCase()+"_send" );
	if ( fld != null )
	{
		if (nlapiGetField(fldnam).getType() == "radio")
			fld = getSelectedRadio( fld );
		nsapiFireOnChange(fld, true);
	}
}
function nlapiFireLineItemOnChange(type, fldnam, linenum)
{
	var form = document.forms[type+'_form'];
	var fld = getFormElement( form, fldnam.toLowerCase() );
	if ( fld != null )
	{
		linenum = isEditMachine( type ) ? "" : linenum;
		if (nlapiGetLineItemField(type, fldnam, linenum).getType() == "radio")
			fld = getSelectedRadio( fld );
		nsapiFireOnChange(fld, true);
	}
}
function nlapiSetLineItemValue(type,fldnam,linenum,value)
{
    nsapiAssertTrue(!isSubrecordField(type, fldnam),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
    if ( linenum == null || linenum < 0 || linenum > nlapiGetLineItemCount( type ) )   // should throw SSS_INVALID_SUBLIST_OPERATION if not for backward compatibility
        return;

    if (nsapiIsInternal() || type != 'item' || /(description|(revrec).+|(custcol).+)/.test(fldnam.toLowerCase()))
    {
        if (hasEncodedField(type, fldnam))
        {
			setEncodedValue(type.toLowerCase(),linenum,fldnam.toLowerCase(),value);
			if ( isEditMachine(type) )
				nsUpdatedMachines[type.toLowerCase()] = 1;
			else if ( nsapiGetCurrentSegment(type) == nsapiGetSegmentForLine(type, linenum) )
				setFormValues( type, linenum, document.forms[type+'_form'], fldnam );
		}
        else if (hasEncodedField(type, "options"))
        {
            setEncodedValue(type.toLowerCase(),linenum,"options",setnamevaluelistvalue(getEncodedValue(type,linenum,"options"),fldnam,value));
            nsUpdatedMachines[type.toLowerCase()] = 1;
        }
    }
}
function nlapiSetLineItemMatrixValue(type,fldnam,linenum,column,value)
{
    nsapiAssertTrue(!isSubrecordField(type, fldnam),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
    if (hasEncodedMatrixField(type, fldnam, column))
        nlapiSetLineItemValue(type, getMatrixFieldName(type, fldnam, column), linenum, value)
}
function nlapiGetLineItemValue(type,fldnam,linenum)
{
    nsapiAssertTrue(!isSubrecordField(type, fldnam),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
    if (hasEncodedField(type, fldnam))
        return getEncodedValue(type.toLowerCase(),linenum,fldnam.toLowerCase());
    else if (hasEncodedField(type, "options"))
        return getnamevaluelistvalue(getEncodedValue(type.toLowerCase(),linenum,"options"),fldnam);
    return null;
}
function nlapiGetLineItemMatrixValue(type,fldnam,linenum,column)
{
    nsapiAssertTrue(!isSubrecordField(type, fldnam),  'SSS_INVALID_OPERATION_USING_SUBRECORD_FIELD');
    if (hasEncodedMatrixField(type, fldnam, column))
        return nlapiGetLineItemValue(type,getMatrixFieldName(type, fldnam, column),linenum);
    return null;
}
function nlapiGetLineItemText(type,fldnam,linenum)
{
    var sel = getFormElement( document.forms[type.toLowerCase()+'_form'], fldnam.toLowerCase() );
    if ( linenum != null && !isEditMachine(type) )
        sel = getFormElement( document.forms[type.toLowerCase()+'_form'], fldnam.toLowerCase()+linenum )
    if ( sel == null )
        return null;
    else if (!isNLDropDown(sel) && sel.type == 'hidden')
        return getEncodedValue(type.toLowerCase(),linenum,fldnam.toLowerCase()+"_display");
    else
        return getlisttext(sel,getEncodedValue(type.toLowerCase(),linenum,fldnam.toLowerCase()));
}
function nlapiGetCurrentLineItemIndex(type)
{
    return getFormValue( getFormElement( document.forms[type.toLowerCase()+"_form"], 'lineindex' ) );
}
function nlapiSetLineItemTotal(type,total)
{
    var displayTotal = NLNumberToString(total);
	if ( hasLineItemGroup(type) && document.getElementById(type+'_total') != null )
		document.getElementById(type+'_total').innerHTML = displayTotal;
    else
    {
        if (undefined==window.hiddenLineItemTotal)
        {
            window.hiddenLineItemTotal = {};
        }
        window.hiddenLineItemTotal[type+'_total'] = displayTotal;
    }
}
function nlapiGetLineItemTotal(type)
{
    var displayTotal = null;
	if ( hasLineItemGroup(type) && document.getElementById(type+'_total') != null )
		displayTotal = document.getElementById(type+'_total').innerHTML;

    if (undefined != window.hiddenLineItemTotal)
        displayTotal = hiddenLineItemTotal[type+'_total'];

    if (displayTotal.length != null)
        return NLStringToNumber(displayTotal);

    return null;
}

function nlapiGetField(fldnam)
{
    if (typeof(ftabs) == 'undefined' && typeof(ftypes) == 'undefined')
    {
        // Issue 176123 - Support basic field metadata for the quickadd case
        var fld = document.getElementById(fldnam + "_fs");
        var bSelect = (isSelect(fld) || isPopupSelect(fld));// || isMultiSelect(fld) || isPopupMultiSelect(fld));
        return new nlobjField(fldnam.toLowerCase(), bSelect ? 'select' : 'text');
    }
	var fldObj = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? new nlobjField(fldnam.toLowerCase(), ftypes[fldnam.toLowerCase()]) : null;
	if ( fldObj == null && document.forms['main_form'].elements[fldnam] != null )
		fldObj = new nlobjField(fldnam.toLowerCase(), ftypes[fldnam.toLowerCase()] != null ? ftypes[fldnam.toLowerCase()] : 'text')
	if ( fldObj != null )
	{
		var fld = getFormElement( document.forms[(ftabs[fldnam.toLowerCase()] != null ? ftabs[fldnam.toLowerCase()]+'_form' : 'main_form')], fldnam.toLowerCase() );
		if ( fld != null )
		{
            fldObj.uifield = fld
            fldObj.noslaving = fld.noslaving;
			fldObj.disabled = getFieldDisabled(fld)
			fldObj.required = getRequired(fld)
			fldObj.readonly = isDisplayOnlyField(fld)
			fldObj.hidden = fld.type == 'hidden' && !(isSelect(fld) || isPopupSelect(fld) || isMultiSelect(fld) || isPopupMultiSelect(fld) || isRichTextEditor(fld)
                    || isFormattedNumericField(fld));
			fldObj.label = getLabel( fldnam+'_fs' );
			fldObj.popup = isPopupSelect( fld ) || isPopupMultiSelect( fld );
			var parent = fparents[fldnam.toLowerCase()];
			if (!isValEmpty(parent))
				fldObj.parent = parent.indexOf(".") != -1 ? nlapiGetLineItemField(parent.substring(0, parent.indexOf(".")), parent.substring(parent.indexOf(".")+1)) : nlapiGetField( parent );
		}
		else
			fldObj = null;
	}
	return fldObj;
}

function isFormattedNumericField(fld)
{
    return  (isNumericField(fld) || isCurrencyField(fld)) && getNLNumericOrCurrencyDisplayField(fld) != null;
}

function nlapiGetSubList(type)
{
    if ( hasLineItemGroup(type) )
    {
        var sublistObj = new nlobjSubList(type);
        return sublistObj;
    }
    return null;
}
function nlapiGetMatrixField(type, fldnam, column)
{
    if (hasEncodedMatrixField(type, fldnam, column))
    {
        var hdr = getFormValue( document.forms['main_form'].elements[type+"header"] )
        var fld = hdr != null ? getFormElement( nvl(document.forms[type+'_form'],document.forms['main_form']), hdr+column ) : null; // sublist could be hidden
        if ( fld == null )
            return;

        var headername = hdr+column;
        var fldObj = typeof(ftabs) != 'undefined' && ftabs[headername] != null ? new nlobjField(headername, ftypes[headername]) : null;
        if ( fldObj != null )
        {
            var fld = getFormElement( document.forms[type+'_form'], headername );
            if ( fld != null )
            {
                fldObj.uifield = fld
                fldObj.noslaving = fld.noslaving;
                fldObj.disabled = getFieldDisabled(fld)
                fldObj.required = getRequired(fld)
                fldObj.readonly = isDisplayOnlyField(fld)
                fldObj.hidden = fld.type == 'hidden' && !(isSelect(fld) || isPopupSelect(fld) || isMultiSelect(fld) || isPopupMultiSelect(fld) || isRichTextEditor(fld))
                fldObj.label = getLabel( headername+'_fs' );
            }
            else
                fldObj = null;
        }
        return fldObj;
    }
    return null;
}
function nlapiGetLineItemField(type, fldnam, linenum)
{
	var fldObj = hasEncodedField(type, fldnam) ? new nlobjField(fldnam.toLowerCase(), getEncodedFieldType(type, fldnam), type) : null;
	if ( fldObj != null )
	{
		var fld = getFormElement( document.forms[type+'_form'], fldnam.toLowerCase()+(linenum != null && !isEditMachine(type) ? linenum : "") );
		if ( fld != null )
		{
            if (linenum != null)
                fldObj.linenum = linenum;            
            fldObj.uifield = fld
            fldObj.noslaving = fld.noslaving;
			fldObj.disabled = getFieldDisabled(fld)
			fldObj.required = getRequired(fld)
			fldObj.readonly = false;
			fldObj.hidden = fld.type == 'hidden' && !(isSelect(fld) || isPopupSelect(fld) || isMultiSelect(fld) || isPopupMultiSelect(fld))
			fldObj.label = getEncodedFieldLabel(type, fldnam);
			fldObj.popup = isPopupSelect( fld ) || isPopupMultiSelect( fld );
			var parent = getEncodedFieldParent(type, fldnam);
			if (!isValEmpty(parent))
				fldObj.parent = parent.indexOf(".") != -1 ? nlapiGetLineItemField(type, parent.substring(parent.indexOf(".")+1), linenum) : nlapiGetField( parent );
		}
		else
			fldObj = null
	}
	return fldObj;
}
function nlapiGetLineItemMatrixField(type, fldnam, column, linenum)
{
    if (hasEncodedMatrixField(type, fldnam, column))
        return nlapiGetLineItemField(type, getMatrixFieldName(type, fldnam, column), linenum != null ? linenum : nlapiGetCurrentLineItemIndex(type))
    return null;
}
function nlapiSetFieldMandatory(fldnam, required)
{
	var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms['main_form'];
	if ( nsapiIsInternal() || /cust(entity|item|body|column|record|itemnumber|page|event).+/.test(fldnam) )
		setRequired(getFormElement( form, fldnam.toLowerCase() ), required);
}
function nlapiGetFieldMandatory(fldnam)
{
	var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms['main_form'];
	return getRequired(getFormElement( form, fldnam.toLowerCase() ));
}
function nlapiSetLineItemMandatory(type, fldnam, required, linenum)
{
	var form = document.forms[type+'_form'];
	if ( nsapiIsInternal() || /cust(entity|item|body|column|record|itemnumber|page|event).+/.test(fldnam) )
	{
		var fld = getFormElement(form,fldnam.toLowerCase());
		if (fld == null)
			fld = getFormElement(form, fldnam.toLowerCase()+linenum);
        if (isEditMachine(type))
            eval( String(type) + '_machine').setElementRequired(fldnam, required)
        else
            setRequired(fld, required);
    }
}
function nlapiGetLineItemMandatory(type, fldnam, linenum)
{
	var form = document.forms[type+'_form'];
	var fld = getFormElement(form,fldnam.toLowerCase());
	if (fld == null)
		fld = getFormElement(form, fldnam.toLowerCase()+linenum);
	return getRequired(fld);
}
function nlapiSetFieldDisabled(fldnam,val)
{
	var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms['main_form'];
	disableField(getFormElement( form, fldnam.toLowerCase() ),val);
    if ( typeof(ftabs) == 'undefined' || ftabs[fldnam.toLowerCase()] == null || ftabs[fldnam.toLowerCase()] == "main" )
		nsDisabledFields[fldnam] = val;
}
function nlapiGetFieldDisabled(fldnam)
{
	var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms['main_form'];
	return getFieldDisabled( getFormElement( form, fldnam.toLowerCase() ) );
}
function nlapiSetLineItemDisabled(type,fldnam,val, linenum)
{
	var fld = getFormElement( document.forms[type.toLowerCase()+'_form'], fldnam.toLowerCase() );
	if( fld == null )
		fld = getFormElement( document.forms[type.toLowerCase()+'_form'], fldnam.toLowerCase()+linenum )
	disableField( fld,val);
}
function nlapiGetLineItemDisabled(type,fldnam, linenum)
{
	var fld = getFormElement( document.forms[type.toLowerCase()+'_form'], fldnam.toLowerCase() );
	if( fld == null )
		fld = getFormElement( document.forms[type.toLowerCase()+'_form'], fldnam.toLowerCase()+linenum )
	return getFieldDisabled( fld );
}
function nlapiDisableField(fldnam,val)
{
	nlapiSetFieldDisabled(fldnam, val)
}
function nlapiDisableLineItemField(type,fldnam,val)
{
	nlapiSetLineItemDisabled(type, fldnam, val)
}
function nlapiSetFieldLabel(fldnam, label)
{
    nsapiCheckArgs( [fldnam], ['fldnam'], 'nlapiSetFieldLabel' );
    setLabel( fldnam + "_fs", label )
}
function nlapiSetFieldVisibility(fldnam, show)
{
    nsapiCheckArgs( [fldnam, show], ['fldnam', 'show'], 'nlapiSetFieldVisibility' );
    setFieldAndLabelVisibility( fldnam + "_fs", show )
}
function nlapiSetFieldDisplay(fldnam, show)
{
    nsapiCheckArgs( [fldnam, show], ['fldnam', 'show'], 'nlapiSetFieldDisplay' );
    showFieldAndLabel( fldnam + "_fs", show )
}
function nlapiSetFieldReadOnly(fldnam,val)
{
	var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms['main_form'];
    var fld = getFormElement( form, fldnam.toLowerCase() );
    if (fld != null && fld.type == "textarea")
        fld.readOnly = val;
}
function nlapiGetFieldReadOnly(fldnam)
{
	var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms['main_form'];
    var fld = getFormElement( form, fldnam.toLowerCase() );
    return fld != null && fld.type == "textarea" ? fld.readOnly : false;
}
function nlapiSetLineItemDisplay(type, show)
{
    nsapiCheckArgs( [type, show], ['type', 'show'], 'nlapiSetLineItemDisplay' );
    hideMachine(type, !show)
}
function nlapiSetLineItemLabel(type, fldnam, label)
{
    nsapiCheckArgs( [type, fldnam], ['type', 'fldnam'], 'nlapiSetLineItemLabel' );
    if ( isEditMachine(type) )
    {
        var mch = eval( String(type) + '_machine');
        mch.setFormElementLabel( fldnam, label );
    }
}
function nlapiGetFieldLabel(fldnam)
{
    nsapiCheckArgs( [fldnam], ['fldnam'], 'nlapiGetFieldLabel' );
    return getLabel( fldnam+"_fs" )
}
function nlapiGetLineItemCount(type)
{
    return hasLineItemGroup(type) ? getFormValue( getFormElement( document.forms['main_form'], 'next'+type.toLowerCase()+'idx' ) ) - 1 : -1;
}
function nlapiGetMatrixCount(type, fldnam)
{
    return hasEncodedMatrixField(type, fldnam, 1) ? getFormValue( getFormElement( document.forms['main_form'], type.toLowerCase()+'headercount' ) ) : -1;
}
function nlapiGetRecordType()
{
    return getFormValue( getFormElement( document.forms['main_form'], 'baserecordtype' ) );
}
function nlapiGetRecordId()
{
    return getFormValue( getFormElement( document.forms['main_form'], 'id' ) );
}
/*--------------- Miscellaneous Utility Functions ------------*/
function nlapiFormatCurrency(str)
{
    return format_currency(str);
}
function nlapiStringToDate(str, formattype)
{
    if ( isValEmpty(str) )
        return null;
    var d = stringtodate( str, window.dateformat, true /* returnNullIfInvalid */, formattype);
    if ( d == null )
        d = stringtotime( null, str )
    return d;
}
function nlapiDateToString(d, formattype)
{
	if ( formattype == 'timeofday' )
		return gettimestring(d);
	else if ( formattype == 'datetime')
        return getdatetimestring(d);
    else if ( formattype == 'datetimetz') 
		return getdatetimetzstring(d);
	else
		return getdatestring(d);
}
function nlapiAddDays(d, days)
{
    return adddays(new Date(d.getTime()), parseInt(days));
}
function nlapiAddMonths(d, months)
{
    return addmonths(new Date(d.getTime()), parseInt(months));
}
function nlapiEncrypt(s, type, key)
{
	nsapiCheckArgs( [s], ['cleartext'], 'nlapiEncrypt' );
    if (type == null)
        type = "sha1";
	return nsServerCall(nsJSONProxyURL, "encrypt", [s, type, key != null ? key : null]);
}
function nlapiDecrypt(s, type, key)
{
	nsapiCheckArgs( [s], ['encryptedtext'], 'nlapiDecrypt' );
	if ( type == "aes" || type == "base64" || type == "xor" )
		return nsServerCall(nsJSONProxyURL, "decrypt", [s, type, key != null ? key : null]);
	return null;
}
function nlapiExchangeRate(fromCurrency, toCurrency, effectiveDate)
{
	nsapiCheckArgs( [fromCurrency, toCurrency], ['fromCurrency', 'toCurrency'], 'nlapiExchangeRate' );
    nsapiCheckUsage( );

    var rate = nsServerCall(nsJSONProxyURL, "exchangeRate", [fromCurrency, toCurrency, effectiveDate != null ? effectiveDate : nlapiDateToString(new Date())]);
    nsapiLogUsage("nlapiExchangeRate")
    return rate;
}
function nlapiEscapeXML(text)
{
    if ( text == null )
        return null;
    text = ""+text;
    return text.replace( /&/gi, '&amp;' ).replace( /</gi,'&lt;' ).replace( />/gi,'&gt;' ).replace( /'/, '&apos;' ).replace( /"/,'&quot;' );
}

function nlapiNanoTime()
{
    throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); 
}

/*--------------- Custom form portlet functions ------------*/
function nlapiRefreshPortlet()
{
    if (typeof window.nlportlet == 'object' && window.nlportlet.type == 'form')
        window.nlportlet.refreshfn();
    else
        nlapiCreateError('SSS_INVALID_RECORD_TYPE');
}

function nlapiResizePortlet()
{
    if (typeof window.nlportlet == 'object' && window.nlportlet.type == 'form')
        nsResizeIframeToContent(window.nlportlet.id);
    else
        nlapiCreateError('SSS_INVALID_RECORD_TYPE');
}
/*--------------- Miscellaneous machine UI functions ------------*/
function nlapiRefreshLineItems(type)
{
    if (isEditMachine(type))
    {
        var isInternal = nsapiIsInternal();
        var slavingOrig = getSlavingAsync();
        try
        {
            setSlavingAsync(false);
            nsapiSetIsInternal(true);
            nsapiCallScript( "refreshLineItem", "internal", type+'_machine.setMachineIndex( '+(getLineCount(type)+1)+' ); '+type+'_machine.buildtable()' );
        }
        finally
        {
            setSlavingAsync(slavingOrig);
            nsapiSetIsInternal(isInternal);
        }
    }
    else if (!hasLineItemGroup(type))	/* true for readonly sublists */
		nsapiCallScript( "refreshLineItem", "internal", 'refreshmachine("'+ type+'" )' );
}
function nlapiSelectLineItem(type, linenum, allowsegmentchange)
{
    var isInternal = nsapiIsInternal();
    var slavingOrig = getSlavingAsync();
	try
	{
		setSlavingAsync(false);
        nsapiSetIsInternal(true);
		if (allowsegmentchange == true)
			nsapiSelectSegmentForLine(type, linenum);
		if (hasMachine(type))
			nsapiCallScript( "selectLineItem", "internal", type+'_machine.viewline('+linenum+')' );
		else if (hasLineItemGroup(type))
			nsapiCallScript( "selectLineItem", "internal", 'setFormValue( document.forms["'+ type+'_form"].elements["lineindex"], '+linenum+' )' );
	}
	finally
	{
		setSlavingAsync(slavingOrig);
        nsapiSetIsInternal(isInternal);
    }
}
function nlapiCommitLineItem(type)
{
    var isInternal = nsapiIsInternal();
    var slavingOrig = getSlavingAsync();
    try
    {
        setSlavingAsync(false);
        nsapiSetIsInternal(true);
		if (isEditMachine(type))
			nsapiCallScript( "commitLineItem", "internal", type+'_machine.addline()' );
		else if ( hasLineItemGroup(type) )
			nsapiCallScript( "commitLineItem", "internal", 'setEncodedValues( "'+ type+'", nlapiGetCurrentLineItemIndex("'+ type+'") )' );
    }
    finally
    {
        setSlavingAsync(slavingOrig);
        nsapiSetIsInternal(isInternal);
    }
}
function nlapiInsertLineItem(type, line)
{
    if (line != undefined)
    {
        nlapiSelectLineItem(type, line);
    }
    var isInternal = nsapiIsInternal();
    var slavingOrig = getSlavingAsync();
    try
    {
        setSlavingAsync(false);
        nsapiSetIsInternal(true);
		if (isEditMachine(type))
			nsapiCallScript( "insertLineItem", "internal", type+'_machine.insertline()' );
    }
    finally
    {
        setSlavingAsync(slavingOrig);
        nsapiSetIsInternal(isInternal);
    }
}
function nlapiRemoveLineItem(type, line)
{
    if (line != undefined)
    {
        nlapiSelectLineItem(type, line);
    }
    var isInternal = nsapiIsInternal();
    var slavingOrig = getSlavingAsync();
    try
    {
        setSlavingAsync(false);
        nsapiSetIsInternal(true);
		if (isEditMachine(type))
			nsapiCallScript( "deleteLineItem", "internal", type+'_machine.deleteline()' );
    }
    finally
    {
        setSlavingAsync(slavingOrig);
        nsapiSetIsInternal(isInternal);
    }
}
function nlapiCancelLineItem(type)
{
    var isInternal = nsapiIsInternal();
    var slavingOrig = getSlavingAsync();
    try
    {
        setSlavingAsync(false);
        nsapiSetIsInternal(true);
		if (isEditMachine(type))
			nsapiCallScript( "cancelLineItem", "internal", type+'_machine.clearline()' );
    }
    finally
    {
        setSlavingAsync(slavingOrig);
        nsapiSetIsInternal(isInternal);
    }
}
function nlapiSelectNewLineItem(type)
{
    var isInternal = nsapiIsInternal();
    var slavingOrig = getSlavingAsync();
    try
    {
        setSlavingAsync(false);
        nsapiSetIsInternal(true);
		if (isEditMachine(type))
			nsapiCallScript( "selectNewLineItem", "internal", type+'_machine.clearline()' );
    }
    finally
    {
        setSlavingAsync(slavingOrig);
        nsapiSetIsInternal(isInternal);
    }
}
function nlapiIsLineItemChanged(type)
{
	return isMachineChanged(type);
}
/*--------------- Miscellaneous dropdown UI functions (only valid on UI Builder fields) ------------*/
function nlapiInsertOption(fldnam, value, text, selected) { nlapiInsertSelectOption(fldnam, value, text, selected) }
function nlapiInsertSelectOption(fldnam, value, text, selected)
{
    nsapiAssertTrue( fldnam != null && fldnam.indexOf('custpage') == 0, 'SSS_INVALID_OPERATION' );
    var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms[0];
    var fld = getFormElement( form, fldnam.toLowerCase() );
    if (fld != null)
        addSelectOption( document, fld, text, value, selected )
}
function nlapiInsertLineItemOption(type, fldnam, value, text, selected)
{
    nsapiAssertTrue( type != null && fldnam != null && fldnam.indexOf('custpage') == 0, 'SSS_INVALID_OPERATION' );
    var form = document.forms[type+'_form'];
    var fld = getFormElement( form, fldnam.toLowerCase() );
    if (fld != null)
        addSelectOption( document, fld, text, value, selected )
}
function nlapiRemoveOption(fldnam, value, text) { nlapiRemoveSelectOption(fldnam, value, text) }
function nlapiRemoveSelectOption(fldnam, value)
{
    nsapiAssertTrue( fldnam != null && fldnam.indexOf('custpage') == 0, 'SSS_INVALID_OPERATION' );
    var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms[0];
    var fld = getFormElement( form, fldnam.toLowerCase() );
    if (fld != null)
        eval( value != null ? 'deleteOneSelectOption( fld, value )' : 'deleteAllSelectOptions( fld, window )' )
}
function nlapiRemoveLineItemOption(type, fldnam, value)
{
    nsapiAssertTrue( type != null && fldnam != null && fldnam.indexOf('custpage') == 0, 'SSS_INVALID_OPERATION' );
    var form = document.forms[type+'_form'];
    var fld = getFormElement( form, fldnam.toLowerCase() );
    if (fld != null)
        eval( value != null ? 'deleteOneSelectOption( fld, value )' : 'deleteAllSelectOptions( fld, window )' )
}
/*--------------- Helper Functions for obtaining current user information ------------*/
function nlapiGetUser()
{
    return nlapiGetFieldValue('nluser');
}
function nlapiGetRole()
{
    return nlapiGetFieldValue('nlrole');
}
function nlapiGetDepartment()
{
    return nlapiGetFieldValue('nldept');
}
function nlapiGetLocation()
{
    return nlapiGetFieldValue('nlloc');
}
function nlapiGetSubsidiary()
{
    return nlapiGetFieldValue('nlsub');
}

/*---------------------------------------- Custom Code API Extensions -------------------------------------*/

/*--------------- instantiate an existing nlobjRecord from the server ------------*/
function nlapiLoadRecord(type, id, initializeDefaults)
{
	nsapiCheckArgs( [type, id], ['type', 'id'], 'nlapiLoadRecord' );
	nsapiCheckType( type, 'nlapiLoadRecord', true );
    nsapiCheckUsage( );
    if (initializeDefaults != null)
        for (var field in initializeDefaults)
            nsapiAssertTrue(arrayContains(nsapiGetRecord( type ).initializedefaults, field), 'SSS_INVALID_INITIALIZE_DEFAULT_VALUE' );
    try
    {
        var nsPayload = nsStringToXML("<nlapiRequest type='nlapiLoadRecord'></nlapiRequest>");
        var nlapiRequest = nsPayload.documentElement;
        nlapiRequest.setAttribute('id', id);
        nlapiRequest.setAttribute('recordType', type);
        if (initializeDefaults != null)
        {
            var nsLoadParams = nsSetChildValue( nlapiRequest, "loadParams" );
            for (var defaultValue in initializeDefaults)
                nsSetChildValue(nsLoadParams, nsapiModifyLoadArg(defaultValue), initializeDefaults[defaultValue])
        }

        var payload = nsXmlToString( nsPayload );
        var request = new NLXMLHttpRequest();
        var response = request.requestURL( nsProxyURL, payload )

		var nsResponse = nsStringToXML( response.getBody() );
		var nsResponseRecord = nsSelectNode( nsResponse, "/nlapiResponse/record" );
		var nsRecord = nsapiExtractRecord( nsResponseRecord );
        nsRecord.logOperation("loadRecord", {"id" : id, "initializeDefaults" : initializeDefaults})
        nsapiAssertTrue( type.toLowerCase() == nsRecord.getRecordType().toLowerCase() ||
						(type.toLowerCase() == 'assemblyitem' && /.*assemblyitem/.test(nsRecord.getRecordType().toLowerCase())) ||
						(type.toLowerCase() == 'inventoryitem' && /.*inventoryitem/.test(nsRecord.getRecordType().toLowerCase())) ||
                       	(type.toLowerCase() == 'customer' && /(prospect|lead|customer)/.test(nsRecord.getRecordType().toLowerCase())), 'SSS_RECORD_TYPE_MISMATCH' );
		nsapiLogUsage( 'nlapiLoadRecord', type )
        return nsRecord;
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----------------- instantiate an nlobjRecord with default values filled in -----*/
function nlapiCreateRecord(type, initializeDefaults)
{
    nsapiCheckArgs( [type], ['type'], 'nlapiCreateRecord' );
    nsapiCheckType( type, 'nlapiCreateRecord', true );
	nsapiCheckUsage( );
	if (initializeDefaults != null)
		for (var field in initializeDefaults)
			nsapiAssertTrue(arrayContains(nsapiGetRecord( type ).initializedefaults, field), 'SSS_INVALID_INITIALIZE_DEFAULT_VALUE' );
    try
    {
        var nsPayload = nsStringToXML("<nlapiRequest type='nlapiCreateRecord'></nlapiRequest>");
        var nlapiRequest = nsPayload.documentElement;
        nlapiRequest.setAttribute('recordType', type);
        if (initializeDefaults != null)
        {
            var nsLoadParams = nsSetChildValue( nlapiRequest, "loadParams" );
            for (var defaultValue in initializeDefaults)
                nsSetChildValue(nsLoadParams, nsapiModifyLoadArg(defaultValue), initializeDefaults[defaultValue])
        }

        var payload = nsXmlToString( nsPayload );
        var request = new NLXMLHttpRequest();
        var response = request.requestURL( nsProxyURL, payload )

		var nsResponse = nsStringToXML( response.getBody() );
		var nsResponseRecord = nsSelectNode( nsResponse, "/nlapiResponse/record" );
		var nsRecord = nsapiExtractRecord( nsResponseRecord );
        nsRecord.logOperation("createRecord", {"initializeDefaults" : initializeDefaults})
        nsapiAssertTrue( type.toLowerCase() == nsRecord.getRecordType().toLowerCase(), 'SSS_RECORD_TYPE_MISMATCH' );
		nsapiLogUsage( 'nlapiCreateRecord', type )
        return nsRecord;
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/*--------------- clone and return an existing nlobjRecord from the server. ------------*/
function nlapiCopyRecord(type, id, initializeDefaults)
{
	nsapiCheckArgs( [type, id], ['type', 'id'], 'nlapiCopyRecord' );
	nsapiCheckType( type, 'nlapiCopyRecord', true );
	nsapiCheckUsage( );
    if (initializeDefaults != null)
        for (var field in initializeDefaults)
            nsapiAssertTrue(arrayContains(nsapiGetRecord(type).initializedefaults, field), 'SSS_INVALID_INITIALIZE_DEFAULT_VALUE' );
    try
    {
        var nsPayload = nsStringToXML("<nlapiRequest type='nlapiCopyRecord'></nlapiRequest>");
        var nlapiRequest = nsPayload.documentElement;
        nlapiRequest.setAttribute('id', id);
        nlapiRequest.setAttribute('recordType', type);
        if (initializeDefaults != null)
        {
            var nsLoadParams = nsSetChildValue( nlapiRequest, "loadParams" );
            for (var defaultValue in initializeDefaults)
                nsSetChildValue(nsLoadParams, nsapiModifyLoadArg(defaultValue), initializeDefaults[defaultValue])
        }

        var payload = nsXmlToString( nsPayload );
        var request = new NLXMLHttpRequest();
        var response = request.requestURL( nsProxyURL, payload )

		var nsResponse = nsStringToXML( response.getBody() );
		var nsResponseRecord = nsSelectNode( nsResponse, "/nlapiResponse/record" );
		var nsRecord = nsapiExtractRecord( nsResponseRecord );
        nsRecord.logOperation("copyRecord", {"id" : id, "initializeDefaults" : initializeDefaults})
        nsapiAssertTrue( type.toLowerCase() == nsRecord.getRecordType().toLowerCase() || (type.toLowerCase() == 'customer' && /(prospect|lead|customer)/.test(nsRecord.getRecordType().toLowerCase())), 'SSS_RECORD_TYPE_MISMATCH' );
		nsapiLogUsage( 'nlapiCopyRecord', type )
        return nsRecord;
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }                                                                 
}
/* ----- transform a record into another type (i.e. salesorder -> invoice -or- opportunity -> estimate) -----*/
function nlapiTransformRecord(type, id, transformType, transformValues)
{
	nsapiCheckArgs( [type, id, transformType], ['type', 'id', 'transformType'], 'nlapiTransformRecord' );
	nsapiCheckType( type, 'nlapiTransformRecord', true );
	nsapiCheckUsage( );

    nsapiAssertTrue(arrayContains(nsapiGetRecord( type ).transformtypes, transformType), 'SSS_INVALID_TRANSFORM_TYPE' );
    if (transformValues != null)
        for (var field in transformValues)
            nsapiAssertTrue(arrayContains(nsapiGetRecord( transformType ).transformdefaults, field), 'SSS_INVALID_TRANSFORM_DEFAULT_VALUE' );
    try
    {
        var nsPayload = nsStringToXML("<nlapiRequest type='nlapiTransformRecord'></nlapiRequest>");
        var nlapiRequest = nsPayload.documentElement;
        nlapiRequest.setAttribute('id', id);
        nlapiRequest.setAttribute('recordType', type);
        nlapiRequest.setAttribute('transformType', transformType);
        if (transformValues != null)
        {
            var nsLoadParams = nsSetChildValue( nlapiRequest, "loadParams" );
            for (var defaultValue in transformValues)
                nsSetChildValue(nsLoadParams, nsapiModifyLoadArg(defaultValue), transformValues[defaultValue])
        }

        var payload = nsXmlToString( nsPayload );
        var request = new NLXMLHttpRequest();
        var response = request.requestURL( nsProxyURL, payload )

		var nsResponse = nsStringToXML( response.getBody() );
		var nsResponseRecord = nsSelectNode( nsResponse, "/nlapiResponse/record" );
		var nsRecord = nsapiExtractRecord( nsResponseRecord );
        nsRecord.logOperation("transformRecord", {"type" : type, "id" : id, "transformType" : transformType, "transformDefaults" : transformValues})
        nsapiAssertTrue( transformType.toLowerCase() == nsRecord.getRecordType().toLowerCase(), 'SSS_RECORD_TYPE_MISMATCH' );
		nsapiLogUsage( 'nlapiTransformRecord', transformType )
        return nsRecord;
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----- commit changes to an nlobjRecord into the system -----*/
function nlapiSubmitRecord(record, options, ignoreMandatoryFields)
{
	nsapiCheckArgs( [record], ['record'], 'nlapiSubmitRecord' );
	nsapiCheckUsage( );

    if (!(record instanceof nlobjRecord))
		throw nlapiCreateError( 'SSS_INVALID_RECORD_OBJ', 'The record is not a valid object.' );
	try
    {
		var nsPayload = nsStringToXML("<nlapiRequest type='nlapiSubmitRecord'></nlapiRequest>");
		var nlapiRequest = nsPayload.documentElement;
		nlapiRequest.setAttribute('enableSourcing', ""+(options === true || (options != null && options.enableSourcing === true) ? true : false));
		nlapiRequest.setAttribute('disableTriggers', ""+(options != null && options.disableTriggers === true ? true : false));
        nlapiRequest.setAttribute('ignoreMandatoryFields', ""+(ignoreMandatoryFields === true || (options != null && options.ignoreMandatoryFields === true) ? true : false) );

        var nsRecord = nsapiSerializeRecord( record );
        nlapiRequest.appendChild( nsRecord.documentElement.cloneNode( true ) );

        var payload = nsXmlToString( nsPayload );
		var request = new NLXMLHttpRequest();
		var response = request.requestURL( nsProxyURL, payload )

		var nsResponse = nsStringToXML( response.getBody() );
		var sKey = nsSelectValue( nsResponse, "/nlapiResponse/id" );
		nsapiLogUsage( 'nlapiSubmitRecord', record.getRecordType() )
        return sKey;
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----- commit record field updates to the system -----*/
function nlapiSubmitField(type, id, fields, values, options)
{
    nsapiCheckArgs( [type, id, fields], ['type', 'id', 'fields'], 'nlapiSubmitField' );
    nsapiCheckType( type, 'nlapiSubmitField' );
	nsapiCheckUsage( );

    try
    {
        var nsPayload = nsStringToXML("<nlapiRequest type='nlapiSubmitField'></nlapiRequest>");
        var nlapiRequest = nsPayload.documentElement;
        nlapiRequest.setAttribute('recordType', type );
        nlapiRequest.setAttribute('id', id );
        nlapiRequest.setAttribute('enableSourcing', ""+(options === true || (options != null && options.enableSourcing === true) ? true : false));
        nlapiRequest.setAttribute('disableTriggers', ""+(options != null && options.disableTriggers === true ? true : false));
		/* add fields. */
        if (fields instanceof String || typeof(fields) == 'string')
        {
            var nsField = nsSetChildValue( nlapiRequest, "field" );
            nsSetChildValue( nsField, "name", fields );
            nsSetChildValue( nsField, "value", values );
        }
        else
        {
			for (var i = 0; fields != null && i < fields.length; i++)
            {
                var nsField = nsSetChildValue( nlapiRequest, "field" );
                nsSetChildValue( nsField, "name", fields[i] );
                nsSetChildValue( nsField, "value", values != null ? values[i] : null );
            }
        }

		var payload = nsXmlToString( nsPayload );
		var request = new NLXMLHttpRequest();
		var response = request.requestURL( nsProxyURL, payload );
		nsapiLogUsage( 'nlapiSubmitField', type )
	}
    catch( e )
    {
		throw nlapiCreateError( e );
	}
}

/* ----- delete an nlobjRecord -----*/
function nlapiDeleteRecord(type, id)
{
	nsapiCheckArgs( [type, id], ['type', 'id'], 'nlapiDeleteRecord' );
	nsapiCheckType( type, 'nlapiDeleteRecord', true );
	nsapiCheckUsage( );
    try
    {
		nsServerCall(nsJSONProxyURL, "deleteRecord", [type, id]);
		nsapiLogUsage( 'nlapiDeleteRecord', type )
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----- get search columns for a particular search type -----*/
function nlapiGetSearchColumns(type, filter, op)
{
	nsapiCheckArgs( [type], ['type'], 'nlapiGetSearchColumns' );
	nsapiCheckType( type, 'nlapiGetSearchColumns' );

	try
    {
        var rawResults = nsServerCall( nsJSONProxyURL, 'getSearchColumns', [type, filter, op]);
        var results = new Array();
        for ( var i = 0; rawResults != null && i < rawResults.length; i++ )
        {
            var columnObject = nsapiUnmarshalSearchColumn(rawResults[i]);
            results.push(columnObject);
        }
        return results.length == 0 ? null : results;
    }
    catch( e )
    {
		throw nlapiCreateError( e );
    }
}
function nsapiUnmarshalSearchColumn(columnMap)
{
    var col = new nlobjSearchColumn(columnMap.name);
    col.label = columnMap.label;
    col.type = columnMap.type;
    return col;
}
/* ----- perform a record search and return an Array of nlobjSearchResult objects -----*/
function nlapiSearchRecord(type, id, filters, columns)
{
    nsapiCheckArgs( [type], ['type'], 'nlapiSearchRecord' );
	nsapiCheckType( type, 'nlapiSearchRecord' );
	nsapiCheckUsage( );

	id = id != null && !isNaN(parseInt( id )) ? parseInt( id ) : id != null ? id : null;
    try
    {
		var rawFilters = nsapiMarshalSearchFilters(filters);
		var rawColumns = nsapiMarshalSearchColumns(columns);
		var rawResults = nsServerCall( nsJSONProxyURL, 'searchRecord', [type, id, rawFilters, rawColumns]);
		var rowResults = nsapiExtractSearchResults( rawResults, columns );

		nsapiLogUsage( 'nlapiSearchRecord', isValEmpty(id) && nsapiIsLookup(filters) ? type : null );
		return rowResults != null && rowResults.length > 0 ? rowResults : null;
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----- factory method: create a new ad-hoc search (client suite script implementation) -----*/
function nlapiCreateSearch(type, filters, columns)
{
    nsapiCheckArgs( [type], ['type'], 'nlapiCreateSearch' );
	nsapiCheckType( type, 'nlapiCreateSearch' );
	nsapiCheckUsage( );
    return new nlobjSearch(type, -1, filters, columns);
}
/* ----- factory method: load an existing saved search (client suite script implementation) -----*/
function nlapiLoadSearch(type, id)
{
    nsapiCheckArgs( [type], ['type'], 'nlapiLoadSearch' );
	nsapiCheckType( type, 'nlapiLoadSearch' );
	nsapiCheckUsage( );
    id = id != null && !isNaN(parseInt( id )) ? parseInt( id ) : id != null ? id : null;
    var search = new nlobjSearch(type, id, null, null);
    search._load();
    return search;
}
/* ----- private search code (client suite script implementation) -----*/
function nsapiMarshalSearchFilters(filters)
{
    filters = isArray(filters) ? filters : filters != null && filters instanceof nlobjSearchFilter ? [filters] : null;

		nsapiCheckArray(filters, 'filters', nlobjSearchFilter);

		var rawFilters = [];
		/* add filters. */
		for ( var i = 0; filters != null && i < filters.length; i++ )
		{
			var rawFilter = new Object();
			rawFilter.name = filters[i].getName();
			rawFilter.operator = filters[i].getOperator();
			rawFilter.values = filters[i].values.length == 0 ? null : filters[i].values;
			rawFilter.join = filters[i].getJoin();
			rawFilter.formula = filters[i].getFormula();
			rawFilter.summarytype = filters[i].getSummaryType();
        rawFilters.push(rawFilter);
		}
    return rawFilters;
}
function nsapiMarshalSearchColumns(columns)
{
    columns = nsapiColumnsAsArray(columns);

    nsapiCheckArray(columns, 'columns', nlobjSearchColumn);

    /* add columns. */
    var rawColumns = [];
    for ( var i = 0; columns != null && i < columns.length; i++ )
    {
        var rawColumn = new Object();
        rawColumn.userindex = i+1;
        columns[i].userindex = i+1;
        rawColumn.name = columns[i].getName();
        rawColumn.join = columns[i].getJoin();
        rawColumn.summary = columns[i].getSummary();
        rawColumn.label = columns[i].getLabel();
        rawColumn.formula = columns[i].getFormula();
        rawColumn.functionid = columns[i].getFunction();
        rawColumn.sortdir = columns[i].getSort();
        rawColumn.whenorderedby = columns[i].getWhenOrderedBy();
        rawColumn.whenorderedbyjoin = columns[i].getWhenOrderedByJoin();
        rawColumns.push(rawColumn);
    }
    return rawColumns;
}
function nsapiColumnsAsArray(columns)
{
    return isArray(columns) ? columns : columns != null && columns instanceof nlobjSearchColumn ? [columns] : null;
}
/* ----- helper function for fetching the value of a field (or joined field) on a record  -----*/
function nlapiLookupField(type, id, columns, text)
{
    nsapiCheckArgs( [type, id, columns], ['type', 'id', 'columns'], 'nlapiLookupField' );
	nsapiCheckType( type, 'nlapiLookupField' );

	var searchcolumns = new Array();
	if ( isArray(columns) )
	{
		for ( var i = 0; i < columns.length; i++ )
		{
			var column = columns[i];
			if ( column.toLowerCase() != 'recordtype' )
			{
				var name = column.indexOf( '.' ) != -1 ? column.substring( column.indexOf( '.' )+1 ) : column;
				var join = column.indexOf( '.' ) != -1 ? column.substring( 0, column.indexOf( '.' ) ) : null;
				searchcolumns[searchcolumns.length] = new nlobjSearchColumn(name, join);
			}
		}
	}
	else if ( columns.toLowerCase() != 'recordtype' )
	{
		var name = columns.indexOf( '.' ) != -1 ? columns.substring( columns.indexOf( '.' )+1 ) : columns;
		var join = columns.indexOf( '.' ) != -1 ? columns.substring( 0, columns.indexOf( '.' ) ) : null;
		searchcolumns[0] = new nlobjSearchColumn(name, join);
	}

	var result = nlapiSearchRecord(	type,
									null,
									new nlobjSearchFilter('internalid',null,'anyof',id),
									searchcolumns );
	var results = null;
	if ( result != null && result.length > 0 )
	{
		results = new Object();
		if ( isArray(columns) )
		{
			for ( var i = 0; i < columns.length; i++ )
			{
				var name = columns[i].indexOf( '.' ) != -1 ? columns[i].substring( columns[i].indexOf( '.' )+1 ) : columns[i];
				var join = columns[i].indexOf( '.' ) != -1 ? columns[i].substring( 0, columns[i].indexOf( '.' ) ) : null;
				results[columns[i]] = name.toLowerCase() == 'recordtype' ? result[0].getRecordType() : text ? result[0].getText( name, join ) : result[0].getValue( name, join );
			}
		}
		else
		{
			var name = columns.indexOf( '.' ) != -1 ? columns.substring( columns.indexOf( '.' )+1 ) : columns;
			var join = columns.indexOf( '.' ) != -1 ? columns.substring( 0, columns.indexOf( '.' ) ) : null;
			results = name.toLowerCase() == 'recordtype' ? result[0].getRecordType() : text ? result[0].getText( name, join ) : result[0].getValue( name, join );
		}
	}
	return results;
}
/* ----- perform a record search and return an Array of nlobjSearchResult objects -----*/
function nlapiSearchGlobal(keywords)
{
    nsapiCheckArgs( [keywords], ['keywords'], 'nlapiSearchGlobal' );
	nsapiCheckUsage( );
    try
    {
		var rawSearchResults = nsServerCall( nsJSONProxyURL, 'searchGlobal', [keywords]);
		var rowResults = nsapiExtractSearchResults( rawSearchResults );

		nsapiLogUsage( 'nlapiSearchGlobal' );
		return rowResults != null && rowResults.length > 0 ? rowResults : null;
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----- perform a duplicate record search and return an Array of nlobjSearchResult objects -----*/
function nlapiSearchDuplicate(type, fields, id)
{
    nsapiCheckArgs( [type, fields != null ? fields : id], ['type', fields != null ? 'fields' : 'id'], 'nlapiSearchDuplicate' );
	nsapiCheckUsage( );
    try
	{
		var obj = new Object();
		for ( var field in fields )
		{
			nsapiAssertTrue( fields[field] != null, 'SSS_INVALID_SRCH_FILTER', field );
			obj[ field ] = fields[ field ];
		}
		var rawSearchResults = nsServerCall( nsJSONProxyURL, 'searchDuplicate', [type, isNaN(parseInt(id)) ? -1 : parseInt(id), obj]);
		var rowResults = nsapiExtractSearchResults( rawSearchResults );

		nsapiLogUsage( 'nlapiSearchGlobal' );
		return rowResults != null && rowResults.length > 0 ? rowResults : null;
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----- fetch URL for a NetSuite resource: (TASKLINK, RECORD, SCRIPTLET) -----*/
function nlapiResolveURL(type, identifier, id, pagemode)
{
	nsapiCheckArgs( [type, identifier], ['type', 'identifier'], 'nlapiResolveURL' );
	try
    {
		if ( pagemode != null && typeof(pagemode) == "boolean" && /(suitelet|record)/.test(type.toLowerCase()) )
			pagemode = type.toLowerCase() == 'suitelet' ? (pagemode ? 'external' : 'internal') : (pagemode ? 'edit' : 'view')
		var sUrl = nsServerCall(nsJSONProxyURL, "resolveURL", [type, identifier, id, pagemode]);
		return sUrl;
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----- set the Redirect URL for a record. This overrides the default redirect (if one exists) -----*/
function nlapiSetRedirectURL(type, identifier, id, pagemode, params)
{
	nsapiCheckArgs( [type, identifier], ['type', 'identifier'], 'nlapiSetRedirectURL' );
	var url = nlapiResolveURL( type, identifier, id, pagemode );
    for ( var i in params )
        url = addParamToURL( url, i, params[ i ] );
    nsapiSetRedirectURL(url);
}
function nsapiSetRedirectURL(url)
{
    setFormValue( document.forms['main_form'].elements.customwhence, url );
}
/* ----- send and record an e-mail -----*/
function nlapiSendEmail(author, recipient, subject, body, cc, bcc, records)
{
	nsapiCheckArgs( [author, recipient, subject, body], ['author', 'recipient', 'subject', 'body'], 'nlapiSendEmail' );
	nsapiCheckUsage( );
    try
    {
		var nsPayload = nsStringToXML("<nlapiRequest type='nlapiSendEmail'></nlapiRequest>");
		var nlapiRequest = nsPayload.documentElement;
		nsSetChildValue( nlapiRequest, "author", author );
		nsSetChildValue( nlapiRequest, "recipient", recipient );
		nsSetChildValue( nlapiRequest, "subject", subject );
		nsSetChildValue( nlapiRequest, "body", body );

		cc = isArray( cc ) ? cc : cc != null ? [ ""+cc ] : null;
		bcc = isArray( bcc ) ? bcc : bcc != null ? [ ""+bcc ] : null;
		nsSetChildValues( nlapiRequest, "cc", cc );
        nsSetChildValues( nlapiRequest, "bcc", bcc );

        if ( records != null && records['transaction'] != null ) nsSetChildValue( nlapiRequest, "transaction", records['transaction'] );
        if ( records != null && records['entity'] != null ) nsSetChildValue( nlapiRequest, "entity", records['entity'] );
        if ( records != null && records['recordtype'] != null ) nsSetChildValue( nlapiRequest, "recordtype", records['recordtype'] );
        if ( records != null && records['record'] != null ) nsSetChildValue( nlapiRequest, "record", records['record'] );
        if ( records != null && records['activity'] != null ) nsSetChildValue( nlapiRequest, "activity", records['activity'] );

		new NLXMLHttpRequest().requestURL( nsProxyURL, nsXmlToString( nsPayload ) );
		nsapiLogUsage( 'nlapiSendEmail' )
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----- send and record an fax -----*/
function nlapiSendFax(author, recipient, subject, body, records)
{
	nsapiCheckArgs( [author, recipient, subject, body], ['author', 'recipient', 'subject', 'body'], 'nlapiSendFax' );
	nsapiCheckUsage( );
    try
    {
		var nsPayload = nsStringToXML("<nlapiRequest type='nlapiSendFax'></nlapiRequest>");
		var nlapiRequest = nsPayload.documentElement;
		nsSetChildValue( nlapiRequest, "author", author );
		nsSetChildValue( nlapiRequest, "recipient", recipient );
		nsSetChildValue( nlapiRequest, "subject", subject );
		nsSetChildValue( nlapiRequest, "body", body );

        if ( records != null && records['transaction'] != null ) nsSetChildValue( nlapiRequest, "transaction", records['transaction'] );
        if ( records != null && records['entity'] != null ) nsSetChildValue( nlapiRequest, "entity", records['entity'] );
        if ( records != null && records['recordtype'] != null ) nsSetChildValue( nlapiRequest, "recordtype", records['recordtype'] );
        if ( records != null && records['record'] != null ) nsSetChildValue( nlapiRequest, "record", records['record'] );
        if ( records != null && records['activity'] != null ) nsSetChildValue( nlapiRequest, "activity", records['activity'] );

		new NLXMLHttpRequest().requestURL( nsProxyURL, nsXmlToString( nsPayload ) );
		nsapiLogUsage( 'nlapiSendFax' )
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----- attach a single record to another -----*/
function nlapiAttachRecord(type, id, type2, id2, attrs)
{
	nsapiCheckArgs( [type, id, type2, id2], ['type', 'id', 'type2', 'id2'], 'nlapiAttachRecord' );
	nsapiCheckType( type, 'nlapiAttachRecord', type != 'file' );
	nsapiCheckType( type2, 'nlapiAttachRecord', true );
	nsapiCheckUsage( );
    try
    {
		nsServerCall(nsJSONProxyURL, "attachRecord", [type, id, type2, id2, nsapiExtractMap(attrs)]);
		nsapiLogUsage( 'nlapiAttachRecord' )
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----- detach a single record from another -----*/
function nlapiDetachRecord(type, id, type2, id2, attrs)
{
	nsapiCheckArgs( [type, id, type2, id2], ['type', 'id', 'type2', 'id2'], 'nlapiDetachRecord' );
	nsapiCheckType( type, 'nlapiDetachRecord', type != 'file' );
	nsapiCheckType( type2, 'nlapiDetachRecord', true );
	nsapiCheckUsage( );
    try
    {
		nsServerCall(nsJSONProxyURL, "detachRecord", [type, id, type2, id2, nsapiExtractMap(attrs)]);
		nsapiLogUsage( 'nlapiDetachRecord' )
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----- issue a GET or POST request for an Internal or External URL resource -----*/
function nlapiRequestURL(url, postdata, headers, callback, method)
{
    nsapiCheckArgs( [url], ['url'], 'nlapiRequestURL' );
    nsapiAssertTrue( url.indexOf( '/' ) == 0 || url.indexOf( 'http' ) == 0, 'SSS_INVALID_URL' );
    if (!isValEmpty(method))
        nsapiAssertTrue ( method == 'PUT' || method == 'POST' || method == 'GET' || method == 'DELETE' || method == 'HEAD','SSS_INVALID_HTTPMETHOD');
	nsapiCheckUsage( );
    try
    {
        var host = document.location.protocol+'//'+document.location.host;
        if (url.indexOf( '/' ) != 0 && url.indexOf( host ) != 0)  /* Proxy all non-local URLs */
        {
            var nsPayload = nsStringToXML( "<nlapiRequest type='nlapiRequestURL'></nlapiRequest>" );
            var nlapiRequest = nsPayload.documentElement;
            nsSetChildValue( nlapiRequest, "url", url );
            nsSetChildValue( nlapiRequest, "method", method );
			if (nsInstanceofDocument( postdata ))
                nsSetChildValue( nlapiRequest, "body", nsXmlToString( postdata ) );
            else if (postdata instanceof String || typeof postdata == "string")
                nsSetChildValue( nlapiRequest, "body", postdata );
			else
			{
				for (var i in postdata)
				{
					var param = nsSetChildValue( nlapiRequest, "param" );
					nsSetChildValue( param, "name", i );
					nsSetChildValue( param, "value", postdata[ i ] );
				}
			}
			for ( var i in headers )
            {
                nsapiAssertTrue( !isValEmpty( i ), 'SSS_INVALID_HEADER' );
                var header = nsSetChildValue( nlapiRequest, "header" );
                nsSetChildValue( header, "name", i );
                nsSetChildValue( header, "value", headers[ i ] );
            }
            url = nsProxyURL;
            postdata = nsXmlToString( nsPayload );
		}
		var request = new NLXMLHttpRequest();
        if (callback instanceof Function)
            request.setResponseHandler( function(response) { nsapiAjaxResponse( response, callback ) } );
        var nsResponse = request.requestURL( url, postdata, headers, callback instanceof Function, method )
        if (nsResponse != null)
            nsResponse = nsapiAjaxResponse( nsResponse );
		nsapiLogUsage( 'nlapiRequestURL' )
        return nsResponse;
    }
    catch( e )
    {
		throw nlapiCreateError( e );
    }
}
/* ----- log an AUDIT/DEBUG/ERROR/EMERGENCY execution -----*/
function nlapiLogExecution(type, title, details)
{
    nsapiCheckArgs( [type, title], ['type', 'title'], 'nlapiLogExecution' );
	try
    {
        var console = document.getElementById('consolewindow');
        if (console != null)
            buildLogConsole( type.toLowerCase(), title, details )
		else
		{
			var scriptid = nlapiGetContext().getScriptId();
			if (!isValEmpty(scriptid) && scriptid != "customform")
				nsServerCall(nsJSONProxyURL, "logExecution", [scriptid, nlapiGetRecordType(), type, title, details != null ? details : null]);
		}
	}
    catch( e )
    {
		throw nlapiCreateError( e );
    }
}
/* ----- convert String to XML Document -----*/
function nlapiStringToXML(text)
{
	nsapiCheckArgs( [text], ['text'], 'nlapiStringToXML' );
	try
    {
        var document = nsStringToXML(text);
        return document;
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----- convert XML Document to String -----*/
function nlapiXMLToString(xml)
{
	nsapiCheckArgs( [xml], ['xml'], 'nlapiXMLToString' );
	try
    {
        var text = nsXmlToString(xml);
        return text;
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----- perform Xpath query for a value in an XML Document -----*/
function nlapiSelectValue(node, xpath)
{
	nsapiCheckArgs( [node, xpath], ['node', 'xpath'], 'nlapiSelectValue' );
	try
    {
        var selection = nsSelectValue(node, xpath);
        return selection;
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----- perform Xpath query for an Array of values in an XML Document -----*/
function nlapiSelectValues(node, xpath)
{
	nsapiCheckArgs( [node, xpath], ['node', 'xpath'], 'nlapiSelectValues' );
	try
    {
        var selections = nsSelectValues(node, xpath);
        return selections;
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----- perform Xpath query for a Node in an XML Document -----*/
function nlapiSelectNode(node, xpath)
{
	nsapiCheckArgs( [node, xpath], ['node', 'xpath'], 'nlapiSelectNode' );
	try
    {
        var selection = nsSelectNode(node, xpath);
        return selection;
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/* ----- perform Xpath query for an Array of Nodes in an XML Document -----*/
function nlapiSelectNodes(node, xpath)
{
	nsapiCheckArgs( [node, xpath], ['node', 'xpath'], 'nlapiSelectNodes' );
	try
    {
        var selections = nsSelectNodes(node, xpath);
        return selections;
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
var nsContextObj = null;
/* ----- return an nlobjContext object containing meta-information about user context -----*/
function nlapiGetContext()
{
    try
    {
		if ( nsContextObj == null )
			nsContextObj = new nlobjContext( );
		return nsContextObj;
    }
    catch ( e )
    {
		throw nlapiCreateError( e );
    }
}
/**
 * @param url URL of request handler
 * @param methodName method name on remote object to call
 * @param methodParams an array of parameters to the method
 * @param asyncCallback a callback if this is to be an async request.  Callback signature should be: callback(result, error)
 * @param httpMethod the http method to use (POST or GET).  GET is the default.
 */
function nlapiServerCall(url, methodName, methodParams, asyncCallback, httpMethod)
{
	return nsServerCall(url, methodName, methodParams, asyncCallback, httpMethod);
}

function nlapiLocalCall(func, timeoutinmillis)
{
	nsapiAssertTrue(timeoutinmillis != null && !isNaN(parseInt(timeoutinmillis)), 'SSS_INVALID_ARGUMENT', 'timeoutinmillis: '+timeoutinmillis)
	var obj = new Object()
	obj.trigger = nsapiQueryScript("trigger")
	obj.scriptid = nsapiQueryScript("scriptid")
	if ( timeoutinmillis == -1 )
		return nsapiCallScript(obj.trigger, obj.scriptid, func)
	return setTimeout( function() { nsapiCallScript(obj.trigger, obj.scriptid, func); }, timeoutinmillis );
}

function nlapiChangeCall(params)
{
	setWindowChanged(window,false)
	window.onbeforeunload=null;
    var url = document.location.href;
    for ( var param in params )
    {
        url = addParamToURL(url, param, params[param], true);
    }
    document.location = url;
}

/* ----- Generates an nlobError object -----*/
function nlapiCreateError(code, detail, suppressNotification)
{
	window.errorObj = new nlobjError( code, detail, suppressNotification );
	return window.errorObj;
}

/*--------------- nlobjRecord definition ------------*/
function nlobjRecord( type, id )
{
	this.type = type;
	this.id = id != null ? id : null;
	this.fields = new Object();
    this.fieldnames = new Array();    
    this.lineitems = new Object();
    this.linetypes = new Object();
    this.linefields = new Object();
    this.matrixfields = new Object();
	this.currentlineitems = new Object();
	this.currentlineitemindexes = new Object();    
    this.initialized = false;
    this.operations = new Array();
}
nlobjRecord.prototype.getId = function( ) { return this.id; }
nlobjRecord.prototype.getRecordType = function( ) { return this.type; }
nlobjRecord.prototype.setFieldValue = function( name, value )
{
    this.fields[name] = value;
    this.logOperation("setFieldValue", {"field" : name, "value" : value})
}
nlobjRecord.prototype.setFieldValues = function( name, values )
{
    this.fields[name] = values;
    this.logOperation("setFieldValues", {"field" : name, "value" : values})
}
nlobjRecord.prototype.getFieldValue = function( name ) { return this.fields[name] != null ? this.fields[name] : null; }
nlobjRecord.prototype.getFieldValues = function( name ) { return this.fields[name] != null ? this.fields[name] : null; }
nlobjRecord.prototype.getAllFields = function( )
{
	var s = new Array();
	for ( var f in this.fields )
		s[s.length++] = f;
    for (var i = 0; i < this.fieldnames.length; i++)
        arrayAdd(s, this.fieldnames[i]);
    return s;
}
nlobjRecord.prototype.getAllLineItems = function( )
{
	var s = new Array();
	for ( var f in this.lineitems )
		s[s.length++] = f;
	return s;
}
nlobjRecord.prototype.getAllLineItemFields = function( name )
{
	var linegroup = this.linefields[ name ];
	if ( linegroup == null )
		return null;

	var s = new Array();
	for ( var i = 0; i < this.linefields[ name ].length; i++ )
		s[s.length++] = this.linefields[ name ][i];
	return s;
}
nlobjRecord.prototype.setLineItemValue = function( group, name, line, value )
{
    nsapiAssertTrue( line > 0 && line-1 <= this.getLineItemCount( group ), 'SSS_INVALID_SUBLIST_OPERATION' )
    /* Special case setting fields on the next line for edit machines and UI object list machines (backward compatiblity) */
    if ( line-1 == this.getLineItemCount( group ) )
        this.selectNewLineItem(group)
    else if ( line <= this.getLineItemCount(group) )
        this.selectLineItem(group, line)
    this.setCurrentLineItemValue(group, name, value)
    this.commitLineItem(group)
}
nlobjRecord.prototype.setAndCommitLineItemValue = function( group, name, line, value )
{
	var linegroup = this.lineitems[ group ];
	if ( linegroup == null )
	{
		linegroup = new Array();
		this.lineitems[ group ] = linegroup;
	}
	var lineitem = linegroup[ line ];
	if ( lineitem == null )
	{
		lineitem = new Array( 1 );
		linegroup[ line ] = lineitem;
	}
	lineitem[ name ] = value;
}
nlobjRecord.prototype.insertLineItem = function( type, line )
{
    nsapiAssertTrue( this.linetypes[type] == 'edit', 'SSS_INVALID_SUBLIST_OPERATION' )
    if (this.getCurrentLineItemIndex(type) == -1)
    {
        if (line-1 == this.getLineItemCount( type ) || isNaN(parseInt(line)))
            this.selectNewLineItem(type)
        else if (line <= this.getLineItemCount(type))
            this.selectLineItem(type, line)
    }
    var linegroup = this.lineitems[ type ];
	if (linegroup == null)
	{
		linegroup = new Array( 1 );
		this.lineitems[ type ] = linegroup;
	}
	linegroup.splice( line, 0, new Array() )
    this.logOperation("insertLineItem", {"type" : type})
}
nlobjRecord.prototype.removeLineItem = function( type, line )
{
    nsapiAssertTrue( this.linetypes[type] == 'edit', 'SSS_INVALID_SUBLIST_OPERATION' )
    if (this.getCurrentLineItemIndex(type) == -1)
    {
        if (line-1 == this.getLineItemCount(type) || isNaN(parseInt(line)))
            this.selectNewLineItem(type)
        else if (line <= this.getLineItemCount(type))
            this.selectLineItem(type, line)
    }

    var linegroup = this.lineitems[ type ];
	if ( linegroup == null || this.getLineItemCount(type) < line )
		return;
	linegroup.splice(line, 1)
    this.logOperation("removeLineItem", {"type" : type})            
    if (this.getCurrentLineItemIndex(type) != -1)
    {
        this.currentlineitems[type] = null;
        this.currentlineitemindexes[type] = null;
    }
}
nlobjRecord.prototype.getLineItemValue = function( group, name, line )
{
	var value = null;
	var linegroup = this.lineitems[ group ];
	if ( linegroup != null )
	{
		var lineitem = linegroup[ line ];
		if ( lineitem != null )
			value = lineitem[ name ];
	}
	return value != null ? value : null;
}
nlobjRecord.prototype.getLineItemCount = function( group )
{
	var linegroup = this.lineitems[ group ];
	return linegroup != null ? linegroup.length - 1 /* zeroth line is unused. */: 0;
}
nlobjRecord.prototype.setLineItemMatrixValue = function( type, fldnam, linenum, column, value )
{
    if ( this.isMatrixField(type, fldnam) )
        this.setLineItemValue(type, this.getMatrixFieldName(type, fldnam, column), linenum, value)
}
nlobjRecord.prototype.getLineItemMatrixValue = function( type, fldnam, linenum, column )
{
    if ( this.isMatrixField(type, fldnam) )
        return this.getLineItemValue(type, this.getMatrixFieldName(type, fldnam, column), linenum)
    return null;
}
nlobjRecord.prototype.findLineItemValue = function( type, fldnam, value )
{
	for (var linenum=1; linenum <= this.getLineItemCount(type);linenum++)
		if (value == this.getLineItemValue(type, fldnam, linenum))
			return linenum;
	return -1;
}
nlobjRecord.prototype.findLineItemMatrixValue = function( type, fldnam, column, value )
{
    if ( this.isMatrixField(type, fldnam) )
        return this.findLineItemValue(type, this.getMatrixFieldName(type, fldnam, column), value);
    return -1;
}
nlobjRecord.prototype.setMatrixValue = function( type, fldnam, column, value )
{
    if ( this.isMatrixField(type, fldnam) )
    {
        this.fields[this.getFieldValue(type+'header')+column] = value;
        this.logOperation("setMatrixValue", {"type" : type, "field" : name, "column" : column, "value" : value})
    }
}
nlobjRecord.prototype.getMatrixValue = function( type, fldnam, column )
{
    return this.isMatrixField(type, fldnam) ? this.getFieldValue(this.getFieldValue(type+'header')+column) : null;
}
nlobjRecord.prototype.getMatrixCount = function( type, fldnam )
{
    return this.isMatrixField(type, fldnam) ? this.getFieldValue(this.getFieldValue(type+'headercount')) : null;
}
nlobjRecord.prototype.selectLineItem = function( type, linenum )
{
    nsapiAssertTrue( this.linetypes[type] != null && linenum > 0 && linenum <= this.getLineItemCount(type), 'SSS_INVALID_SUBLIST_OPERATION' )
    this.currentlineitems[type] = new Object();
    this.currentlineitemindexes[type] = linenum;
    var flds = this.getAllLineItemFields(type)
    for ( var i = 0; i < flds.length; i++ )
        this.currentlineitems[type][flds[i]] = this.getLineItemValue(type, flds[i], linenum)
    this.logOperation("selectLineItem", {"type" : type, "linenum" : linenum})
}
nlobjRecord.prototype.selectNewLineItem = function( type )
{
    nsapiAssertTrue( this.linetypes[type] != null && this.linetypes[type] == 'edit', 'SSS_INVALID_SUBLIST_OPERATION' )
    this.currentlineitems[type] = new Object();
    this.currentlineitemindexes[type] = this.getLineItemCount(type)+ 1;
    this.logOperation("selectNewLineItem", {"type" : type})
}
nlobjRecord.prototype.cancelLineItem = function( type )
{
    nsapiAssertTrue( this.getCurrentLineItemIndex(type) != -1, 'SSS_INVALID_SUBLIST_OPERATION' )
    this.currentlineitems[type] = null;
    this.currentlineitemindexes[type] = null;
    this.logOperation("cancelLineItem", {"type" : type})
}
nlobjRecord.prototype.commitLineItem = function( type )
{
    nsapiAssertTrue( this.getCurrentLineItemIndex(type) != -1, 'SSS_INVALID_SUBLIST_OPERATION' )
    var flds = this.getAllLineItemFields(type)
    var linenum = this.getCurrentLineItemIndex(type);
    for ( var i = 0; i < flds.length; i++ )
        this.setAndCommitLineItemValue(type, flds[i], linenum, this.currentlineitems[type][flds[i]])
    this.currentlineitems[type] = null;
    this.currentlineitemindexes[type] = null;
    this.logOperation("commitLineItem", {"type" : type})
}
nlobjRecord.prototype.getCurrentLineItemIndex = function( type ) { return this.currentlineitems[type] != null ? this.currentlineitemindexes[type] : -1; }
nlobjRecord.prototype.getCurrentLineItemValue = function( type, name )
{
    nsapiAssertTrue( this.getCurrentLineItemIndex(type) != -1, 'SSS_INVALID_SUBLIST_OPERATION' )
    return this.currentlineitems[type][name]
}
nlobjRecord.prototype.setCurrentLineItemValue = function( type, name, value )
{
    nsapiAssertTrue( this.getCurrentLineItemIndex(type) != -1, 'SSS_INVALID_SUBLIST_OPERATION' )
    this.currentlineitems[type][name] = value;
    this.logOperation("setCurrentLineItemValue", {"type" : type, "field" : name, "value" : value})
}
nlobjRecord.prototype.setCurrentLineItemMatrixValue = function( type, fldnam, column, value )
{
    nsapiAssertTrue( this.getCurrentLineItemIndex(type) != -1, 'SSS_INVALID_SUBLIST_OPERATION' )
    this.currentlineitems[type][this.getMatrixFieldName(type, fldnam, column)] = value;
    this.logOperation("setCurrentLineItemMatrixValue", {"type" : type, "field" : fldnam, "column" : column, "value" : value})
}
nlobjRecord.prototype.getCurrentLineItemMatrixValue = function( type, fldnam, column )
{
    nsapiAssertTrue( this.getCurrentLineItemIndex(type) != -1, 'SSS_INVALID_SUBLIST_OPERATION' )
    return this.currentlineitems[type][this.getMatrixFieldName(type, fldnam, column)]
}
/* field text APIs and field metadata APIs not yet supported via nlobjRecord interface in Client SuiteScript */
nlobjRecord.prototype.setFieldText = function( name, text ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.setFieldTexts = function( name, texts ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getFieldText = function( name ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getFieldTexts = function( name ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getLineItemText = function( type, name, line ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getCurrentLineItemText = function( type, name ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.setCurrentLineItemText = function( type, name, text ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getField = function( fldnam ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getSublist = function( type ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getMatrixField = function( type, fldnam ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getLineItemField = function( type, name, linenum ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getLineItemField = function( type, name, linenum ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getFieldDisabled = function( name ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getFieldMandatory = function( name ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getFieldDisplay = function( name ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getFieldVisibility = function( name ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getFieldLabel = function( name ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getLineItemDisplay = function( name ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getLineItemDisabled = function( type, name, linenum ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getLineItemMandatory = function( type, name, linenum ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjRecord.prototype.getLineItemLabel = function( type, name ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
/* internal nlobjRecord helper methods */
nlobjRecord.prototype.isMatrixField = function( type, fld ) { return this.getFieldValue(type+'matrixfields') != null && arrayIndexOf(this.getFieldValue(type+'matrixfields').split(","), fld) != -1; }
nlobjRecord.prototype.getMatrixFieldName = function(type, fldnam, column) { return this.isMatrixField(type, fldnam) ? fldnam+"_"+column+"_" : null; }
nlobjRecord.prototype.logOperation = function(operation, args) { if ( this.initialized ) this.operations.push( { "operation" : operation, "args" : args } ); }
/*--------------- nlobjSearch definition ------------*/
function nlobjSearch(type, id, filters, columns)  /* Not intended to be public; customers should use the factory methods. */
{
    this.type = type;
    this.searchId = id;
    this.scriptId = null;
    this.filters = filters;
    this.columns = columns;
    this.isPublic = false;
}
nlobjSearch.prototype._load = function()
{
    var payloadMap = nsServerCall(nsJSONProxyURL, 'loadSearch', [this.type, this.searchId]);
    this.isPublic = payloadMap['ispublic'];
    this.searchId = payloadMap['searchId'];
    this.scriptId = payloadMap['scriptid'];
    var columnCount = payloadMap['columncount'];
    this.columns = [];
    for (var i=0; i<columnCount; ++i)
    {
        var columnMap = payloadMap['column'+i];
        var columnObject = nsapiUnmarshalSearchColumn(columnMap);
        this.columns.push(columnObject);
    }
}
nlobjSearch.prototype._clone = function()
{
    var i;
    var filtersCopy = [];
    for (i=0; i<this.filters.length; ++i) { filtersCopy.push(this.filters[i]._clone()); }
    var columnsCopy = [];
    for (i=0; i<this.columns.length; ++i) { columnsCopy.push(this.columns[i]._clone()); }
    var clone = new nlobjSearch(this.type, this.searchId, filtersCopy, columnsCopy);
    clone.scriptId = this.scriptId;
    clone.isPublic = this.isPublic;
    return clone;
}
nlobjSearch.prototype.runSearch = function()
{
    return new nlobjSearchResultSet(this._clone());
}
nlobjSearch.prototype.saveSearch = function(title, scriptId)
{
    try
    {
		var rawFilters = nsapiMarshalSearchFilters(this.filters);
		var rawColumns = nsapiMarshalSearchColumns(this.columns);
		var searchId = nsServerCall(nsJSONProxyURL, 'saveSearch', [title, scriptId, this.type, this.searchId, rawFilters, rawColumns, this.isPublic]);
//		nsapiLogUsage( 'nlapiSearchRecord', isValEmpty(searchId) && nsapiIsLookup(this.filters) ? type : null );
		return searchId;
    }
    catch (e)
    {
        throw nlapiCreateError( e );
    }
}
nlobjSearch.prototype.deleteSearch = function()
{
    try
    {
        nsapiAssertTrue(this.searchId && this.searchId != -1, 'SSS_CANT_DELETE_AD_HOC_SEARCH');
		nsServerCall(nsJSONProxyURL, 'deleteSearch', [this.type, this.searchId]);
//		nsapiLogUsage( 'nlapiSearchRecord', isValEmpty(searchId) && nsapiIsLookup(this.filters) ? type : null );
    }
    catch (e)
    {
        throw nlapiCreateError( e );
    }
}
nlobjSearch.prototype.getFilters = function()
{
    return this.filters;
}
nlobjSearch.prototype.setFilters = function(filters)
{
    this.filters = filters;
}
nlobjSearch.prototype.addFilter = function(filter)
{
    if (!this.filters)
        this.filters = [filter];
    else
        this.filters.push(filter);
}
nlobjSearch.prototype.addFilters = function(filters)
{
    if (filters)
    {
        for (var i=0; i<filters.length; ++i)
            this.addFilter(filters[i]);
    }
}
nlobjSearch.prototype.getColumns = function()
{
    return this.columns;
}
nlobjSearch.prototype.setColumns = function(columns)
{
    this.columns = columns;
}
nlobjSearch.prototype.addColumn = function(column)
{
    if (!this.columns)
        this.columns = [column];
    else
        this.columns.push(column);
}
nlobjSearch.prototype.addColumns = function(columns)
{
    if (columns)
    {
        for (var i=0; i<columns.length; ++i)
            this.addColumn(columns[i]);
    }
}
nlobjSearch.prototype.setRedirectURLToSearch = function()
{
    try
    {
		var rawFilters = nsapiMarshalSearchFilters(this.filters);
		var rawColumns = nsapiMarshalSearchColumns(this.columns);
        var url = nsServerCall(nsJSONProxyURL, 'prepareSearchPage', [this.type, this.searchId, rawFilters, rawColumns]);
        nsapiSetRedirectURL(url);
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
nlobjSearch.prototype.setRedirectURLToSearchResults = function()
{
    try
    {
		var rawFilters = nsapiMarshalSearchFilters(this.filters);
		var rawColumns = nsapiMarshalSearchColumns(this.columns);
        var url = nsServerCall(nsJSONProxyURL, 'prepareSearchResults', [this.type, this.searchId, rawFilters, rawColumns]);
        nsapiSetRedirectURL(url);
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
nlobjSearch.prototype.getId = function()
{
    return (!this.searchId || this.searchId == -1) ? null : this.searchId;
}
nlobjSearch.prototype.getScriptId = function()
{
    return this.scriptId;
}
nlobjSearch.prototype.getIsPublic = function()
{
    return this.isPublic;
}
nlobjSearch.prototype.setIsPublic = function(isSearchPublic)
{
    this.isPublic = isSearchPublic;
}
nlobjSearch.prototype._getResultsSlice = function(start, end)
{
    try
    {
		var rawFilters = nsapiMarshalSearchFilters(this.filters);
		var rawColumns = nsapiMarshalSearchColumns(this.columns);
		var rawResults = nsServerCall(nsJSONProxyURL, 'searchRecordSlice', [this.type, this.searchId, rawFilters, rawColumns, start, end]);
		var rowResults = nsapiExtractSearchResults( rawResults, this.columns );

		nsapiLogUsage( 'nlapiSearchRecord', isValEmpty(this.searchId) && nsapiIsLookup(this.filters) ? type : null );
		return rowResults != null && rowResults.length > 0 ? rowResults : null;
    }
    catch( e )
    {
        throw nlapiCreateError( e );
    }
}
/*--------------- nlobjSearchResultSet definition ------------*/
function nlobjSearchResultSet(searchObject)  /* Not intended to be public; customers should use runSearch(). */
{
    this.search = searchObject;
}
nlobjSearchResultSet.prototype.getColumns = function()
{
    return this.search.getColumns();
};
nlobjSearchResultSet.prototype.getResults = function(start, end)
{
    nsapiAssertTrue(start >= 0, 'SSS_INVALID_SEARCH_RESULT_INDEX');
    nsapiAssertTrue((end - start) <= 1000, 'SSS_SEARCH_RESULT_LIMIT_EXCEEDED');
    if (start >= end)
        return [];
    return this.search._getResultsSlice(start, end);
};
nlobjSearchResultSet.prototype.forEachResult = function(callback)
{
    var PAGE_SIZE = 50, continueIteration = true;
    for (var start=0; ; start+=PAGE_SIZE)
    {
        var searchResults = this.getResults(start, start+PAGE_SIZE);
        if (!searchResults)
            break;
        for (var i=0; continueIteration && i<searchResults.length; ++i)
        {
            continueIteration = callback(searchResults[i]);
        }
        if (searchResults.length < PAGE_SIZE)
            break;
    }
};
/*--------------- nlobjSearchFilter definition ------------*/
function nlobjSearchFilter( name, join, operator, value, value2 )
{
    nsapiCheckArgs( [name], ['name'], 'nlobjSearchFilter' );
    this.name = name;
	this.join = join;
	this.operator = operator;
	this.values = new Array();
    this.addValue( value );
    this.addValue( value2 );
	this.formula = null;
	this.summarytype = null;
}
nlobjSearchFilter.prototype._clone = function()
{
    var clone = new nlobjSearchFilter(this.name, this.join, this.operator, null, null);
    clone.values = this.values.slice();
    clone.formula = this.formula;
    clone.summarytype = this.summarytype;
    return clone;
}
nlobjSearchFilter.prototype.getName = function( ) { return this.name; }
nlobjSearchFilter.prototype.getJoin = function( ) { return this.join; }
nlobjSearchFilter.prototype.getOperator = function( ) { return this.operator; }
nlobjSearchFilter.prototype.getSummaryType = function( ) { return this.summarytype; }
nlobjSearchFilter.prototype.getFormula = function( ) { return this.formula; }
nlobjSearchFilter.prototype.setFormula = function( formula ) { this.formula = formula; return this; }
nlobjSearchFilter.prototype.setSummaryType = function( type ) { this.summarytype = type; return this; }
nlobjSearchFilter.prototype.addValue = function( value )
{
	if ( isArray(value) )
	{
		for ( var i = 0; i < value.length; i++ )
		{
			if ( value[i] != null )
				this.values[this.values.length] = String(value[i]);
		}
	}
	else if ( value != null )
		this.values[this.values.length] = new String(value);
}
/*--------------- nlobjSearchColumn definition ------------*/
function nlobjSearchColumn( name, join, summary )
{
    nsapiCheckArgs( [name], ['name'], 'nlobjSearchColumn' );
    this.name = name;
	this.join = join;
	this.summary = summary;
    this.type = null;
    this.label = null;
	this.functionid = null;
	this.formula = null;
	this.sortdir = null;
	this.index = -1;
	this.userindex = -1;
    this.whenorderedby = null;
    this.whenorderedbyjoin = null;
}
nlobjSearchColumn.prototype._clone = function()
{
    var clone = new nlobjSearchColumn(this.name, this.join, this.summary);
    clone.type = this.type;
    clone.label = this.label;
    clone.functionid = this.functionid;
    clone.formula = this.formula;
    clone.sortdir = this.sortdir;
    clone.index = this.index;
    clone.userindex = this.userindex;
    clone.whenorderedby = this.whenorderedby;
    clone.whenorderedbyjoin = this.whenorderedbyjoin;
    return clone;
};
nlobjSearchColumn.prototype.getName = function( ) { return this.name; };
nlobjSearchColumn.prototype.getJoin = function( ) { return this.join; };
nlobjSearchColumn.prototype.getType = function( ) { return this.type; };
nlobjSearchColumn.prototype.getSummary = function( ) { return this.summary; };
nlobjSearchColumn.prototype.getFormula = function( ) { return this.formula; };
nlobjSearchColumn.prototype.setFormula = function( formula ) { this.formula = formula; return this; };
nlobjSearchColumn.prototype.getLabel = function( ) { return this.label; };
nlobjSearchColumn.prototype.setLabel = function( label ) { this.label = label; return this; };
nlobjSearchColumn.prototype.getFunction = function( ) { return this.functionid; };
nlobjSearchColumn.prototype.setFunction = function( functionid ) { this.functionid = functionid; return this; };
nlobjSearchColumn.prototype.getSort = function( ) { return this.sortdir; };
nlobjSearchColumn.prototype.setSort = function( descending ) { this.sortdir = descending ? "DESC" : "ASC"; return this; };
nlobjSearchColumn.prototype.getWhenOrderedBy = function( ) { return this.whenorderedby; };
nlobjSearchColumn.prototype.getWhenOrderedByJoin = function( ) { return this.whenorderedbyjoin; };
nlobjSearchColumn.prototype.setWhenOrderedBy = function( whenorderedby, whenorderedbyjoin ) { this.whenorderedby = whenorderedby; this.whenorderedbyjoin = whenorderedbyjoin; return this; };

/*--------------- nlobjSearchResult definition ------------*/
function nlobjSearchResult( type, id, rawValues, rawColumns )
{
	this.type = type;
	this.id = id;
	this.rawValues = rawValues;
	this.rawColumns = rawColumns;
	this.valuesByIdx = [];	/* index values by column index for performance */
	this.valuesByKey = new Object(); 	/* index values by legacy key for performance */
	for ( var i = 0; rawValues != null && i < rawValues.length; i++ )
	{
		this.valuesByIdx[rawValues[i].index] = rawValues[i]
		this.valuesByKey[this.getKey(rawColumns[i].name, rawColumns[i].join, rawColumns[i].summary)] = rawValues[i]
	}
}
nlobjSearchResult.prototype.getId = function( ) { return this.id; }
nlobjSearchResult.prototype.getRecordType = function( ) { return this.type; }
nlobjSearchResult.prototype.getValue = function( name, join, summary )
{
	var cell = null;
	if ( typeof(name) == "string" )
		cell = this.valuesByKey[ this.getKey(name,join,summary) ]
	else if (name instanceof nlobjSearchColumn)
	{
		var col = name;
		if ( col.index != -1 )
			cell = this.valuesByIdx[ col.index ];
		if ( cell == null )
			cell = this.valuesByKey[ this.getKey(col.name,col.join,col.summary) ]
	}
	return cell != null ? cell.value : null;
}
nlobjSearchResult.prototype.getText = function( name, join, summary )
{
	var cell = null;
	if ( typeof(name) == "string" )
		cell = this.valuesByKey[ this.getKey(name,join,summary) ]
	else if (name instanceof nlobjSearchColumn)
	{
		var col = name;
		if ( col.index != -1 )
			cell = this.valuesByIdx[ col.index ];
		if ( cell == null )
			cell = this.valuesByKey[ this.getKey(col.name,col.join,col.summary) ]
	}
	return cell != null ? cell.text : null;
}
nlobjSearchResult.prototype.getKey = function( name, join, summary )
{
	return (join != null ? join.toLowerCase()+'_' : '')+name.toLowerCase()+(summary != null ? '_'+summary.toLowerCase() : '');
}
nlobjSearchResult.prototype.getAllColumns = function()
{
	return this.rawColumns;
}

var nsDefaultContextObj = null;
/*--------------- nlobjContext definition ------------*/
function nlobjContext( )
{
	var jsContextObj = nsDefaultContextObj != null ? nsDefaultContextObj : nsServerCall(nsJSONProxyURL, "getContext");

	this.name = jsContextObj.name;
	this.email = jsContextObj.email;
	this.user = jsContextObj.user;
	this.role = jsContextObj.role;
	this.roleid = jsContextObj.roleid;
	this.rolecenter = jsContextObj.rolecenter;
	this.company = jsContextObj.company;
	this.contact = jsContextObj.contact;
	this.department = jsContextObj.department;
	this.location = jsContextObj.location;
	this.version = jsContextObj.version;
	this.subsidiary = jsContextObj.subsidiary;
	this.environment = jsContextObj.environment;
	this.executioncontext = jsContextObj.context;
	this.scriptprefs = null;
	this.usage = new Object();
	this.internal = true;
	this.setUsage = function(func, type)
	{
		var script = this.getScriptId();
        if ( script != "global" && script != "internal" )
        {
            var iCost = parseInt( nsUsageCosts[ func ] );
            if (type != null)
                iCost /= (nsapiGetRecord(type).type == "RECORD" ? 5 : nsapiGetRecord(type).type == "BODY" ? 1 : 2);
            this.usage[script] = (this.usage[script] != null ? this.usage[script] : 0) + iCost;
        }
    }
}
nlobjContext.prototype.getName = function( ) { return this.name; }
nlobjContext.prototype.getUser = function( ) { return this.user; }
nlobjContext.prototype.getRole = function( ) { return this.role; }
nlobjContext.prototype.getRoleId = function( ) { return this.roleid; }
nlobjContext.prototype.getRoleCenter = function( ) { return this.rolecenter; }
nlobjContext.prototype.getEmail = function( ) { return this.email; }
nlobjContext.prototype.getContact = function( ) { return this.contact; }
nlobjContext.prototype.getCompany = function( ) { return this.company; }
nlobjContext.prototype.getDepartment = function( ) { return this.department; }
nlobjContext.prototype.getLocation = function( ) { return this.location; }
nlobjContext.prototype.getSubsidiary = function( ) { return this.subsidiary; }
nlobjContext.prototype.getEnvironment = function( ) { return this.environment; }
nlobjContext.prototype.getExecutionContext = function( ) { return this.executioncontext; }
nlobjContext.prototype.getRemainingUsage = function( ) { return 1000 - (this.usage[this.getScriptId()] == null ? 0 : parseInt( this.usage[this.getScriptId()] )); }
nlobjContext.prototype.getRemainingInstructions = function( ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjContext.prototype.getBundleId = function( ) { return fBundleIds[ nsapiQueryScript( 'scriptid' ) ]; }
nlobjContext.prototype.getScriptId = function( ) { return nsapiQueryScript( 'scriptid' ); }
nlobjContext.prototype.getDeploymentId = function( ) { return fDeployIds[ nsapiQueryScript( 'scriptid' ) ]; }
nlobjContext.prototype.getScriptType = function( ) { return "CLIENT"; }
nlobjContext.prototype.getFeature = function( name ) { return nsServerCall(nsJSONProxyURL, "getFeature", [name]); }
nlobjContext.prototype.getPreference = function( name )
{
	if ( name.toLowerCase().indexOf('custscript') == 0 )
	{
		this.scriptprefs = this.scriptprefs != null ? this.scriptprefs : nsServerCall(nsJSONProxyURL, "getScriptPrefs", [nlapiGetRecordType()]);
		return this.scriptprefs[name];
	}
	return nsServerCall(nsJSONProxyURL, "getPref", [name]);
}
nlobjContext.prototype.getPermission = function( name ) { return nsServerCall(nsJSONProxyURL, "getPerm", [name]); }
nlobjContext.prototype.getSessionObject = function( name ) { return nsServerCall(nsJSONProxyURL, "getSessionObject", [name]); }
nlobjContext.prototype.setSessionObject = function( name, value ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjContext.prototype.getAllSessionObjects = function() { return nsServerCall(nsJSONProxyURL, "getAllSessionObjects"); }
nlobjContext.prototype.getPercentComplete = function( ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjContext.prototype.setPercentComplete = function( value ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjContext.prototype.getRecordCount = function( ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjContext.prototype.setRecordCount = function( value ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjContext.prototype.getRecordCompletedCount = function( ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjContext.prototype.setRecordCompletedCount = function( value ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjContext.prototype.getRecordFailedCount = function( ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjContext.prototype.setRecordFailedCount = function( value ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjContext.prototype.getSetting = function( type, name )
{
	switch ( type.toLowerCase() )
	{
		case "script" :
			return this.getPreference(name);
		case "feature" :
	       	return this.getFeature(name) ? "T" : "F";
		case "preference" :
			return this.getPreference(name);
		case "permission" :
			return this.getPermission(name);
		case "session" :
			return this.getSessionObject(name);
		throw nlapiCreateError('SSS_NOT_YET_SUPPORTED');
	}
	return null;
}
nlobjContext.prototype.setSetting = function( type, name, value ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjContext.prototype.getVersion = function( ) { return this.version; }
nlobjContext.prototype.isInternal = function( ) { return nsapiIsInternal(); }
nlobjContext.prototype.getColorPreferences = function( ) { return nsServerCall(nsJSONProxyURL, "getColorPreferences"); }

/*--------------- nlobjError definition ------------*/
function nlobjError( code, error, suppressnotification )
{
    this.id = null;
    this.code = code;
	this.details = error;
    this.stacktrace = stacktrace();
	this.suppressnotification = suppressnotification;
	if ( code instanceof nlobjError || code instanceof NLXMLResponseError )
	{
		this.id = code.getId();
		this.code = code.getCode();
		this.details = code.getDetails();
        if ( code instanceof nlobjError )
            this.stacktrace = code.getStackTrace();
	}
    this.name = this.code;      /* exposed for compatibility with Javascript Error object. */
    this.message = this.details;/* exposed for compatibility with Javascript Error object. */
    this.description = this.details;/* exposed for compatibility with Javascript Error object. */
}
nlobjError.prototype.getId = function( ) { return this.id; }
nlobjError.prototype.getCode = function( ) { return this.code; }
nlobjError.prototype.getDetails = function( ) { return this.details; }
nlobjError.prototype.getStackTrace = function( ) { return this.stacktrace; }

/*--------------- nlobjServerResponse definition ------------*/
function nlobjServerResponse ( code, body, headers, error )
{
	this.code = code;
	this.body = body;
	this.headers = headers;
    this.headerNames = new Array();
    for ( var i in this.headers )
        this.headerNames[this.headerNames.length] = i;
    this.error = error;
	this.contentType = this.getHeader("Content-Type");
}
nlobjServerResponse.prototype.getCode = function( ) { return this.code; }
nlobjServerResponse.prototype.getBody = function( ) { return this.body; }
nlobjServerResponse.prototype.getContentType = function( ) { return this.contentType; }
nlobjServerResponse.prototype.getAllHeaders = function( ) { return this.headerNames; }
nlobjServerResponse.prototype.getHeader = function( name ) { return this.headers[ this.resolveHeaderName(name) ] != null ? nullIfEmpty( this.headers[ this.resolveHeaderName(name) ][0] ) : null }
nlobjServerResponse.prototype.getHeaders = function( name ) { return this.headers[ this.resolveHeaderName(name) ] }
nlobjServerResponse.prototype.getError = function( ) { return this.error; }
nlobjServerResponse.prototype.resolveHeaderName = function(name)
{
	if (window.navigator.userAgent.indexOf("Safari") != -1 && name != null && name.indexOf(nsHeaderPrefix) == 0 && this.headers[name] == null)
		for (var i in this.headers)
			if (i.toLowerCase() == name.toLowerCase())
				return i;
	return name;
}


/*--------------- simple nlobjField definition (readonly for now). Currently implemented as snapshot. Make dynamic for 2010.1 ------------*/
function nlobjField( name, type, sublist )
{
    this.name = name;
	this.type = type;
	this.noslaving = false;
	this.sublist = sublist;
	this.label = null;
	this.required = false;
	this.disabled = false;
	this.hidden = false;
	this.display = false;
	this.visible = false;
	this.popup = false;
	this.readonly = false;
	this.parent = null;
	this.uifield = null;
	this.linenum = -1;
}
nlobjField.prototype.getName = function( ) { return this.name; }
nlobjField.prototype.getType = function( ) { return this.type; }
nlobjField.prototype.getLabel = function( ) 	{ return this.label; }
nlobjField.prototype.getSubList = function( ) 	{ return this.sublist; }
nlobjField.prototype.getParent = function( ) 	{ return this.parent; }
nlobjField.prototype.getLine = function( ) 	{ return this.linenum; }
nlobjField.prototype.getUIField = function( ) 	{ return this.uifield; }
nlobjField.prototype.noSlaving = function( ) 	{ return this.noslaving; }
nlobjField.prototype.isMandatory = function( ) 	{ return this.required; }
nlobjField.prototype.isDisabled = function( ) 	{ return this.disabled; }
nlobjField.prototype.isHidden = function( ) 	{ return this.hidden; }
nlobjField.prototype.isPopup = function( ) 		{ return this.popup; }
nlobjField.prototype.isDisplay = function( ) 	{ return this.display; }
nlobjField.prototype.isVisible = function( )    { return this.visible; }
nlobjField.prototype.isReadOnly = function( ) 	{ return this.readOnly; }
nlobjField.prototype.setLabel = function( required ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjField.prototype.setAlias = function( required ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjField.prototype.setDefaultValue = function( required ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjField.prototype.setDisabled = function( disabled ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjField.prototype.setMandatory = function( disabled ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjField.prototype.setMaxLength = function( disabled ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjField.prototype.setDisplayType = function( disabled ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjField.prototype.setLayoutType = function( disabled ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjField.prototype.setLinkText = function( disabled ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjField.prototype.setHelpText = function( text ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjField.prototype.setDisplaySize = function( disabled ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjField.prototype.setPadding = function( disabled ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjField.prototype.addSelectOption = function( disabled ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjField.prototype.getSelectOptions = function( token ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }

/*--------------- nlobjSubList definition (readonly for now). Currently implemented as snapshot. Make dynamic for 2010.1 ------------*/
function nlobjSubList( name, type )
{
    this.name = name;
	this.type = isEditMachine(type) ? (eval( String(type) + '_machine').isinline ? "inlineeditor" : "editor") :
                getFormElement(document.forms['main_form'], type+"matrixfields" ) != null ? "matrix" : "list";
	this.label = null;
	this.hidden = false;
    this.display = true;
}
nlobjSubList.prototype.getName = function( ) { return this.name; }
nlobjSubList.prototype.getType = function( ) { return this.type; }
nlobjSubList.prototype.getLabel = function( ) 	{ return this.label; }
nlobjSubList.prototype.isHidden = function( ) 	{ return this.hidden; }
nlobjSubList.prototype.isDisplay = function( ) 	{ return this.display; }
nlobjSubList.prototype.isChanged = function( ) 	{ return wasMachineChanged(this.name); }
nlobjSubList.prototype.setLabel = function( label ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.setHelpText = function( help ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.setDisplayType = function( type ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.setLineItemValue = function( field, line, value ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.setLineItemMatrixValue = function( field, line, column, value ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.setLineItemValues = function( values ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.getField = function( name ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.getAllFields = function( ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.getAllHeaderFields = function( ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.addField = function( name,type,label,source,group ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.addHeaderField = function( name,type,label,source ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.setAmountField = function( fldnam ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.setUniqueField = function( fldnam ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.getMatrixCount = function( field ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.addButton = function( name, label, script ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.getButton = function( name ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.addRefreshButton = function( ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }
nlobjSubList.prototype.addMarkAllButtons = function( ) { throw nlapiCreateError('SSS_NOT_YET_SUPPORTED'); }

/*--------------------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------------------- */
/* ------------- Internal Helper functions for Client SuiteScript API.  ----------------- */
/*--------------------------------------------------------------------------------------- */
/*--------------------------------------------------------------------------------------- */
function nsapiButtonCall(trigger, scriptid, func, args)
{
    return nsapiCallUserScript(trigger, scriptid, func, args)
}
function nsapiCallUserScript(trigger, scriptid, func, args)
{
    var isInternal = nsapiIsInternal();
    try
    {
        nsapiSetIsInternal(false);
        return nsapiCallScript(trigger, scriptid, func, args)
    }
    finally
    {
		nsapiUpdateMachines();
        nsapiSetIsInternal(isInternal);
    }
}
function nsapiCallScript(trigger, scriptid, func, args)
{
	if (isValEmpty(func))
		return true;
	var argstr = ""
	if (typeof(func) != "function" && (typeof(func) != "string" || func.indexOf("(") == -1))
	{
		for ( var i = 0; args != null && i < args.length; i++ )
			argstr += (i > 0 ? ", " : "") + (args[i] == null || typeof(args[i]) == "undefined" ? "null" : typeof(args[i]) != "string" ? args[i] : "'"+args[i]+"'");
	}
	if (nlapiGetContext().isInternal())
	{
		if ( typeof(func) == "function" )
			return func()
		else if ( typeof(func)== "string" && func.indexOf("(")>0 )
			return eval(func)
		else
			return eval(func+"("+argstr+")");
	}
	else
	{
		try
		{
			if (typeof(func) == "function")
				return func()
			else if (typeof(func)== "string" && func.indexOf("(")>0)
				return eval(func)
			else
				return eval(func+"("+argstr+")");
		}
		catch ( e )
		{
			var fn = typeof(func) == "function" ? getFuncName(func) : func.indexOf("(")>0 ? func.substring(0, func.indexOf("(")) : func;
			var id = e.getCode != null && typeof(e.getCode) == "function" ? e.getId() : null;
			var code = e.getCode != null && typeof(e.getCode) == "function" ? e.getCode() : typeof(e) == "string" ? new String(e) : typeof(e) == "object" && e.name && e.message ? "JS_EXCEPTION" : "UNEXPECTED_ERROR";
            if (code == "UNEXPECTED_ERROR" && id != null)
                code += " (id="+id+")";
			var msg = e.getDetails != null && typeof(e.getDetails) == "function" ? emptyIfNull(e.getDetails()) : typeof(e) == "string" ? "" : typeof(e) == "object" && e.name && e.message ? e.name+' '+e.message : e.toString()
			var suppressnotification = e.getCode != null && typeof(e.getCode) == "function" && e.suppressnotification === true;
			var supportsLogging = scriptid != "customform";
			alert(window.nsScriptErrorMsg+'\n\n'+fn+' ('+trigger+')\n'+scriptid+''+(isValEmpty(nlapiGetContext().getBundleId()) ? '' : ' ('+ nlapiGetContext().getBundleId() +')')+'\n\n'+""+code+'\n'+msg)
			if (supportsLogging)
				nsServerCall(nsJSONProxyURL, "logError", [code, msg, id, fn, scriptid, suppressnotification, nlapiGetRecordType(), nlapiGetRecordId()]);
			throw e;
		}
	}
}
function nsapiIsInternal( )
{
    return nlapiGetContext().internal;
}
function nsapiSetIsInternal( x )
{
	nlapiGetContext().internal = x;
}
function nsapiQueryScript( arg )
{
	for (var a=arguments.callee.caller; a != null && a.caller != a; a=a.caller)
	{
		if ( getFuncName(a).indexOf("nsapiCallScript") >= 0 && a.arguments.length >= 3 )
			return a.arguments[arg == "trigger" ? 0 : 1];
    }
	return arg == "scriptid" ? "global" : null;
}

function nsapiFireOnChange(fld,firefieldchanged)
{
	if (nsapiIsInternal() && firefieldchanged == false)	/* bail if author requested fieldchange to not fire */
		return;

	var fcFunc = '';
	var checkValid = fld.checkvalid
    var isInternal = nsapiIsInternal();
    if (firefieldchanged == false && document.forms['main_form'].elements.nlapiFC != null)/* suppress user fieldchange if requested */
    {
        fcFunc = document.forms['main_form'].elements.nlapiFC.value;
        document.forms['main_form'].elements.nlapiFC.value = '';
    }
    try
    {
		fld.checkvalid = true;
        nsapiSetIsInternal(true)
        fireProperOnChange(fld);
    }
    finally
    {
        if (fcFunc.length > 0)
            document.forms['main_form'].elements.nlapiFC.value = fcFunc;
		fld.checkvalid = checkValid;
        nsapiSetIsInternal(isInternal)
    }
}
var nsUpdatedMachines = new Object();	/* track updated line items */
function nsapiUpdateMachines()
{
    for( var s in nsUpdatedMachines )
    {
        var mch = eval( String(s) + '_machine');
        if (mch != null)
            mch.buildtable();
    }
    nsUpdatedMachines = new Object();
}
var nsDisabledFields = new Object();	/* track disabled main form fields */
/* ------------- Helper functions for managing access to tasklinks and recordtype metadata ------------ */
var nsTasklinks;
var nsRecordTypes;
function nsapiGetTaskLink( id )
{
	if ( nsTasklinks == null )
	{
		nsTasklinks = nsServerCall(nsJSONProxyURL, "getTaskLinks");
	}
   	return nsTasklinks[ id ];
}
function nsapiInitRecords()
{
	if ( nsRecordTypes == null )
	{
	    nsRecordTypes = nsServerCall(nsJSONProxyURL, "getRecordTypes");
	}
}
function nsapiGetRecord(type)
{
	nsapiInitRecords();
	return nsRecordTypes[ type ];
}
function nsapiGetRecordURL(type, id)
{
	nsapiInitRecords();
	var recordType = nsapiGetRecord(type);
    if (recordType != null)
	{
		var url = recordType.url;
		var params = recordType.urlparams;
		if (params != null && params.indexOf(',') != -1)
			params = params.replace(',', '&')
		if (!isValEmpty( id ))
			url = addParamToURL( url, 'id', id )
		if ((isValEmpty(id) || recordType.type == 'OTHER') && params != null && url.indexOf(params) == -1)
			url = addNextParamPrefixToURL( url ) + params;
		return url;
	}
	else
		return null;
}
function nsapiModifyLoadArg(param)
{
	if (param == "customform")
		param = "cf"
	return param;
}

var nsUsageCosts = null;
function nsapiCheckUsage( )
{
	if ( nsUsageCosts == null )
	{
		nsUsageCosts = nsServerCall(nsJSONProxyURL, 'getUsageUnits');
	}
    if ( nlapiGetContext().getRemainingUsage() < 0 )
        throw new nlapiCreateError( 'SCRIPT_EXECUTION_USAGE_LIMIT_EXCEEDED', 'Script Execution Usage Limit Exceeded' );
}
function nsapiLogUsage( func, type )
{
	nlapiGetContext().setUsage(func, type);
}
function nsapiCheckType( type, funcName, bStrictValidation )
{
	nsapiInitRecords();
	var typeObj = nsapiGetRecord(type);
    if ( typeObj == null || (bStrictValidation && typeObj.scriptable == false) )
		throw nlapiCreateError( 'SSS_INVALID_RECORD_TYPE', (funcName != null ? funcName+': ' : '')  +'type argument '+type+' is not a valid record or is not available in your account. Please see the documentation for a list of supported record types.' );
    return true;
}
function nsapiCheckArray( arrayObj, name, objType )
{
	if ( !isArray(arrayObj) )
		return;

	for ( var i = 0; i < arrayObj.length; i++ )
		if ( arrayObj[ i ] == null || !(arrayObj[ i ] instanceof objType) )
			throw nlapiCreateError( 'SSS_INVALID_ARRAY_ARGUMENT', name+'['+i+']' );
}
function nsapiResolveField(type, fldnam, linenum, column)
{
    var fld = null;
    if ( column == null )
    {
        if ( type == null )
        {
            var form = typeof(ftabs) != 'undefined' && ftabs[fldnam.toLowerCase()] != null ? document.forms[ftabs[fldnam.toLowerCase()]+'_form'] : document.forms['main_form'];
            fld = form.elements[ fldnam ];
            if ( fld == null )
                fld = getFormElement( form, fldnam.toLowerCase()+"_send" );
        }
        else
        {
            var form = document.forms[type+'_form'];
            fld = form.elements[ isEditMachine(type) ? fldnam : fldnam+linenum ];
        }
    }
    else
        fld = linenum != null ? getMatrixField(type, fldnam, linenum, column) : getMatrixHeaderField(type, fldnam, column);
    return fld;
}
function nsapiIsLookup(filters)
{
    return filters != null && filters.length == 1 && filters[0].getName().toLowerCase() == "internalid"
                && filters[0].getOperator().toLowerCase() == "anyof"
                && filters[0].getSummaryType() == null
                && filters[0].getFormula() == null;
}
/* ------------ Helper function used for unmarshalling search results from server. ----------------*/
function nsapiExtractSearchResults(rawResults, columns)
{
	var rowResults = [];
    var columnArray = nsapiColumnsAsArray(columns);
	if ( rawResults != null )
	{
		for ( var i = 0; rawResults.columns != null && i < rawResults.columns.length; i++ )
		{
			var obj = null;
			var col = rawResults.columns[i];
			if ( col.userindex == -1 )
			{
				obj = new nlobjSearchColumn(rawResults.columns[i].name, rawResults.columns[i].join, rawResults.columns[i].summary);
				obj.sortdir = col.sortdir;
				obj.formula = col.formula;
				obj.label = col.label;
				obj.functionid = col.functionid;
                obj.whenorderedby = col.whenorderedby;
                obj.whenorderedbyjoin = col.whenorderedbyjoin;
			}
			else if (columnArray != null)
			{
                obj = columnArray[col.userindex-1];
			}
			obj.index = col.index;
            obj.type = col.type;            
            rawResults.columns[i] = obj;
		}

		for ( var i = 0; i < rawResults.rows.length; i++ )
		{
			rowResults[rowResults.length] = new nlobjSearchResult( rawResults.rows[i].recordType, rawResults.rows[i].id, rawResults.rows[i].cells, rawResults.columns )
		}
	}
	return rowResults.length == 0 ? null : rowResults;
}

/* ------------- Helper function(s) for Serializing <record></record> Element to an nlobjRecord ----------------*/
function nsapiExtractRecord( nsrecord )
{
	var sKey = nsSelectValue( nsrecord, "@id" );
	var sType = nsSelectValue( nsrecord, "@recordType" );

	var record = new nlobjRecord( sType, sKey );
    record.fieldnames = nsSelectValue( nsrecord, "@fields" ).split(",")
    var nsfields = nsSelectNodes( nsrecord, "*" );
    nsapiExtractFields( record, nsfields);

	var nsmachines = nsSelectNodes( nsrecord, "machine" );
	for ( var m = 0; nsmachines != null && m < nsmachines.length; m++ )
	{
		var nsmachine = nsmachines[ m ];
		var machineName = nsmachine.getAttribute('name');
		var nslines = nsSelectNodes( nsmachine, "line" );
        record.linetypes[machineName] = nsmachine.getAttribute('type');
        record.linefields[machineName] = nsmachine.getAttribute('fields').split(',');
        if ( nsmachine.getAttribute('matrixfields') != null )
            record.matrixfields[machineName] = nsmachine.getAttribute('matrixfields').split(',');
		for ( var line = 0; nslines != null && line < nslines.length; line++ )
		{
			var nsline = nslines[ line ];
			var nslinefields = nsSelectNodes( nsline, "*" );
            nsapiExtractFields( record, nslinefields, machineName, line+1);
		}
    }
    record.initialized = true;
    return record;
}
function nsapiExtractFields( record, fields, machine, linenum )
{
    var buffer = new Array();
    for (var i = 0; fields != null && i < fields.length; i++)
    {
        var field = fields[ i ];
        var fieldName = field.nodeName;
		if ( fieldName == "machine" && field.getAttribute('type') != null )	/* skip over machine nodes. */
			continue
		var fieldValue = nsGetXMLValue( field );
        var fieldValues = buffer[ fieldName ] != null ? buffer[ fieldName ] : new Array();

        fieldValues[ fieldValues.length ] = fieldValue;
        buffer[ fieldName ] = fieldValues;
        eval( machine != null ? 'record.setAndCommitLineItemValue( machine, fieldName, linenum, fieldValues.length == 1 ? fieldValues[0] : fieldValues )' : 'record.setFieldValue( fieldName, fieldValues.length == 1 ? fieldValues[0] : fieldValues )');
    }
}
/* ------------- Helper function(s) for Serializing nlobjRecord into an <record><record> Document ----------------*/
function nsapiSerializeRecord( record )
{
	var nsrecord = nsStringToXML("<record></record>");
	nsrecord.documentElement.setAttribute('recordType', record.getRecordType() );
	if ( record.getId() != null )
		nsrecord.documentElement.setAttribute('id', record.getId() );
    var operations = nsSetChildValue( nsrecord.documentElement, "operations" );
    nsapiSerializeOperation( record.operations[0], operations, "load" );
	for ( var i = 1; i < record.operations.length; i++ )
	{
        nsapiSerializeOperation( record.operations[i], operations, "data" );
	}
    return nsrecord;
}
function nsapiSerializeOperation( jsOperation, operationsNode, type )
{
    var operation = nsSetChildValue( operationsNode, "operation" );
    operation.setAttribute("type", type)
    operation.setAttribute("name", jsOperation.operation)

    for (var arg in jsOperation.args)
    {
        if ( isArray( jsOperation.args[arg] ) )
        {
            for ( var i = 0; i < jsOperation.args[arg].length; i++ )
            {
                nsSetChildValue( operation, arg, jsOperation.args[arg][i] );
            }
        }
        else if ( typeof jsOperation.args[arg] == "object" )
        {
            var argNode = nsSetChildValue( operation, arg );
            for (var entry in jsOperation.args[arg])
            {
                nsSetChildValue( argNode, entry, jsOperation.args[arg][entry] );
            }
        }
        else
        {
            nsSetChildValue( operation, arg, jsOperation.args[arg] );
        }
    }
}
var nsProxyURL = '/app/common/scripting/nlapihandler.nl';
var nsJSONProxyURL = '/app/common/scripting/nlapijsonhandler.nl';
/* ----- internal function for handling AJAX server call for issuing nlapiRequestURL calls (nsapiPrefix is defined in NLAPI.jsp) -----*/
function nsapiAjaxResponse( response, callbackFunc )
{
	var error = response.getError();
	if ( error != null )
	{
		error = nlapiCreateError(error);
		if ( callbackFunc == null )
			throw error;
	}

	var code = response.getCode();
	var body = response.getBody();
	var headers = response.getHeaders();
	var nlheaders = [];
	if ( headers[nsHeaderPrefix+'-Code'] != null )  /* handle proxyed requests */
	{
		code = headers[nsHeaderPrefix+'-Code'];
		for ( var header in headers )
			if ( header.indexOf( nsHeaderPrefix ) == 0 )
				nlheaders[header.substring( nsHeaderPrefix.length+1 )] = headers[header];
	}
	else
		nlheaders = headers;

	var response = new nlobjServerResponse( code, body, nlheaders, error );
	if ( typeof(callbackFunc) == "function" )
		callbackFunc( response );
	return response;
}
function nsapiCheckArgs( funcArgs, funcArgNames, funcName )
{
	for ( var i = 0; i < funcArgs.length; i++ )
	{
		if ( funcArgs[ i ] == null || (typeof funcArgs[ i ] == "string" && isValEmpty(funcArgs[ i ])) )
		{
			throw nlapiCreateError( 'SSS_MISSING_REQD_ARGUMENT', (funcName != null ? funcName+': ' : '')  +'Missing a required argument: '+funcArgNames[ i ] );
		}
	}
}
function nsapiAssertTrue( expression, errorCode, errorMessage )
{
	if ( !expression )
	{
		throw nlapiCreateError( errorCode, errorMessage );
	}
}
function nsapiExtractMap(obj)
{
	if ( obj == null ) return null;
	var map = new Object();
	for ( var attr in obj )
		map[attr] = obj[attr]
	return map;
}
/* ----- internal function for handling machine segmenting -----*/
function nsapiGetCurrentSegment(type)
{
	var sel = null;
	if (document.forms[type+'_main_form'] != null)
		sel = document.forms[type+'_main_form'].elements[type+'range'];
	return sel != null ? parseInt(getSelectValue(sel)) : 1;
}

function nsapiGetSegmentForLine(type, linenum)
{
	var segmentSize = null;
	if (document.forms[type+'_main_form'] != null)
		segmentSize = document.forms[type+'_main_form'].elements[type+'segmentsize'];
	return segmentSize != null ? Math.floor((linenum-1)/parseInt(segmentSize.value)) : 1;
}

function nsapiSelectSegmentForLine(type, linenum)
{
	var sel = null;
		if (document.forms[type+'_main_form'] != null)
		sel = document.forms[type+'_main_form'].elements[type+'range'];
	if (sel != null)
	{
		var currentSegment = nsapiGetCurrentSegment(type);
		var targetSegment = nsapiGetSegmentForLine(type, linenum);
		if (currentSegment != targetSegment)
		{
			setSelectValue(sel, targetSegment);
			eval("Sync" + type + "range(true);");
		}
	}
}

function process_slaving_result(response)
{
    var isInternal = nsapiIsInternal();
    try
    {
        nsapiSetIsInternal(true)
        process_slaving_result_original(response);
    }
    finally
    {
        nsapiSetIsInternal(isInternal)
    }
}

function nlapiShowSaveConfirmation(sUrl)
{
    if (window.ischanged && window.bautosave)
    {
        if (window.bautosave == 'F') // Will move the title to translation once UE comes up with the language.
            nlShowSaveConf('You have made changes to this page. Would you like to save before continuing?', 'Information', null,sUrl);
        else {
            if ((!document.forms['main_form'].onsubmit || document.forms['main_form'].onsubmit()))    { 
                var theForm = document.forms["main_form"];
                var newOption = document.createElement("input");
                newOption.id = "setclientredirecturl";
                newOption.name = "setclientredirecturl";
                newOption.type = "hidden";
                newOption.value = sUrl;
                theForm.appendChild(newOption); 
                document.forms['main_form'].submit();
            }
        }
        return true;
    }
    else
        return false;
}

function nlapiGetLineItemLabel(type, fldnam)
{
    nsapiCheckArgs( [type, fldnam], ['type', 'fldnam'], 'nlapiGetLineItemLabel' );
    if ( hasMachine(type) )
    {
        var mch = eval( String(type) + '_machine');
        return mch.getFormElementLabel(mch.getArrayPosition(fldnam));
    }
    else
    {
        // implement me for list machines using splitIntoCells( document.forms['main_form'].elements[type+"labels"].value )
    }
    return null;
}


function nlapiViewCurrentLineItemSubrecord(machinename, fldname)
{
    nsapiAssertTrue(isSubrecordField(machinename, fldname),  'SSS_INVALID_FIELD_ON_SUBRECORD_OPERATION');
    var linenum = nlapiGetCurrentLineItemIndex(machinename);
    return nlapiViewLineItemSubrecord(machinename, fldname, linenum);
}

function nlapiViewLineItemSubrecord(machinename, fldname, linenum)
{
    nsapiAssertTrue(isSubrecordField(machinename, fldname),  'SSS_INVALID_FIELD_ON_SUBRECORD_OPERATION');
    var subrecord = NLGetSubRecord(machinename, fldname, linenum);
    return subrecord;
}


function nlapiRemoveCurrentLineItemSubrecord(machinename, fldname)
{
    nsapiAssertTrue(isSubrecordField(machinename, fldname),  'SSS_INVALID_FIELD_ON_SUBRECORD_OPERATION');
    var linenum = nlapiGetCurrentLineItemIndex(machinename);
    var subrecord = NLGetSubRecord(machinename, fldname, linenum);
    if (subrecord)
        subrecord.remove();
}

function nlapiViewSubrecord(fldname)
{
    nsapiAssertTrue(isSubrecordField(null, fldname),  'SSS_INVALID_FIELD_ON_SUBRECORD_OPERATION');
    var subrecord = NLGetSubRecord(null, fldname, 1);  //for body field, there is only one subrecord row, so will be in the first row.
    return subrecord;
}


function nlapiRemoveSubrecord(fldname)
{
    nsapiAssertTrue(isSubrecordField(null, fldname),  'SSS_INVALID_FIELD_ON_SUBRECORD_OPERATION');
    var subrecord = NLGetSubRecord(null, fldname, 1); //for body field, there is only one subrecord, so will be in the first row.
    if (subrecord)
        subrecord.remove();
}

function isSubrecordField(machinename, fldname)
{
    if (typeof(NLGetUIForm) != 'function' || typeof(NLGetBusinessObject) != 'function')
    {
        return false;
    }

    try
    {
        if(isValEmpty(machinename))
        {
            var recordManager= NLGetUIForm() == null ? null : NLGetUIForm().recordManager;
            if(recordManager!=null && recordManager.getField(fldname)!=null)
                return recordManager.getField(fldname)['type'] == "summary";
        }
        else
        {
           var recordManager=NLGetBusinessObject() == null ? null : NLGetBusinessObject().getRecordManager(machinename);
           if(recordManager !=null && recordManager.getField(fldname)!=null)
                return recordManager.getField(fldname)['type'] == 'summary';
        }
    }catch(e)
    {
        return false;
    }
    return false;
}
var nsHeaderPrefix = 'Custom-Header';
var nsScriptErrorMsg = 'An unexpected error occurred in a script running on this page.';
var nsYesString = 'Yes';
var nsNoString = 'No';

