












		

var isIE9 = false;
var isIE10 = false;
var isIE11 = false;

<!-- version 2015.1 -->




function debugAlert(sMsg){}
function debugStartTimer(){}
function debugGetTime(){}



/* The core NetSuite object */
(function(window) {
    /* Sandbox */
    var document = window.document,
        location = window.location,
        navigator = window.navigator;

	var NS = window.NS || {};
	window.NS = NS;

    /*
     *******
     * NetSuite namespace and common functions
     ******
     */
    NS.Core = (function() {
        var guid = 0;

        return {
            getWindow: function() {
                return window;
            },

            getDocument: function() {
                return document;
            },

            getLocation: function() {
                return location;
            },

            getNavigator: function() {
                return navigator;
            },

            isUndefined: function(val) {
                return (typeof val === "undefined");
            },

            getURLParameter: function(param) {
                var val = new RegExp('[?&]' + param + '=([^&]*)').exec(location.search);
                return (val != null) ? decodeURIComponent(val[1]) : null;
            },

            getUniqueId: function() {
                return ++guid;
            }
        };
    }());

    /*
     ********
     * Event bus
     *
     * Example 1:
     *   NS.event.bind("my_event", function() { alert("Triggered"); });         // Bind event listener
     *   NS.event.once("my_event", function() { alert("One-time listener"); }); // Listener that is triggered only once
     *   NS.event.dispatch("my_event");                                         // Trigger event
     *
     * Example 2:
     *   NS.event.bind("my_event", function(e, data) {                          // Bind listener
     *      alert(data.value);                                                  // Output event parameters
     *      if (data.value) { NS.event.unbind(e.name, e.fn); }                  // Conditional unbind
     *   });
     *   NS.event.dispatch("my_event", { value: true });                        // Trigger event with parameters
     *
     * NOTE: Please don't use events in code that may run on the server. Rhino doesn't have a setTimeout function that
     * is essential for asynchronous event dispatching.
     *
     ********
    */
	NS.event = (function() {
		var eventListeners = {};

		/*
		 Event object.

		 name: The name of the event that triggered the handler.
		 fn  : The handler function.
		 */
		function EventObject(name, fn) {
			this.name = name;
			this.fn = fn;
		}

		function ListenerObject(fn, condition, scope) {
			this.fn = fn;
			this.condition = condition;
			this.scope = scope;
		}

		function bindEvent(eventName, fn, condition, scope, once) {
			var listeners, origFn;

			if (!eventListeners[eventName]) {
				eventListeners[eventName] = {};
			}
			listeners = eventListeners[eventName];

			scope = scope || NS.Core.getWindow();
			fn.nsEventGuid = fn.nsEventGuid || NS.Core.getUniqueId();
			origFn = fn;

			if (once) {
				fn = function() {
					delete listeners[fn.nsEventGuid];
					origFn.apply(this, arguments);
				};
				fn.nsEventGuid = origFn.nsEventGuid;
			}
			listeners[fn.nsEventGuid] = new ListenerObject(fn, condition, scope);
		}

		function listenerInvoker(eventName, listener, data) {
			return function () {
				var event = new EventObject(eventName, listener.fn);
				if (!listener.condition || listener.condition.call(listener.scope, event, data)) {
					listener.fn.call(listener.scope, event, data);
				}
			};
		}

		function emptyFunction() {
			return undefined;
		}

		return {
			/*
			 Attach a handler to an event.

			 eventName: The name of the event.
			 callback : Handler that is executed every time the event is triggered. The handler receives two
			 parameters: EventObject and Data. EventObject contains information about the event that
			 triggered the handler and reference to the handler itself. This information can be
			 used, e.g., to unbind the handler. The Data object contains user data passed to the event.
			 [scope]  : Optional. The scope of the handler function. Global scope is used if not defined otherwise.
			 */
			bind: function(eventName, callback, scope) {
				bindEvent(eventName, callback, null, scope, false);
			},

			/*
			 Attach a handler to an event. The handler is executed at most once.

			 eventName   : The name of the event.
			 callback    : Handler that is executed when the event is triggered.
			 [condition] : Optional. If defined the handler is executed only if the condition is true. If the condition
			 returns false the handler remains registered and waits for the next occurence of the event.
			 The condition function is executed with the same parameters as the handler.
			 [scope]     : Optional. The scope of the handler function. Global scope is used if not defined otherwise.
			 */
			once: function(eventName, callback, condition, scope) {
				bindEvent(eventName, callback, condition, scope, true);
			},

			/*
			 Execute all handlers attached to an event. Note that event dispatching is done asynchronously, i.e., the
			 listeners are NOT executed immediately.

			 eventName   : The name of the event.
			 data        : Additional parameters that will be passed to each listener.
			 doneHandler : Callback that is triggered when all event handlers sucesfully finish. May be undefined or null.
			 errorHandler: Callback that is triggered when any of the listeners fails. It is run after all listners for
			 the given event have been executed. May be undefined or null.
			 */
			dispatch: function(eventName, data, doneHandler, errorHandler) {
				var key, listeners, listener, invoker, wrapper;
				var listenersExecuted = 0, listenersFinished = 0, listenersTotal = 0;

				if (eventListeners[eventName]) {
					listeners = eventListeners[eventName];
					listenersTotal = Object.keys(listeners).length;

					for (key in listeners) {
						if (listeners.hasOwnProperty(key)) {
							listener = listeners[key];
							invoker = listenerInvoker(eventName, listener, data);

							wrapper = (function(inner) {
								return function() {
									listenersExecuted++;
									if (listenersExecuted === listenersTotal) {
										setTimeout(function () {
											var finalHandler = ((listenersFinished === listenersTotal) ? doneHandler : errorHandler) || emptyFunction;
											finalHandler();
										}, 0);
									}
									inner();
									listenersFinished++;
								}
							})(invoker);

							setTimeout(wrapper, 0);
						}
					}
				}

				if (listenersTotal === 0 && doneHandler) {
					setTimeout(doneHandler, 0);
				}
			},
			/*
			 Synchronous execution of all handlers attached to an event.

			 eventName   : The name of the event.
			 data        : Additional parameters that will be passed to each listener.
			 doneHandler : Callback that is triggered when all event handlers sucesfully finish. May be undefined or null.
			 errorHandler: Callback that is triggered when any of the listeners fails. It is run after all listners for
			 the given event have been executed. May be undefined or null.
			 */
			dispatchImmediate: function(eventName, data, doneHandler, errorHandler) {
				var key, listeners, listener, invoker, errorEncountered = false;

				if (eventListeners[eventName]) {
					listeners = eventListeners[eventName];

					for (key in listeners) {
						if (listeners.hasOwnProperty(key)) {
							try {
								listener = listeners[key];
								invoker = listenerInvoker(eventName, listener, data);
								invoker();
							} catch (err) {
								errorEncountered = true;
								if (console) {
									console.log(err);
								}
							}
						}
					}
				}

				if (!errorEncountered && doneHandler) {
					doneHandler();
				} else if (errorEncountered && errorHandler) {
					errorHandler();
				}
			},

            /*
                Remove attached event handler.

                eventName: The name of the event.
                callback : The handler function.
             */
            unbind: function(eventName, callback) {
                if (callback.nsEventGuid) {
                    if (eventListeners[eventName]) {
                        delete eventListeners[eventName][callback.nsEventGuid];
                    }
                }
            }
        };
    }());

    /*
     ********
     * Supported event types
     ********
    */
    NS.event.type = {
        FORM_INITED: "formInited",
        FORM_CHANGED: "formChanged",
        FORM_VALID: "formValid",
        PAGE_INIT_FINISHED: "pageInitFinished",
        FIELD_CHANGED: "fieldChanged"
    };

    /*
     *******
     * Form object
     ******
    */
    NS.form = (function() {
        // NS.Core.getWindow().isinited = false;  // Make it undefined temporarily before Selenium tests are fixed
        NS.Core.getWindow().ischanged = false;
        NS.Core.getWindow().isvalid = true;

        return {
            isInited: function() {
                return (NS.Core.getWindow().isinited === true);
            },

            setInited: function(val) {
                if (typeof val === "boolean" && this.isInited() !== val) {
                    NS.Core.getWindow().isinited = val;
                    NS.event.dispatch(NS.event.type.FORM_INITED, {value: val});
                }
            },

            isChanged: function() {
                return NS.Core.getWindow().ischanged;
            },

            setChanged: function(val) {
                if (typeof val === "boolean" && this.isChanged() !== val) {
                    NS.Core.getWindow().ischanged = val;
                    NS.event.dispatch(NS.event.type.FORM_CHANGED, {value: val});
                }
            },

            isValid: function() {
                return NS.Core.getWindow().isvalid;
            },

            setValid: function(val) {
                if (typeof val === "boolean" && this.isValid() !== val) {
                    NS.Core.getWindow().isvalid = val;
                    NS.event.dispatch(NS.event.type.FORM_VALID, {value: val});
                }
            },

            isEditMode: function() {
                return (NS.Core.getURLParameter("e") == "T");
            },

            isViewMode: function() {
                var recordId = NS.Core.getURLParameter("id") || "-1";
                return (!this.isEditMode() && recordId != "-1");
            },

            isNewMode: function() {
                var recordId = NS.Core.getURLParameter("id") || "-1";
                return (!this.isEditMode() && recordId == "-1");
            }
        };
    }());
}(this));  /* Use 'this' instead of 'window' which is not available to server side javascript */




NS.Logger = { debugValue : false };



if (!Array.prototype.push) {
  Array.prototype.push = function() {
		var startLength = this.length;
		for (var i = 0; i < arguments.length; i++)
      this[startLength + i] = arguments[i];
	  return this.length;
  }
}



try{
    parentAccesible =(typeof parent.encode != "undefined");
}catch(e)
{
    parentAccesible = false;
}

function encode(text)
{
    return escape(text).replace(/\+/g, '%2B');
}

function alphafirst(str)
{
    var re = new RegExp("([A-Za-z].*)");
    return (re.exec(str)!=null && RegExp.$1==str);
}


function stacktrace()
{
    var s = "stacktrace: "
    for (var a=arguments.callee.caller; a!=null; a=a.caller)
    {
        s += getFuncName(a);
        s += getFuncArgs(a) + "\n\n";
        if (a.caller == a) break;
    }
    return s;
}

function getFuncArgs(a)
{
    s = "arguments: {";
    for (i = 0; i < a.arguments.length; i++)
    {
        if (typeof a.arguments[i] == "undefined")
            s += '\'undefined\'';
        else if (a.arguments[i] == null)
            s += 'null';
        else if (typeof a.arguments[i] == "string")
            s += "'" + a.arguments[i].toString() + "'";
        else
            s += a.arguments[i].toString();
        if (i < a.arguments.length -1)
            s += ",";
    }
    s += "}";
    return s;
}

function getFuncName(f)
{
    var s = f.toString();
    if (s.indexOf("anonymous") >= 0)
    {
        if (s.length > 100)
            return s.substr(0, 100) + "\n";
        else
            return s + "\n";
    }
    else
    {
        s = s.match(/function[^{]*/);
        if (s !== null)
            s = s[0];
    }
    if ((s == null) || (s.length == 0)) return "anonymous \n";
    return s;
}

function scrollDiv()
{
    if( document.getElementById('div__label') ) document.getElementById('div__label').scrollLeft = document.getElementById('div__body').scrollLeft;
}


function getVisibleWindowHeight()
{
    var isWindowContainedInDivFrame = (window.parentAccesible && typeof parent != "undefined" && typeof parent.Ext != "undefined" && parent.Ext.WindowMgr.getActive()!=null);

    return (isWindowContainedInDivFrame ? parent.Ext.WindowMgr.getActive().body.dom.contentWindow.innerHeight : jQuery(window).height());
}


function getDocumentClientHeight()
{
    var isWindowContainedInDivFrame = (window.parentAccesible && typeof parent != "undefined" && typeof parent.Ext != "undefined" && parent.Ext.WindowMgr.getActive()!=null);
    
       // return document.body.clientHeight;
        return (isWindowContainedInDivFrame ? parent.Ext.WindowMgr.getActive().body.dom.clientHeight : jQuery(document).height());
    
}

function getDocumentClientWidth()
{
    var isWindowContainedInDivFrame = (window.parentAccesible && typeof parent != "undefined" && typeof parent.Ext != "undefined" && parent.Ext.WindowMgr.getActive()!=null);
    
        return (isWindowContainedInDivFrame ? parent.Ext.WindowMgr.getActive().body.dom.clientWidth : jQuery(document).width());
    

}

// Do not use the two functions below to get width and height of document client area
// In IE, the value will not include scroll bar; In FF and Safari, the value will include scrollbar
function getDocumentHeight()
{
    if (window.innerHeight)
        return window.innerHeight;
    else if (document.documentElement && document.documentElement.clientHeight && document.documentElement.clientHeight != 0)
        return document.documentElement.clientHeight;
    else 
        return document.body.clientHeight;
}
function getDocumentWidth()
{
    if (window.innerWidth)
        return window.innerWidth ;
    else if (document.documentElement && document.documentElement.clientWidth && document.documentElement.clientWidth != 0)
        return document.documentElement.clientWidth;
    else  
        return document.body.clientWidth;
}

function getWindowPageXOffset()
{
	return (window.pageXOffset !== undefined) ? window.pageXOffset : (document.documentElement || document.body.parentNode || document.body).scrollLeft;
}

function getWindowPageYOffset()
{
	return (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
}


function getElementContentWidth(element)
{
    return  element.offsetWidth
            - getRuntimeSize(element, "paddingLeft")
            - getRuntimeSize(element, "paddingRight")
            - getRuntimeSize(element, "borderLeftWidth")
            - getRuntimeSize(element, "borderRightWidth")
            - getRuntimeSize(element, "marginLeft")
            - getRuntimeSize(element, "marginRight") ;
}


function getElementContentHeight(element)
{
    return element.offsetHeight
            - getRuntimeSize(element, "paddingTop")
            - getRuntimeSize(element, "paddingBottom")
            - getRuntimeSize(element, "borderTopWidth")
            - getRuntimeSize(element, "borderBottomWidth")
            - getRuntimeSize(element, "marginTop")
            - getRuntimeSize(element, "marginBottom") ;
}


var ieDiffWidth=0;
var ieDiffHeight=0;

function initOuter() {

  var w, h, offW, offH, diffW, diffH;
  var fixedW = 800;
  var fixedH = 600;
  if (document.all) {
    offW = document.body.offsetWidth;
    offH = document.body.offsetHeight;
    window.resizeTo(fixedW, fixedH);
    diffW = document.body.offsetWidth  - offW;
    diffH = document.body.offsetHeight - offH;
    w = fixedW - diffW;
    h = fixedH - diffH;
    ieDiffWidth  = w - offW;
    ieDiffHeight = h - offH;
    window.resizeTo(w, h);
  }
}

function outerWd() {

  if (document.all)
  {
    if (ieDiffHeight==0) initOuter();
    return document.body.offsetWidth  + ieDiffWidth;
  }
  else
    return window.outerWidth;
}

function outerHt() {

  if (document.all)
  {
    if (ieDiffHeight==0) initOuter();
    return document.body.offsetHeight  + ieDiffHeight;
  }
  else
    return window.outerHeight;
}

function onBeforePrint()
{
    var t= document.getElementById('div__label');
    if (t != null)
    {
        t.style.width = null ;
        t.style.height = null;
    };
    t = document.getElementById('div__body');
    if (t != null)
    {
        t.style.width = null;
        t.style.height = null;
    }

    document.body.scroll = 'auto';
}
function onAfterPrint()
{
    
    if(document.getElementById("resetdivwascalled") != null)
        resetDivSizes();
}


window.onbeforeprint = onBeforePrint;
window.onafterprint = onAfterPrint;


function getNavTreePaneDivID()
{
    return 'div__nav_tree';
}

function resetDivSizes()
{
    if (typeof(ignoreResetDivSizes) != 'undefined' && ignoreResetDivSizes)
    {
        return;
    }

    
    if(document.getElementById("resetdivwascalled") == null)
    {
        var hasBeenCalled = document.createElement("input");
        hasBeenCalled.type = "hidden";
        hasBeenCalled.value = "T";
        hasBeenCalled.id = "resetdivwascalled";
        document.body.appendChild(hasBeenCalled);
    }

    var header = document.getElementById('div__header');
    var title = document.getElementById('div__title');
    var banner = document.getElementById('div__banner');
    var messsageBox = document.getElementById('div__alert');
    var prelabel = document.getElementById('div__prelabel'); 
    var label = document.getElementById('div__label'); 
    var list = document.getElementById('div__body');
    var nav = document.getElementById( 'div__nav');
    var footer = document.getElementById('div__footer');

    
    var newElementsHeight = 0;
    var newTitleArea = jQuery(".pt_container").get(0);
    if (newTitleArea)
    {
        newElementsHeight += getHeight(newTitleArea) + 30; 
    }

    var controlbarHeight = 0;
    var controlBar = jQuery(".uir_control_bar").get(0);
    if (controlBar)
    {
        newElementsHeight += getHeight(controlBar) + 25;
    }

	
	var topBanner = document.getElementById('bannerContainer');
    var topBannerHeight = getHeight(topBanner);
    if (topBannerHeight > 0)  
    	topBannerHeight += 5;

    if (list == null)
        return; 

    // we never want vertical scroll bars, but horizontal scroll bars are ok if necessary
    // There should never be Y-overflow since we are sizing all of the elements to fit and scrolling individually
    document.body.style.overflowY = "hidden";

    
    if (footer != null)
    {
        var childnodes = footer.childNodes;
        for(var i = 0; i < childnodes.length; i++)
        {
            var tableFooter = childnodes[i];
            
            if(tableFooter.tagName == "TABLE")
            {
                document.body.style.overflow =
                    (tableFooter.scrollWidth > document.body.clientWidth) ? "-moz-scrollbars-horizontal" : "-moz-scrollbars-none";
                break;
            }
        }
    }
    

    
    var nHeight = getDocumentHeight() - 10;
    nHeight -= topBannerHeight + getHeight(header) + getHeight(footer) + getHeight(title) + getHeight(banner)+ getHeight(prelabel)+ getHeight(label) + getHeight(messsageBox) + 25 + newElementsHeight;
    list.style.height = ( nHeight > 0 ? nHeight : 0) + "px";
    
    list.clientWidth;
    
    
    var docwidth = getDocumentWidth();
    var reportDataTable = document.getElementById('_rptdata');
    if ( nav != null )
    {
        list.style.height = ( nHeight - list.offsetTop > 0 ? nHeight - list.offsetTop : 0) + "px";
        var tree = document.getElementById('div__nav_tree');
        if (tree)
            tree.style.height = ( nHeight - tree.offsetTop > 0 ? nHeight - tree.offsetTop : 0 ) + "px";

        docwidth -= isIE ? nav.offsetWidth : nav.scrollWidth;

        
        var node = nav.parentNode;
        var cellSpacing = 0;
        while (node != null)
        {
            if (node.getAttribute("cellspacing"))
            {
                cellSpacing = node.getAttribute("cellspacing");
                break;
            }
            node = node.parentNode;
        }
        docwidth -= 4*cellSpacing;
    }
    
    list.style.width = Math.max( docwidth-18, 0 ) + "px";

    
    nHeight = getDocumentHeight() - 10;
    nHeight -= topBannerHeight + getHeight(header) + getHeight(footer) + getHeight(title) + getHeight(banner) + getHeight(prelabel) + getHeight(label) + getHeight(messsageBox) + 25 + newElementsHeight;
    list.style.height = ( nHeight > 0 ? nHeight : 0) + "px";
    if ( nav != null )
    {
        list.style.height = ( nHeight - list.offsetTop > 0 ? nHeight - list.offsetTop : 0) + "px";
        var tree = document.getElementById('div__nav_tree');
        if (tree)
            tree.style.height = ( nHeight - tree.offsetTop > 0 ? nHeight - tree.offsetTop : 0 ) + "px";
    }
    
    if (label != null )
    {
        label.style.width = list.clientWidth + "px";
        label.style.left = -document.getElementById('div__body').scrollLeft + "px";
    }

    
    
    if( reportDataTable )
    {
        var labtab = document.getElementById('div__labtab');
        labtab.style.width = reportDataTable.clientWidth + "px";
    }
    

    
    var bFirst = true;
    var lastCol;
    var lastWidth;
    for (var i=0; i==0 || document.getElementById('div__labcol'+i) != null; i++)
    {
        var col = document.getElementById('div__labcol'+i);
        var lab = document.getElementById('div__lab'+i);
        if (lab != null)
        {
            var width = col.offsetWidth;
            if (bFirst && width > 0)
            {
                bFirst = false;
                width--;
            }
            if (width > 0)
            {
                lastCol = lab;
                lastWidth = width;
            }
            if ( lab.tagName == 'TD' )
            {
                lab.style.width = width + "px";
            }
            else
            {
                lab.offsetParent.style.width = width + "px";
            }
        }
    }
    if (lastCol && lastWidth > 0)
        lastCol.style.width = lastWidth - 1 + "px";

    
    makeVisible(label);
    makeVisible(list);
    makeVisible(footer);

    
    var paddingCell = document.getElementById("div__labend");
    if (paddingCell)
    {
        paddingCell.style.width = list.offsetWidth - list.clientWidth + "px";
        if (label)
	        paddingCell.style.height = label.offsetHeight + "px";
        paddingCell.style.left = list.clientWidth - 1 + "px";
    }

    hideInvisibleRows();
}



function hideInvisibleRows()
{
    var div = document.getElementById("squeezeBox");
    if (div == null)
        return;
    var trs = div.getElementsByTagName("tr");
    var hiddenHeight = 0;
    for (var i=0; i < trs.length; i++)
    {
        
        if (trs[i].className == "labelRow" && isValEmpty(trs[i].getAttribute("squeezeBox")) )
        {
            hiddenHeight += trs[i].offsetHeight + 1;
            trs[i].setAttribute("squeezeBox","T");
        }
    }
    if (hiddenHeight > 0)
    {
        div.style.overflow = "hidden";
        div.style.height = div.offsetHeight - hiddenHeight + (isIE ? 0 : 28) + "px";
    }
}



function resizePopupWindow()
{
    var list = document.getElementById('div__body');
    if (list == null)
        return; 
    var docwidth = getDocumentWidth()-10;
    var maxspanwidth = getMaxContentWidth(list.getElementsByTagName("span"));
    var maxdivwidth = getMaxContentWidth(list.getElementsByTagName("div"));
    var maxwidth = Math.max(list.scrollWidth,Math.max(maxspanwidth,maxdivwidth));
    
    if ( maxwidth > docwidth )
        window.resizeBy(maxwidth -docwidth,0);
}

function getMaxContentWidth(elems)
{
    var size = 0;
    for ( i = 0; i < elems.length; i++ )
    {
        if ( elems[i].scrollWidth > size )
            size = elems[i].scrollWidth;;
    }
    return size;
}


function getHeight(elem)
{
    if (elem == null)
        return 0;
    else
        return elem.offsetHeight ? elem.offsetHeight : 0;
}

function makeVisible(elem)
{
    if (elem != null)
        elem.style.visibility = 'visible';
}

function visible(elem, on )
{
    if (elem != null)
        elem.style.visibility = on ? 'inherit' : 'hidden';
}



function endsWith(str, token)
{
	return str != null && token != null && str.length >= token.length && str.substr(str.length-token.length) == token;
}

function checkzipcode(f, bIsCanada)
{
  var v = f.value;
  var n = bIsCanada ? 6 : 5;
  if(!onlydigits(f) || v.length != n)
  {
    if ( bIsCanada )
        alert('Please enter a valid '+n+' digit Postal Code.');
    else
        alert('Please enter a valid '+n+' digit Zip Code.');
    return false;
  }
  return true;
}

function splitIntoRows( value )
{
    return value != null ? (value.length > 0 ? value.split(String.fromCharCode(2)) : new Array()) : null;
}
function splitIntoCells( value )
{
    return value != null ? (typeof(value) == 'string' ? value.split(String.fromCharCode(1)) : value) : null;
}


function isempty(fld1,nam)
{
	var val = fld1.value;
    return isValEmpty(val,nam);
}


function checknotempty(fld1,nam)
{
    if (!checkvalnotempty(fld1.value, 'Please enter a value for {1}'.replace('{1}',nam)))
    {
        try {
            fld1.focus();
            fld1.select();
        } catch (e) { }
        return false;
    }

    return true;
}

function amount_string(amount)
{
    var cents = Math.floor((amount-Math.floor(amount))*100+0.5);
    var centstring = (cents < 10) ? '0'+cents.toString() : cents.toString();
    var dollarstring = dollars_string(Math.floor(amount));
    return dollarstring.charAt(0).toUpperCase() + dollarstring.substr(1) + 'and ' + centstring + '/100';
}
function format_rate(a,p)
{
    var returnMe;
    if (isNaN(parseFloat(a)))
    {
        returnMe= '';
    }
    else
    {
    	var precision = get_precision();
                                               
    	if (precision>1 || p)
    	{
            var s=(a<0);
            if (s) a=-a;
            var d=Math.floor(a);
            var c=Math.floor((a-d)*(p?10:100)+0.5);
                             
            if (a == d+c/(p?10:100))
            {
                if (c==(p?10:100)) {d++;c=0;}
                var cs=p?c.toString():((c < 10)?'0'+c.toString():c.toString());
                returnMe = (s?'-':'')+d.toString()+'.'+cs+(p?'%':'');
           }
            else
              returnMe = (s?'-':'')+a+(p?'%':'');
        }
        else if (precision==1)
        {
            var s=(a<0);
            if (s) a=-a;
            var cs = a.toString();
            var n = cs.indexOf('.');
            if (n==-1) cs = cs.toString() + '.0';
            else if (n==0) cs = '0.' + cs.toString() ;
            else if (n==cs.length-1) cs = cs.toString() + '0' ;
      		returnMe = (s?'-':'') + cs ;
        }
        else if (precision==0)
        {
            var s=(a<0);
            if (s) a=-a;
            var cs = a.toString();
            var n = cs.indexOf('.');
            if (n==0) cs = '0.' + cs.toString() ;
            else if (n==cs.length-1) cs = cs.substring(0, cs.length-2);
      		returnMe = (s?'-':'') + cs ;
        }
    }
  return returnMe;
}
function get_precision()
{
var cp = getFormElementViaFormName('main_form', 'currencyprecision');
    var precision = 2;
    if (cp != null) 
    {
  	  var tprecision = parseFloat(cp.value);
      if (!isNaN(tprecision))
      {
          precision=tprecision;
      }
    } 
    return precision;
}
function round_currency(amount, numofdecimals, method)
{
var TEN_POWER_TABLE=[1.0, 10.0, 100.0, 1000.0, 10000.0, 100000.0, 1000000.0, 1.0E7, 1.0E8, 1.0E9, 1.0E10, 1.0E11, 1.0E12, 1.0E13, 1.0E14, 1.0E15, 1.0E16, 1.0E17, 1.0E18, 1.0E19, 1.0E20, 1.0E21, 1.0E22, 9.999999999999999E22, 1.0E24, 1.0E25, 1.0E26, 1.0E27, 1.0E28, 1.0E29];
function shouldRoundUp (absNum, floor, ceil, tolerance, multiplicator, roundingMode)
{
	switch (roundingMode)
	{
		case 'UP':
			return absNum > floor / multiplicator + tolerance;
		case 'DOWN':
			return absNum >= ceil / multiplicator - tolerance;
		default:
			return absNum >= (floor + 0.5) / multiplicator - tolerance;
	}
}
function roundDouble(num, digits, tolerance, roundingMode)
{
	if (!isFinite (num))
		return num;
	var signum = (num >= 0) ? +1 : -1
	var absNum = Math.abs (num);
	var multiplicator = TEN_POWER_TABLE[digits];
	var multipliedAbsNum = multiplicator * absNum;
	var floor = Math.floor (multipliedAbsNum);
	var ceil = Math.ceil (multipliedAbsNum);
	var roundUp = shouldRoundUp (absNum, floor, ceil, tolerance, multiplicator, roundingMode);
	var multipliedResult = (roundUp) ? ceil : floor;
	var result = signum * multipliedResult / multiplicator;
	return (result == -0.0) ? 0.0 : result;
}
  var precision = numofdecimals;
  if (precision==null) 
    precision = get_precision();
  var tolerance = Math.min (5.0E-6 / TEN_POWER_TABLE[precision], 5.0E-10)
  return roundDouble(amount, precision, tolerance, method);
}
function round_float(a)
{
  return round_float_to_n_places(a,8);
}
function round_float_to_n_places(a,n)
{
  var str = a + '';
  if(str.indexOf('.') < 0)
    return a;
  if(str.length-str.indexOf('.')-1 <= n)
    return a;
  var b = Math.abs(a);
  b = b + 0.00000000000001;
  var factor = Math.pow(10,n);
  b = Math.floor((b * factor)+0.5) / factor;
  b = b * (a >= 0.0 ? 1.0 : -1.0);
  if( b == 0.0 )
    return 0.0;
  return b;
}
function pad_to_atleast_two_decimal_places(a)
{
  var s;
    if(a == null)
    {
       s = '';
    }
  else
  {
    s = a.toString();
    var n = s.indexOf('.');
    if(n == -1)
    {
      s = s + '.00';
    }
    else if(n == s.length-1)
    {
      s = s + '00';
    }
    else if(n == s.length-2)
    {
      s = s + '0';
    }
    if (n == 0)
    {
      s = '0' + s;
    }
  }
  return s;
}
function pad_decimal_places(a, noOfDecimalPlaces)
{
  var s;
  if(a == null)
  {
     s = '';
  }
  else
  {
    s = a.toString();
    var n = s.indexOf('.');
    if (noOfDecimalPlaces==0) 
    {
      if(a == 0.0)
      {
        s = 0; 
      }
      else if(n > -1)
      {
        s = s.substring(0, n) ;
      } 
    }
    else if (noOfDecimalPlaces==1) 
    {
      if(n == -1)
      {
        s = s + '.0';
      }
      else if(n == s.length-1)
      {
        s = s + '0';
      } 
      else if (n == 0)
      {
        s = '0' + s;
      }
    }
    else
    {
      if(n == -1)
      {
        s = s + '.00';
      }
      else if(n == s.length-1)
      {
        s = s + '00';
      }
      else if(n == s.length-2)
      {
        s = s + '0';
      }
      if (n == 0)
      {
        s = '0' + s;
      }
    }
  }
  return s;
}
function format_currency(a, bDoNotRound)
{
if(isNaN(a))
{
    return '';
}
var cp = getFormElementViaFormName('main_form', 'currencyprecision');
  var noOfDecimalPlaces = 2;
  if (cp != null) 
  {
  	noOfDecimalPlaces = parseFloat(cp.value);
    if (isNaN(noOfDecimalPlaces))
    {
        noOfDecimalPlaces = 2;
    }
  } 
var returnMe;
if( !(bDoNotRound == true)) 
{
    returnMe = round_currency(a, noOfDecimalPlaces);
}
else
{
    returnMe = a;
}
returnMe = pad_decimal_places(returnMe, noOfDecimalPlaces);
return returnMe;
}
function format_currency2(n)
{
  if(isNaN(n))
  {
    return '';
  }
  var returnMe;
  if( (n+'').indexOf('.') < 0 )
    returnMe = n;
  else
    returnMe = round_float_to_n_places(n,8);
  var precision = get_precision();
  if (precision == 2) {
    returnMe = pad_to_atleast_two_decimal_places(returnMe);
  } 
  return returnMe;
}
function format_percent(p) {
  if(typeof p == 'string')
     p = parseFloat(p);
 return p+(p==Math.floor(p) ? '.0%' : '%'); }
function process_currency_field_value(value, fieldType) {
    if (fieldType == null || fieldType.indexOf('currency') == -1)
        return value;
    if (isValEmpty(value) || ('' + value).indexOf('.') != -1 || isNaN(parseFloat(value)))
        return value;
    var precision = fieldType.indexOf('currency2') >= 0 ? 2 : get_precision();
    return pad_decimal_places('' + value, precision);
}





function parseCJKNumbers(field)
{
	var val = field.value;
    if (val == null) return null;
	var re = /[\uff01-\uff5e]/g;
	var out = [];
	var m , last = 0;
	re.lastIndex = 0; 
	while ((m = re.exec(val)) != null)
	{
		if (m.index > last) out.push(val.substring(last, m.index));
		last = re.lastIndex;
		out.push(String.fromCharCode(m[0].charCodeAt(0) - 0xfee0));
	}
	if (last == 0) return val;
	if (last < val.length) out.push(val.substring(last));
	return out.join('');
}


function validate_textfield_maxlen(field, maxLen, bAlert, bMaxInChars)
{
	if (field.value == null || field.value.length == 0)
	{
		NS.form.setValid(true);
		return true;
	}
	var bValid = true, truncOffset = null;
	if (bMaxInChars)
	{
        
		var len = field.value.replace(/\r/g, '').replace(/\n/g, '\n ').length;
		if (len > maxLen)
		{
			if (bAlert)
				alert('You have exceeded the '+maxLen+' character limit for this field. Please shorten your entry by '+(len-maxLen)+' characters.');
			truncOffset = getIndexForSelection(field.value, maxLen);
		}
	}
	else
	{
		var toTrim = analyzeUTF8(field.value, maxLen);
		if (toTrim)
		{
			if (bAlert)
				alert('You have exceeded the length limit for this field. Please shorten your entry by '+toTrim+' characters.');
			truncOffset = UTF8toUTF16index(field.value, maxLen);
		}
	}
	if (truncOffset)
	{
		window.focusedTextArea = field;
		setTimeout("try { setSelectionRange(window.focusedTextArea, " + truncOffset + ", " + field.value.length + "); } catch (e) {}",0);
		bValid = false;
	}
	NS.form.setValid(bValid);
	return bValid;
}


function getIndexForSelection(str, index)
{
    var text = str.replace(/\r/g, '');
    var length = 0;
    for (var i=0; i<text.length; ++i)
    {
        var chnum=text.charCodeAt(i);
        if (chnum == 10) // new line is considered as two characters.
        {
            length++;
        }
        length++;
        if (length > index)
            return i;
    }
    return 0;
}
function truncateStringInUnicode(str, maxlen)
{
    var totalnum = 0;
    var sLower = 128;
    var sHigher = 2048;
    var strOut = "";
    for (var i=0; i < str.length; i++ )
    {
        var chnum = str.charCodeAt(i);
        if ( chnum < sLower )
            totalnum += 1;
        else if ( chnum >= sLower && chnum < sHigher )
            totalnum += 2;
        else if ( chnum >= sHigher )
            totalnum += 3;
        if ( totalnum < maxlen )
            strOut = strOut + str.charAt(i);
    }
    return strOut;
}
function UTF8toUTF16index(str, utf8index)
{
    str = str.replace(/\r/g, '');
    var utf8len = 0;
    var sLower = 128;
    var sHigher = 2048;
    for (var i=0; i<str.length; ++i)
    {
        var chnum=str.charCodeAt(i);
        if (chnum == 10) // new line is considered as two characters.
        {
            utf8len += 2;
        }
        else if (chnum < sLower)
            utf8len += 1;
        else if (chnum < sHigher)
            utf8len += 2;
        else
            utf8len += 3;
        if (utf8len > utf8index)
            return i;
    }
    return 0;
}

function lengthInUTF8Bytes(str) {
    
    return encodeURIComponent(str.replace(/\r/g, '')).replace(/%0A/g, 'UU').replace(/%[A-F\d]{2}/g, 'U').length;
}

function analyzeUTF8(str, maxByteLen)
{
    var lengthInBytes = lengthInUTF8Bytes(str);
    var excessBytes = lengthInBytes - maxByteLen;
    if(excessBytes > 0) {
        var coef = lengthInBytes / str.length; 
        return Math.round(excessBytes / coef);
    }
    return 0;
}

function searchMonth(str, fullName) {
    var tmp_str = str.toLowerCase();
    var months = new Array();
    if (fullName) {
        months = ["january", "february", "march", "april", "may", "june", "july",
                  "august", "september", "october", "november", "december"];
    } else {
        months = ["jan", "feb", "march", "april", "may", "june", "july",
                  "aug", "sept", "oct", "nov", "dec"];
    }
    var idx = 0;
    for(var i = 0; i < months.length(); i++) {
        idx = tmp_str.indexOf(months[i], 0);
        if (idx >= 0) {
            idx = idx + months[i].length;
            while (str.charAt(idx) == ' ')
              idx ++;
            return idx;
        }
    }
    return -1;
}

function getTimeStartIdx(str)
{
    var n = 0, spaceIdx= 0;
    if (window.dateformat == "DD de MONTH de YYYY") {
        spaceIdx = str.lastIndexOf("de", 0);
        n = 2;
    }
    else if (window.dateformat == "DD MONTH, YYYY") {
        spaceIdx = str.indexOf(",", 0);
        n = 2;
    }
    else if (window.dateformat == "DD-MONTH-YYYY") {
        spaceIdx = str.lastIndexOf("-", 0);
        n = 1;
    }
    else if (window.dateformat == "DD MONTH YYYY") {
        spaceIdx = searchMonth(str, true);
        n = 1;
    }
    else if (window.dateformat == "DD. Mon YYYY") {
        spaceIdx = searchMonth(str, false);
        n = 1;
    }
    else if (window.dateformat == "YYYY년 MM월 DD?") {
        spaceIdx = 0;
        n = 3;
    } else {
        spaceIdx = 0;
        n = 1;
    }

    for (var i = 0; i < n; ++i) {
        spaceIdx = str.indexOf(" ", spaceIdx + 1);
        if (spaceIdx < 0)
          break;
    }
    return spaceIdx;
}

function extract_date_time(str, doalert)
{
    var date_time = new Array();
    var tmp_str = trim(str);
    var spaceIdx = getTimeStartIdx(str);
    if (spaceIdx > 0) {
        var date_str = tmp_str.substring(0, spaceIdx);
        var time_str = tmp_str.substring(spaceIdx+1, tmp_str.length);
        return { validflag:true, date:date_str, time: trim(time_str)};
    } else
    {
        alert("Invalid date/time (miss spaces between date and time)");
    }
    return { validflag:false };
}

function validate_date(fldvalue, doalert)
{
    var dt = NLDate_parseString(fldvalue, doalert);
    var ret;
    if(dt == null)
    {
        ret = { validflag:false }
    }
    else
    {
        ret = { validflag:true, value: getdatestring(dt) };
    }
    return ret;
}

function validate_time(fldvalue, doalert, includeSeconds)
{
    
    var fldvalue = hhmmtotimestring( fldvalue );
    var time;
    if (includeSeconds)
       time = regexstringtotime(null, fldvalue, includeSeconds);
    else
       time = stringtotime(null, fldvalue);
    
    var validflag = !isNaN(time);
    var value;
    if (validflag)
    {
        if (includeSeconds)
           value = gettimewithsecondsstring(time, window.datetime_am_string, window.datetime_pm_string);
        else
           value = gettimestring(time, window.datetime_am_string, window.datetime_pm_string);
    }
    else if (doalert)
    {
        alert("Invalid time value");
    }
    return {validflag:validflag, value:value};
}
        
function checkForQuirks(type, value)
{
    var quirkText = "";
    switch(type)
    {
        case "mmdddate":
        case "visiblepassword":
        case "printerOffset":
        case "metricPrinterOffset":
            quirkText = "Field Type Actually used!";
            break;

        case "integer":
        case "posinteger":
        case "float":
        case "posfloat":
        case "nonnegfloat":
            if (value.indexOf("%") >= 0)
                quirkText = "% found in non-percent type";
            break;

        case "currency":
        case "currency2":
        case "poscurrency":
            if (value.substring(1).search(/[\+\-\*\/]/g) >= 0)
                quirkText = "Equation detected";
            break;

        default:
            return;
    }

    if (quirkText !== "")
        makeValidationQuirkLog(type, value, quirkText)
}

function makeValidationQuirkLog(type, value, description)
{
    nsServerCall(nsJSONProxyURL, "logValidationQuirk", [type, value, description]);
}

function validate_field(field, type, doalert, autoplace, minval, maxval, mandatory, separator)
{
    if ((typeof validationFlowSwitch !== "undefined") && validationFlowSwitch.usesNewPath)
    {
        var endedWithPercent = ("" + field.value).slice(-1) === "%";
        var validateMe = nlapi.util.formatter.parse(field.value, type, isNumericField(field), isCurrencyField(field), null, autoplace);
        try
        {
            nlapi.util.validator.validateField(field.name, type, validateMe, isNumericField(field), isCurrencyField(field), null, minval, maxval, null, mandatory);
        }
        catch (e)
        {
            alert(e.message);
            return false;
        }
        finally
        {
            field.value = nlapi.util.formatter.format(validateMe, type, isNumericField(field), isCurrencyField(field), endedWithPercent);
        }
        return true;
    }
    else
    {
        return old_validate_field(field, type, doalert, autoplace, minval, maxval, mandatory, separator);
    }
}

function old_validate_field(field, type, doalert, autoplace, minval, maxval, mandatory, separator)
{
    // Issue 233790 - validation alert in IE fires an additional blur event which results in another validation alert
    if (field.hasOwnProperty("validationLimit"))
    {
        if (field.validationLimit > 0)
            field.validationLimit--;
        else return false;
    }

    
    NS.form.setValid(false);
    type = type.toLowerCase();
    if (field.value == null || field.value.length == 0)
    {
        if (mandatory)
        {
            if (doalert) alert("Field must contain a value.");
            selectAndFocusField(field);
            NS.form.setValid(false);
            return false;
        }
        else
        {
            NS.form.setValid(true);
            return true;
        }
    }
    checkForQuirks(type, field.value);
    if ( (type != "text" && type != "identifier" && type != "identifieranycase" && type != "address" && type != "visiblepassword") &&
		 ("en" == "ja" || "en" == "ko" || "en" == "zh") )
        field.value = parseCJKNumbers(field);
    var validflag = true;
    if (type =="url")
    {
        var val = trim(field.value.toLowerCase());
        
        
        if (!(val.indexOf('/') == 0 || val.indexOf('http://') == 0 || val.indexOf('https://') == 0 || val.indexOf('ftp://') == 0 || val.indexOf('file://') == 0))
        {
            
            if (val.indexOf('://') != -1)
            {
                if (doalert)
                    alert("Invalid url. Url must start with http://, https://, ftp://, or file://");
                validflag = false;
            }
            else
            {
                makeValidationQuirkLog(type, field.value, "HTTP prepended");
                field.value = 'http://' + trim(field.value);
        }
        }
        
        if ( val.indexOf( ' ' ) > 0 || val.indexOf( '\t' ) > 0 )
        {
            if (doalert)
                alert("Invalid url. Spaces are not allowed in the URL");
            validflag = false;
        }
    }
    else if (type == "currency" || type == "currency2" || type == "poscurrency")
    {
        var val = field.value.replace(/$/g,"");

        val = val.toLowerCase();
        if(val.charAt(0) == '=')
            val = val.substr(1);
        else if (val.substr(1).search(/[\+\-\*\/]/g) == -1)
            val = NLStringToNumber(val, true) + '';

        

        if (val.substr(1).search(/[\+\-\*\/]/g) != -1)
        {
            
            // normalize the string for the group separator and decimal separator, so that  the string is ready to be eval'ed.
            if(window.groupseparator && window.decimalseparator)
                val = val.replace(new RegExp( '\\' + window.groupseparator, 'g'), '').replace(new RegExp( '\\' + window.decimalseparator, 'g'), '.');
            var c = val.charAt(0);
            if(val.charAt(0) >='a' && val.charAt(0) <='z')
            {
                value = "error";
            }
            else
            {

                
                try {
                    val = eval(val);
                } catch (e) { val = "error"; }
                autoplace = false;
            }
        }
        numval = parseFloat(val);
        var totalDigitCount = getTotalDigitCount(val);
        if (isNaN(numval))
        {
			if (doalert)
			   alert('Invalid currency value. Values must be numbers up to 999,999,999,999,999.99');
			validflag = false;
        }
        else if ( maxval != null && !isNaN(maxval) && Math.abs(numval)>=maxval )
        {
			if (doalert)
			{
                var regex  = new RegExp('(-?[0-9]+)([0-9]{3})');
                var preDecimal = (maxval-1).toString();
                while(regex.test(preDecimal))
                {
                   preDecimal = preDecimal.replace(regex, '$1' + ',' + '$2');
                }
                alert('Invalid currency value. Values must be numbers up to '+preDecimal+'.999999999999999'+'');
            }

    		validflag = false;
		}
        
        if ((type == "poscurrency" || minval == 0) && numval < 0)
        {
            if (doalert) alert("Invalid currency value. Value can not be negative.");
            validflag = false;
        }
        if (type == "poscurrency" && numval === 0 && validflag)
            makeValidationQuirkLog(type, field.value, "poscurrency accepted 0");

        if (validflag)
        {
            

            if(autoplace && window.decimalseparator && field.value.indexOf(window.decimalseparator) == -1) numval/=100;
            if(type == "currency" || type == "poscurrency")
                val =format_currency(numval);
            else
                val = format_currency2(numval);
            if (isNLNumericOrCurrencyDisplayField(field))
                val = NLNumberToString(val);
            field.value = val;
        }
    }
    else if (type == "date")
    {
        var ret = validate_date(field.value, doalert);
        validflag = ret.validflag;
        if (validflag)
           field.value = ret.value;
        /*
        var dt = NLDate_parseString(field.value, doalert);

        if(dt == null)
        {
            validflag = false;
        }
        else
        {
            validflag = true;
            field.value = getdatestring(dt);
        }
        */        
    }
    else if (type == "mmyydate")
    {
        // try to read year and month from the field
        var value;
        try
        {
            value = parseMMYYDateString(field.value);
        }
        catch(e) {}

        // check its validity
        if (value != null && value.month >= 1 && value.month <= 12 && value.year > 1900 && value.year < 2100)
        {
			var dDate = validateDate(new Date(value.year, value.month-1), doalert);
			if (dDate)
			{
				field.value = getmmyydatestring(dDate, NLDate_short_months);
                validflag = true;
            }
            else
		    	validflag = false;
		}
        else
        {
            // invalid => show error with suggested date pattern
            var fmterr =  "MMYY, MMYYYY, ";
            if (window.dateformat == "DD-Mon-YYYY")
                fmterr += "Mon-YY, Mon-YYYY";
            else if (window.dateformat == "DD.MM.YYYY")
                fmterr += "MM.YY, MM.YYYY";
            else
                fmterr += "MM/YY, MM/YYYY";

            if (doalert) alert('Invalid date value (must be '+fmterr+')');
            validflag = false;
        }
    }
    else if (type == "mmdddate")
    {
    
        // try to read day and month from the field
        var value;
        try
        {
            value = parseMMDDDateString(field.value);
        }
        catch(e) {}

        // check its validity
        if (value != null && value.month >= 0 && value.month <= 11 && value.day >= 1 && value.day <= 31)
        {
            var dDate = validateDate(new Date(1970, value.month, value.day), doalert);
            if (dDate)
            {
                validflag = true;
            }
            else
            {
                validflag = false;
                // invalid => show error
                if (doalert) alert('Please enter a valid Start Date in MM/DD format.');
            }
        }
        else
        {
            // invalid => show error
            if (doalert) alert('Invalid date value (must be MM/DD)');
            validflag = false;
        }
    }
    else if (type == "ccexpdate" || type == "ccvalidfrom")
    {
        

        validflag = true;
        var m=0, y=0;
        if(field.value.indexOf('/') != -1)
        {
            var dToday = new Date();
            var Y = dToday.getFullYear();
            var M = dToday.getMonth() + 1;
            if(Y <= 999) Y += 1900;         

            var c = field.value.split('/');
            if(onlydigits(c[0])) m = parseInt(c[0],10);
            if(onlydigits(c[1])) y = parseInt(c[1],10);

            if(m<1) m=1; else if(m>12) m=12;
            if(y<100) y+=((y>=70)?1900:2000);

            
            if(type == "ccexpdate" && (y < Y || (y==Y && m < M)) ||
               type == "ccvalidfrom" && (y > Y || (y==Y && m > M)))
            {
                if (doalert) alert("Notice: The credit card appears to be incorrect");
            }
            field.value = (m<10?'0':'')+m+'/'+y;
        }
        else
        {
            if (doalert)
            {
                if (type == "ccexpdate") alert("Please enter an expiration date in MM/YYYY format");
                else alert("Please enter a Valid From / Start Date in MM/YYYY format");
            }
            validflag = false;
        }
    }
    else if (type == "ccnumber") 
    {
		validflag = (field.value.length > 4 &&
						field.value.substring(0, field.value.length-4).replace(new RegExp( "\\*", "g" ), '').length == 0 &&
						field.value.substring(field.value.length-4).replace(new RegExp( "\\*", "g" ), '').length == 4) || checkccnumber(field);
    }
    else if (type == "rate" || type == 'ratehighprecision')
    {
        var numval;

        var val = field.value;
        var pctidx = val.lastIndexOf("%");
        var isPct = (pctidx!=-1);
        if (isPct)
            val = val.substr(0,pctidx);

        numval = NLStringToNumber(val, true);
        if (isNaN(numval))
        {
            if (doalert) alert("Invalid number or percentage");
            validflag = false;
        }
        else
        {
            if (autoplace && !isPct && val.indexOf(".") == -1)
                numval/=100;
            var numstr = format_rate(numval, isPct);  // this is the normalized rate string, i.e. using standard number formatting
            if (isNLNumericOrCurrencyDisplayField(field))
            {
                numstr = NLNumberToString(numstr.replace('%',''));
                if(isPct && numval < 0 && numstr.indexOf('-') < 0)  //other formats used for negative number
                {
                    var positiveNumberStr = NLNumberToString(format_rate(-numval, isPct).replace('%',''));
                    numstr = numstr.replace(positiveNumberStr, positiveNumberStr+'%');
                }
                else
                    numstr = numstr + (isPct?'%':'');
            }
            field.value = numstr;
            validflag = true;
        }
    }
    else if (type == "integer" || type == "posinteger" || type == "float" || type == "posfloat" || type == "nonnegfloat" || type == "percent")
    {
        var numval;
        var custrange=false;
        if ((minval != null || maxval != null) || type == "percent")
          custrange=true;
        var minclip= minval == null ? (type == "percent" ? 0 : -Math.pow(2,32)) : minval;
        var maxclip = maxval == null ?(type == "percent" ? 100 : Math.pow(2,64)) : maxval;
        var val = field.value.replace(/$/g,"");
        val = val.replace(/%/g,"");

        numval = NLStringToNumber(val, true);
        if (type == "integer")
            numval = parseInt(numval,10);
        else if (type == "posinteger")
        {
            numval = parseInt(numval,10);
            minclip=0;
        }
        else if (type == "posfloat" || type == "nonnegfloat" || type == "float")
        {
            if(val.indexOf(".") != -1)
			    numval = round_float(numval);
			if (type == "posfloat")
				minclip=0;
            if (type == "nonnegfloat")
            {
                minclip=-Number.MIN_VALUE;
            }
        }
        if (isNaN(numval) || (custrange && (numval > maxclip || numval < minclip)) || (!custrange && (numval >= maxclip || numval <= minclip)))
        {
            if (doalert)
            {
                if (type == "percent")
                {
					alert("Invalid percentage (must be between "+minclip+" and "+maxclip+")");
                }
                else if (custrange == true)
                {
                    if (minval == null)
                        alert("Invalid number (must be at most "+maxclip+")");
                    else if (maxval == null)
                        alert("Invalid number (must be at least "+minclip+")");
                    else
                        alert("Invalid number (must be between "+minclip+" and "+maxclip+")");
                }
                else if (type=="posinteger" || type=="posfloat")
                    alert("Invalid number (must be positive)");
                else if (type=="nonnegfloat")
                {
                    alert("Invalid: Please enter a number greater than or equal to 0.");
                }
                else if (type=="integer" || type=="float")
                {
                    if (isNaN(numval))
                        alert('You may only enter numbers into this field');
                    else
                        alert("Illegal number: " + numval);
                }
                else
                    alert("Invalid number (must be greater than -4.29B");
             }
             validflag = false;
        }
        else
        {
            var numberStr = numval + '';
            var isPct = (type == "percent");
            if (isPct)
                numberStr = format_percent(numval);   // normalized percent string, i.e. using standard number format
            if (isNLNumericOrCurrencyDisplayField(field))
            {
                numberStr = NLNumberToString(numberStr.replace("%", ""));
                if(isPct && numval < 0 && numberStr.indexOf('-') < 0) //other formats used for negative number
                {
                    var positiveNumberStr = NLNumberToString(format_percent(-numval).replace('%',''));
                    numberStr = numberStr.replace(positiveNumberStr, positiveNumberStr+'%');
                }
                else
                    numberStr = numberStr + (isPct?'%':'');
            }
            field.value = numberStr;
            validflag = true;
        }
    }
    else if (type == "address")
    {
        var err = '';
        if (field.value.length>999)
        {
            err = "Address too long (truncated at 1000 characters)";
            newval = field.value.substr(0,999);
        }
        if (err != '')
        {
            if (doalert) alert(err);
            field.value = newval;
        }
    }
    else if (type == "function")
    {
        if (field.value.indexOf('(') > 0)
            field.value = field.value.substr(0,field.value.indexOf('('));
		var val = field.value;
		var re = /^[0-9A-Za-z_]+(\.[0-9A-Za-z_]+)*$/;
		if (!re.test(val))
		{
			if  (doalert) alert("The Function field must be a valid JavaScript function identifier");
			validflag = false;
		}
	}
    else if (type == "time" || type == "timetrack")
    {
		var hours;
		var minutes;
        var isNegative = false;
        var val = field.value;

        if ((type === "timetrack") && (val.search(/^\s*\-/) !== -1))
        {
            isNegative = true;
            val = val.replace(/^\s*\-/, "");
        }

		var re = /([0-9][0-9]?)?(:[0-9][0-9]+)?/
        var result = re.exec(val)
        if (result==null || result.index > 0 || result[0].length != val.length)
		{
            timeval = parseFloat(val);
			if (isNaN(timeval) || field.value.indexOf(':') != -1)
				hours = -1;
			else
			{
				hours = Math.floor(timeval);
				minutes = Math.floor((timeval-hours)*60+0.5);
			}
		}
		else
		{
			if (RegExp.$1.length > 0)
				hours = parseInt(RegExp.$1,10);
			else
				hours = 0;
			if (typeof(RegExp.$2) != "undefined" && RegExp.$2.length > 0)
			{
				minutes = parseInt(RegExp.$2.substr(1),10);
				// if the user entered a value >= 60 for minutes, add the extra hours to the hours var and reduce
				// minutes to be less than 60 (issue 48406)
				if (minutes >= 60)
				{
					var hours_delta = Math.floor(minutes / 60);
					minutes -= (hours_delta * 60);
					hours += hours_delta;
				}
			}
			else
				minutes = 0;
		}
		if (hours >= 0 && minutes >= 0 && minutes < 60)
		{
			field.value = (isNegative ? "-" : "") + hours + ":" + (minutes < 10 ? "0" : "") + minutes;
			validflag = true;
		}
		else
		{
			if (doalert) alert("Invalid time value (must be hh:mm)");
			validflag = false;
		}
    }
    else if (type == "timeofday")
    {
        var ret = validate_time(field.value, doalert, false);
        validflag = ret.validflag;
        if (validflag)
           field.value = ret.value;
        /*
        var fldvalue = field.value;

        
		fldvalue = hhmmtotimestring( fldvalue );
		var time = stringtotime(null, fldvalue);
		validflag = !isNaN(time);
		if (validflag)
        {
			field.value = gettimestring(time, window.datetime_am_string, window.datetime_pm_string);
        }
        else if (doalert)
        {
			alert("Invalid time value");
        }
        */
    }
    else if (type == 'datetimetz')
    {
        var ret_date_time = extract_date_time(field.value, doalert);
        validflag = ret_date_time.validflag;
        if (validflag)
        {
            var ret_date = validate_date(ret_date_time.date, doalert);
            validflag = ret_date.validflag;
            if (validflag)
            {
                var ret_time = validate_time(ret_date_time.time, doalert, true);
                validflag = ret_time.validflag;
                if (validflag)
                {
                    field.value = ret_date.value + "  " + ret_time.value;
                }
            }
        }
    }
    else if (type == "visiblepassword")
    {
        validflag = checkpassword(field.value, field.value, doalert);
    }
    else if (type == "email")
    {
        validflag = checkemail(field.value, true, doalert);
    }
    else if (type == "emails")
    {
        var bademails = new Array();
        var validcount = 0;
        if (!separator) separator = /[,;]/;
        var emails = field.value.split(separator);
		for (var j=0; j < emails.length; j++)
		{
			var semail = trim(emails[j]);
			if (semail)
			{
				if (checkemailvalue(semail, false))
					validcount += 1;
				else
					bademails.push(emails[j]);
			}
		}
        if (bademails.length > 0)
        {
            validflag = false;
            if (doalert) alert('Invalid email(s) found: '+bademails.join('; '));
        }
        else if (validcount < 1)
        {
            validflag = false;
            if (doalert) alert('No valid emails found in \"'+field.value+'\"');
        }
    }
    else if (type == "printerOffset")
    {
        var maxclip =  2.0;
        var minclip = -2.0;
        var val = field.value;
        val = val.replace(/,/g,"");

        numval = parseFloat(val);
        if (isNaN(numval) || numval >= maxclip || numval <= minclip)
        {
      if (doalert)
      {
        if (numval >= maxclip)
            alert("Invalid number (must be lower than " + maxclip + ").");
        else if (numval <= minclip)
            alert("Invalid number (must be greater than " + minclip + ").");
        else
            alert("Illegal number: " + numval);
            }
            validflag = false;
        }
        else
        {
            
            validflag = true;
        }
    }
    else if (type == "metricPrinterOffset")
    {
        var maxclip =  50.0;
        var minclip = -50.0;
        var val = field.value;
        val = val.replace(/,/g,"");

        numval = parseFloat(val);
        if (isNaN(numval) || numval >= maxclip || numval <= minclip)
        {
      if (doalert)
      {
        if (numval >= maxclip)
            alert("Invalid number (must be lower than " + maxclip + ").");
        else if (numval <= minclip)
            alert("Invalid number (must be greater than " + minclip + ").");
        else
            alert("Illegal number: " + numval);
            }
            validflag = false;
        }
        else
        {
            
            validflag = true;
        }
    }
    else if (type == "phone"  || type == "fullphone")
    {
        var val = field.value;
        
        if(val.length!=0 && val.length<7)
        {
            if (doalert) alert("Phone number should have seven digits or more.");
            validflag = false;
        }

        if (validflag && type == "fullphone")
        {
            
            if(val.length!=0 && val.length<10)
            {

                if (doalert) alert("Please include the area code for phone number: " + val);
                validflag = false;
            }
        }
        if (autoplace && validflag)
        {
            var extidx = val.search(/[A-Za-z]/);
            var ext = '';
            if (extidx >= 0)
            {
                ext = ' '+val.substring(extidx);
                val = val.substring(0,extidx);
            }
            var re = /^[0-9()-.\s]+$/;
            if (re.test(val))
            {
			  var digits = val.replace(/[()-.\s]/g,'');
			  var phoneformat = window.phoneformat.replace(new RegExp( "[360]", "g" ),String.fromCharCode(3));
              if (digits.length == 7)
                 field.value=phoneformat.replace(phoneformat.substring(0,phoneformat.indexOf('4')),'').replace('45'+String.fromCharCode(3),digits.substring(0,3)).replace('789'+String.fromCharCode(3),digits.substring(3)) + ext;
              else if (digits.length == 10)
                 field.value=phoneformat.replace('12'+String.fromCharCode(3),digits.substring(0,3)).replace('45'+String.fromCharCode(3),digits.substring(3,6)).replace('789'+String.fromCharCode(3),digits.substring(6)) + ext;
              else if (digits.length == 11 && digits.substring(0,1) == '1')
                 field.value='1 '+phoneformat.replace('12'+String.fromCharCode(3),digits.substring(1,4)).replace('45'+String.fromCharCode(3),digits.substring(4,7)).replace('789'+String.fromCharCode(3),digits.substring(7)) + ext;
            }
        }
    }
    else if (type == "color")
    {
        var val = field.value;
        if (val.substring(0,1) == "#")
            val = val.substring(1);
        
        var re = /^[0-9ABCDEFabcdef]{6,}$/;
        if (val.length > 6 || !re.test(val))
        {
            if (doalert) alert("Color value must be 6 hexadecimal digits of the form: #RRGGBB.  Example: #FF0000 for red.");
            validflag = false;
        }
        else
            field.value = "#"+val;
    }
    else if (type == "identifier" || type == "identifieranycase")
    {
        var val = field.value;
        var re = /^[0-9A-Za-z_]+$/;
        if (!re.test(val))
        {
            if (doalert) alert("Identifiers can contain only digits, alphabetic characters, or \"_\" with no spaces");
            validflag = false;
        }
        else
            field.value = type == "identifier" ? val.toLowerCase() : val;
    }
	else if (type == "package")
	{
	validflag = /^([a-zA-Z][a-zA-Z0-9_]*)(\.([a-zA-Z0-9_]+))*$/.test(field.value);
	if (!validflag && doalert)
	{
	alert("Package can contain only digits, alphabetic characters, underscore \"_\" or dot \".\" with no spaces. It should start with an alphabetic character and should not end with a dot.");
	}
	}
    else if (type == "furigana")
    {
        var val = field.value;
        var re = /^[\u0020\u3000\u30A0-\u30FF\uFF61-\uFF9F]+$/;
        if (!re.test(val))
        {
			if (doalert) alert("A non-katakana character has been entered.");
            validflag = false;
        }
    }
	else if(type == "urlcomponent") 
	{
		var val = field.value.toLowerCase();
		var re = /^[a-z0-9\-]*$/;
		if(!re.test(val)) {
			if(doalert) alert("This field can contain only lower case letters, numbers and \'-\'.");
			validflag = false;
		}
		else
			field.value = val;
	}
    if (mandatory == true)
    {
        if (field.value.length == 0)
        {
            if (doalert) alert("Field must contain a value.");
            validflag = false;
        }
    }
    if (!validflag)
        selectAndFocusField(field);
    else if (isNLNumericOrCurrencyDisplayField(field))
    {

    }
    NS.form.setValid(validflag);
    return validflag;
}

function getTotalDigitCount(numberString)
{
    numberString = numberString + ''; // convert the parameter to string just in case that it's already a number
    if(numberString == '')
        return 0;
    else
    {
        numberString = numberString.replace('-',''); // remove minus sign
        if(numberString.indexOf(".") > 0)
        	numberString = numberString.replace(/0*?$/, '').replace('.',''); // remove trailing 0's and decimal point
	    return numberString.length;
	}
}

function selectAndFocusField(field)
{
        if (isIE)
        {
            try
            {
                field.focus();
                field.select();
            }
            catch(err)
            {
                //do nothing.
                //issue 206079, field is not visible, IE throws an exception when try to focus on it, Jieping suggested to put try/catch block here
            }
        }
        else
        {
        
            setTimeout(function() { field.focus(); field.select(); }, 50);
        }
}


function validatePeriodRange(fldPeriodStart, fldPeriodEnd)
{
    if( getSelectIndex(fldPeriodEnd) < getSelectIndex(fldPeriodStart) )
    {
        alert('Please enter a valid date range. The From date must precede the To date.');
        return false;
    }

    return true;
}


function setSelectionRange(input, selectionStart, selectionEnd) {
  if (input.setSelectionRange) {
    input.focus();
    // Issue 235915: Newer versions of Firefox silently throws an error which prevents filtering from finishing
    // Catching this error allows it to finish properly. (Reproduced on FF12, FF18. No problem on FF3)
    try
    {
        input.setSelectionRange(selectionStart, selectionEnd);
    }
    catch (e)
    {
    }
  }
  else if (input.createTextRange) {
    var range = input.createTextRange();
    range.collapse(true);
    range.moveEnd('character', selectionEnd);
    range.moveStart('character', selectionStart);
    range.select();
  }
}


NLDate_months = ['January','February','March','April','May','June','July','August','September','October','November','December'];
if ( 13 > 12 )
NLDate_months.push('');
NLDate_short_months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
if ( 13 > 12 )
NLDate_short_months.push('');
function nlGetFullYear(d)
{
    if (window.navigator != null && window.navigator.appName == "Netscape")
    {
        if (d.getFullYear == "undefined")
            return d.getYear();
    }
    return d.getFullYear();
}
function nlSetFullYear(d,val)
{
    if (window.navigator != null && window.navigator.appName == "Netscape")
    {
        if (d.setFullYear == "undefined")
            d.setYear(val);
    }
    d.setFullYear(val);
}

var year_char_cn = "年";
var month_char_cn = "月";
var day_char_cn = "日";

var weekday = new Array(7);
weekday[0] = "Sunday";
weekday[1] = "Monday";
weekday[2] = "Tuesday";
weekday[3] = "Wednesday";
weekday[4] = "Thursday";
weekday[5] = "Friday";
weekday[6] = "Saturday";

function getdatestring(d, format)
{
	// if dateformat is specified, use it from the format parameter
	// else use the window property (set from user preference)
	var dateformat;
	if (typeof(format) != "undefined")
		dateformat = format;
	else if (typeof(window.dateformat) != "undefined")
		dateformat = window.dateformat;
	else
		dateformat = "MM/DD/YYYY";

	// replace format literals with date field values
	dateformat = dateformat.replace("YYYY", nlGetFullYear(d));
	dateformat = dateformat.replace("MM", (d.getMonth() + 1));
	dateformat = dateformat.replace("DD", d.getDate());
	dateformat = dateformat.replace(/month/i, NLDate_months[d.getMonth()]);
	dateformat = dateformat.replace(/mon/i, NLDate_short_months[d.getMonth()]);

	// japan specific
	if (dateformat.indexOf("EEYY") == 0)
		dateformat = dateformat.replace("EEYY", get_japanese_imperial_era(d) + get_japanese_imperial_year(d));
	else if (dateformat.indexOf("EYY") == 0)
		dateformat = dateformat.replace("EYY", get_short_japanese_imperial_era(d) + get_japanese_imperial_year(d));

	return dateformat;
}

var heisei_start_date = new Date(1989,0,8);
var shouwa_start_date = new Date(1926,11,25);
var taishou_start_date = new Date(1912,6,30);
var meiji_start_date = new Date(1867,1,3);
function get_japanese_imperial_era(d)
{
	if(d >= heisei_start_date)
		return "平成";
	else if(d >= shouwa_start_date)
		return "昭和";
	else if(d >= taishou_start_date)
		return "大正";
	else
		return "明治";
}
function get_short_japanese_imperial_era(d)
{
	if(d >= heisei_start_date)
		return "H";
	else if(d >= shouwa_start_date)
		return "S";
	else if(d >= taishou_start_date)
		return "D";
	else
		return "M";
}
function get_japanese_imperial_year(d)
{
	if(d >= heisei_start_date)
		return nlGetFullYear(d) - 1988;
	else if(d >= shouwa_start_date)
		return nlGetFullYear(d) - 1925;
	else if(d >= taishou_start_date)
		return nlGetFullYear(d) - 1911;
	else
		return nlGetFullYear(d) - 1867;
}
function get_gregorian_year(ja_imperial_year, era)
{
	if(era == "平成" || era == "H")
		return ja_imperial_year + 1988;
	else if(era == "昭和" || era == "S")
		return ja_imperial_year + 1925;
	else if(era == "大正" || era == "D")
		return ja_imperial_year + 1911;
	else
		return ja_imperial_year + 1867;
}

function getdefaultformatdatestring(d)
{
    return (d.getMonth()+1)+"/"+d.getDate()+"/"+nlGetFullYear(d);
}
function gettimestring(time,amvar,pmvar)
{
	return gettimestringwithformat(time, amvar, pmvar, window.timeformat);
}

function gettimestringwithformat(time, amvar, pmvar, format)
{
	var hours = time.getHours();
	if(typeof(amvar) == "undefined")
	{
		amvar = window.datetime_am_string;
		pmvar = window.datetime_pm_string;
	}
	var ampm = hours < 12 ? amvar : pmvar;
	if(format.indexOf("HH24") < 0)
	{
		hours = hours % 12;
		if(hours == 0)
			hours = 12;
	}
	var minutes = time.getMinutes() < 10 ? '0' + time.getMinutes() : time.getMinutes();
	var timeStr = format;
	timeStr = timeStr.replace("24", "");
	timeStr = timeStr.replace("fmHH", hours);
	timeStr = timeStr.replace("fmMI", minutes);
	if(format.indexOf("HH24") < 0)
		timeStr = timeStr.replace("am", ampm);
	return timeStr;
}

function gettimewithsecondsstring(time,amvar,pmvar)
{
	var hours = time.getHours();
	if(typeof(amvar) == "undefined")
	{
		amvar = window.datetime_am_string;
		pmvar = window.datetime_pm_string;
	}
	var ampm = hours < 12 ? amvar : pmvar;
	if(window.timeformatwithseconds.indexOf("HH24") < 0)
	{
		hours = hours % 12;
		if(hours == 0)
			hours = 12;
	}
	var minutes = time.getMinutes() < 10 ? '0' + time.getMinutes() : time.getMinutes();
    var seconds = time.getSeconds() < 10 ? '0' + time.getSeconds() : time.getSeconds();
	var timeStr = window.timeformatwithseconds.replace(/fm/g, "");
	timeStr = timeStr.replace("24", "");
	timeStr = timeStr.replace("HH", hours);
	timeStr = timeStr.replace("MI", minutes);
    timeStr = timeStr.replace("SS", seconds);
	if(window.timeformatwithseconds.indexOf("HH24") < 0)
		timeStr = timeStr.replace("am", ampm);
	return timeStr;
}

function getdatetimestring(date)
{
    return getdatestring(date) + " " + gettimestring(date);
}

function getdatetimetzstring(date)
{
    return getdatestring(date) + " " + gettimewithsecondsstring(date);
}

/**
 * Convert date to MMYY string.
 * Should behave the same way as NLDateRangeFieldGroup.getInvTurnDate().
 * The result must also be parsable by parseMMYYDateString.
 *
 * @param d
 * @param NLDate_short_months
 */
function getmmyydatestring(d, NLDate_short_months)
{
    if (window.dateformat == "DD-Mon-YYYY")
        return NLDate_short_months[d.getMonth()]+"-"+nlGetFullYear(d);
    else if (window.dateformat == "DD.MM.YYYY")
        return (d.getMonth()+1)+"."+nlGetFullYear(d);
    else if (window.dateformat == "DD/MM/YYYY")
        return (d.getMonth()+1)+"/"+nlGetFullYear(d);
    else if (window.dateformat == "YYYY/MM/DD")
        return (d.getMonth()+1)+"/"+nlGetFullYear(d);
    else
        return (d.getMonth()+1)+"/"+nlGetFullYear(d);
}

/**
 * Parse year and month from a MMYY value.
 * Try to be as benevolent as possible, while keeping unambiguous.
 * Must parse anything produced by getmmyydatestring()
 * and NLDateRangeFieldGroup.getInvTurnDate().
 *
 * @param value the string value
 */
function parseMMYYDateString(value)
{
    var year, month;
    if(!/^[0-9-\/\.]+$/.test(value))
    {
        // contains other chars than numerals and ./- => must contain month short name
        var c = value.split(/[\/-]/);
        if (c.length != 2) {
            return null;
        }
        month = getMonthIndex(c[0]);
        year = parseInt(c[1],10);
    }
    else
    {
        // split it by any of ./-
        var comps = value.split(/[\.\/-]/);
        if (comps.length == 1)
        {
            // without any separator - month is the first 1 or 2 chars,
            // the rest is year (2 or 4 chars)
            var l = value.length;
            month = parseInt(value.substr(0,2-l%2),10);
            year = parseInt(value.substr(2-l%2),10);
        }
        else
        {
            // first month then year
            month = parseInt(comps[0],10);
            year = parseInt(comps[1],10);
        }
    }

    // make the year full year if less then 100
    if (year < 50)
        year += 2000;
    else if (year < 100)
        year += 1900;

    return {
        year: year,
        month: month
    };
}

/**
 * Parse day and month from a DDMM value.
 *
 * @param value the string value
 */
function parseMMDDDateString(value)
{
    var day, month;
    // format is fixed as MM/DD
    var c = value.split(/[\/]/);
    if (c.length != 2) {
        return null;
    }
    // first month then day
    month = parseInt(c[0],10)-1;
    day = parseInt(c[1],10);

    return {
        month: month,
        day: day
    };
}

function stringtodate(arg, dateformat, returnNullIfInvalid, formattype)
{
    var comps;
	var month, day, year;
	var year_char_index, month_char_index, day_char_index, era;
    var d = arg;  // date string, assume it's the whole string for now
	if(dateformat == null)
	{
		if(typeof(window.dateformat) != "undefined")
			dateformat = window.dateformat;
		else
			dateformat = "MM/DD/YYYY";
	}
	var datestring_length = arg.length;
	var end_string; //the end segment in date string (mainly used for date seg since year string's length is always 4)
	var year_length = 4;
	var returnValIfError = returnNullIfInvalid ? null : new Date();

	if(d.length > 0)
	{
		if(dateformat == "MM/DD/YYYY")
		{
			comps = d.split("/");
			if(comps.length < 3)       // the format can contains time hh:mm:ss or hh-mm-ss
				return returnValIfError;
			month = parseInt(comps[0], 10) - 1;
			day = parseInt(comps[1], 10);
			year = parseInt(comps[2].substring(0, year_length), 10);
			datestring_length = comps[0].length + comps[1].length + year_length + 2;
		}
		else if(dateformat == "DD/MM/YYYY")
		{
			comps = d.split("/");
			if(comps.length < 3)     // the format can contains time hh:mm:ss or hh-mm-ss
				return returnValIfError;
			day = parseInt(comps[0], 10);
			month = parseInt(comps[1], 10) - 1;
			year = parseInt(comps[2].substring(0, year_length), 10);
			datestring_length = comps[0].length + comps[1].length + year_length + 2;
		}
		else if(dateformat == "DD-Mon-YYYY")
		{
			comps = d.split("-");
			if(comps.length < 3)     // the format can contains time hh:mm:ss or hh-mm-ss
				return returnValIfError;
			day = parseInt(comps[0], 10);
			month = getMonthIndex(comps[1]) - 1;
			year = parseInt(comps[2].substring(0, year_length), 10);
			datestring_length = comps[0].length + comps[1].length + year_length + 2;
		}
		else if(dateformat == "DD.MM.YYYY")
		{
			comps = d.split(".");
			if(comps.length < 3)     // the format can contains time hh:mm:ss or hh-mm-ss
				return returnValIfError;
			day = parseInt(comps[0], 10);
			month = parseInt(comps[1], 10) - 1;
			year = parseInt(comps[2].substring(0, year_length), 10);
			datestring_length = comps[0].length + comps[1].length + year_length + 2;
		}
		else if(dateformat == "DD-MONTH-YYYY")
		{
			comps = d.split("-");
			if(comps.length < 3)     // the format can contains time hh:mm:ss or hh-mm-ss
				return returnValIfError;
			day = parseInt(comps[0], 10);
			month = arrayIndexOf(NLDate_months, comps[1], true);
			year = parseInt(comps[2].substring(0, year_length), 10);
			datestring_length = comps[0].length + comps[1].length + year_length + 2;
		}
		else if(dateformat == "YYYY/MM/DD")
		{
			comps = d.split("/");
			if(comps.length < 3)     // the format can contains time hh:mm:ss or hh-mm-ss
				return returnValIfError;
			end_string = comps[2].split(" ")[0];
			day = parseInt(end_string, 10);
			month = parseInt(comps[1], 10) - 1;
			year = parseInt(comps[0], 10);
			datestring_length = comps[1].length + end_string.length + year_length + 2;
		}
		else if(dateformat == "YYYY-MM-DD")
		{
			comps = d.split("-");
			if(comps.length < 3)     // the format can contains time hh:mm:ss or hh-mm-ss
				return returnValIfError;
			end_string = comps[2].split(" ")[0];
			day = parseInt(end_string, 10);
			month = parseInt(comps[1], 10) - 1;
			year = parseInt(comps[0], 10);
			datestring_length = comps[1].length + end_string.length + year_length + 2;
		}
		else if(dateformat == "EEYY年MM月DD日")
		{
			year_char_index = d.indexOf(year_char_cn);
			month_char_index = d.indexOf(month_char_cn);
			day_char_index = d.indexOf(day_char_cn);
			if(year_char_index < 0 || month_char_index < 0 || day_char_index < 0)
				return returnValIfError;
			day = parseInt(d.substring(month_char_index+1,day_char_index), 10);
			month = parseInt(d.substring(year_char_index+1,month_char_index), 10) - 1;
			era = d.substring(0, 2);
			year = get_gregorian_year(parseInt(d.substring(2,year_char_index), 10), era);
			datestring_length = day_char_index + 1;
		}
		else if(dateformat == "YYYY年MM月DD日")
		{
			year_char_index = d.indexOf(year_char_cn);
			month_char_index = d.indexOf(month_char_cn);
			day_char_index = d.indexOf(day_char_cn);
			if(year_char_index < 0 || month_char_index < 0 || day_char_index < 0)
				return returnValIfError;
			day = parseInt(d.substring(month_char_index+1,day_char_index), 10);
			month = parseInt(d.substring(year_char_index+1,month_char_index), 10) - 1;
			year = parseInt(d.substring(0,year_char_index), 10);
			datestring_length = day_char_index + 1;
		}
		else if(dateformat == "EYY.MM.DD")
		{
			comps = d.split(".");
            if(comps.length < 3)     // the format can contains time hh:mm:ss or hh-mm-ss
				return returnValIfError;
			end_string = comps[2].split(" ")[0];
			day = parseInt(end_string, 10);
			month = parseInt(comps[1], 10) - 1;
			era = comps[0].substring(0, 1);
			year = get_gregorian_year(parseInt(comps[0].substring(1,comps[0].length), 10), era);
			datestring_length = comps[0].length + comps[1].length + end_string.length + 2;
		}
		else if(dateformat == "DD. MON YYYY")
		{
			comps = d.split(" ");
            if(comps.length < 3)     // the format can contains time hh:mm:ss or hh-mm-ss
				return returnValIfError;
			day = parseInt(comps[0].substring(0, comps[0].length - 1), 10);
			month = arrayIndexOf(NLDate_short_months, comps[1]);
			year = parseInt(comps[2].substring(0, year_length), 10);
			datestring_length = comps[0].length + comps[1].length + year_length + 2;
		}
		else if(dateformat == "DD de MONTH de YYYY")
		{
			comps = d.split(" de ");
            if(comps.length < 3)     // the format can contains time hh:mm:ss or hh-mm-ss
				return returnValIfError;
			day = parseInt(comps[0], 10);
			month = getMonthIndex(comps[1]) - 1;
			year = parseInt(comps[2].substring(0, year_length), 10);
			datestring_length = comps[0].length + comps[1].length + year_length + 8;
		}
		else if(dateformat == "YYYY년 MM월 DD일")
		{
			comps = d.split(" ");
			if(comps.length < 3)     // the format can contains time hh:mm:ss or hh-mm-ss
				return returnValIfError;
			day = parseInt(comps[2].substring(0, comps[2].length-1), 10);
			month = parseInt(comps[1].substring(0, comps[1].length-1), 10) - 1;
			year = parseInt(comps[0].substring(0, comps[0].length-1), 10);
			datestring_length = year_length + comps[1].length + comps[2].length + 5;
		}
		else if(dateformat == "DD MONTH YYYY")
		{
			comps = d.split(" ");
			if(comps.length < 3) //the format could be "DD MONTH YYYY HH:MI:SS AM" . length =4
				return returnValIfError;
			day = parseInt(comps[0], 10);
			month = arrayIndexOf(NLDate_months, comps[1], true);
			year = parseInt(comps[2].substring(0, year_length), 10);
			datestring_length = comps[0].length + comps[1].length + year_length + 2;
		}
		else if(dateformat == "DD MONTH, YYYY")
		{
			comps = d.split(" ");
			if(comps.length < 3) //the format could be "DD MONTH YYYY HH:MI:SS PM" . length = 4
				return returnValIfError;
			day = parseInt(comps[0], 10);
			month = arrayIndexOf(NLDate_months, comps[1].substring(0, comps[1].length-1), true);
			year = parseInt(comps[2].substring(0, year_length), 10);
			datestring_length = comps[0].length + comps[1].length + year_length + 2;
		}
	}

	if (!isvalidyearmonthday(year, month, day))
		return returnValIfError;
	
	// now handle the time segment
	var result;
    var t = arg.substring(datestring_length);
	if (t != null && t.length > 0)
    {
        if (formattype == 'datetimetz')
            result = regexstringtotime(arg.substring(0,datestring_length),t, true);
        else if (formattype == 'datetime' || formattype == 'timeofday')
            result = regexstringtotime(arg.substring(0,datestring_length),t, false);
        else
            result = stringtotime(arg.substring(0,datestring_length),t);        
    }
    else
        result = new Date(year,month,day);
    if (year < 50)
        nlSetFullYear(result, year+2000);
    else if (year < 100)
        nlSetFullYear(result, year+1900);
    return result;
}

function isvalidyearmonthday(year, month, day)
{
	if(isNaN(year) || year < 0 || isNaN(month) || month < 0 || month > 11 || isNaN(day) || day < 1 || day > 31)
		return false;
	else
		return true;
}

// we need this for sever side script
function trimstring(str)
{
    return str.replace(/^\s+/,"").replace(/\s+$/,"");
}

function regexstringtotime(date, time, includeSeconds)
{
    var flddate = date != null ? stringtodate(date) : new Date();
    if (time != null && new String(time).length != 0 && new String(time).search(/\S/) >= 0)
    {
        var hours, minutes, seconds;
        hours = NaN;
        minutes = NaN;
        seconds = NaN;

        var delimitors = null;
        time = trimstring(time); // remove all leading/trailing spaces

        var TIME_FORMAT_MAP =
        {
            "HH:MI:SS am": { rcase:0, hend:':', mend:':', send:' '},
            "HH-MI-SS am": { rcase:0, hend:'-', mend:'-', send:' '},
            "HH24:MI:SS": { rcase:0, hend:':', mend:':', send:null},
            "HH24-MI-SS": { rcase:0, hend:'-', mend:'-', send:null},
            "amHH時MI分SS秒": { rcase:1, hend:'時', mend:'分', send:'秒'},
            "amHH点MI分SS秒": { rcase:1, hend:'点', mend:'分', send:'秒'},
            "amHH시MI분SS초": { rcase:1, hend:'시', mend:'분', send:'초'},
            "HH24時MI分SS秒": { rcase:1, hend:'時', mend:'分', send:'秒'},
            "HH24点MI分SS秒": { rcase:2, hend:'点', mend:'分', send:'秒'},
            "HH24시MI분SS초": { rcase:2, hend:'시', mend:'분', send:'초'},
            "HH:MI am": { rcase:0, hend:':', mend:' ', send:null},
            "HH-MI am": { rcase:0, hend:'-', mend:' ', send:null},
            "HH24:MI": { rcase:0, hend:':', mend:null, send:null},
            "HH24-MI": { rcase:0, hend:'-', mend:null, send:null},
            "amHH時MI分": { rcase:1, hend:'時', mend:'分', send:null},
            "amHH点MI分": { rcase:1, hend:'点', mend:'分', send:null},
            "amHH시MI분": { rcase:1, hend:'시', mend:'분', send:null},
            "HH24時MI分": { rcase:2, hend:'時', mend:'分', send:null},
            "HH24点MI分": { rcase:2, hend:'点', mend:'分', send:null},
            "HH24시MI분":{ rcase:2, hend:'시', mend:'분', send:null}
        }

        format = includeSeconds ? window.timeformatwithseconds.replace(/fm/g, "") : window.timeformat.replace(/fm/g, "");
        format = trimstring(format);
        delimitors = TIME_FORMAT_MAP[format];

        var m;
        var ampm = null;
        var hend = null, mend = null, send = null;
        if (delimitors != null)
        {
            switch (delimitors.rcase)
            {
                case 0:
                {
                    m = /^(\d+)(\D)(\d+)((\D)(\d+))?\s*(am|pm)?/.exec(time);
                    if (m !== null)
                    {
                        hours = parseInt(m[1], 10);
                        hend = m[2];
                        minutes = parseInt(m[3], 10);
                        mend = m[5];
                        if (includeSeconds && m[4] != null)
                            seconds = parseInt(m[6], 10);
                        else
                            seconds = 0;
                        ampm = m[7];
                    }
                    break;
                }
                case 1:
                {
                    m = /^(am|pm)(\d+)(\D)(\d+)(\D)((\d+)(\D))?/.exec(time);
                    if (m !==  null)
                    {
                        hours = parseInt(m[2], 10);
                        hend = m[3];
                        minutes = parseInt(m[4], 10);
                        mend = m[5];
                        if (includeSeconds && m[6] != null)
                        {
                            seconds = parseInt(m[7], 10);
                            send = m[8];
                        }
                        else
                            seconds = 0;
                        ampm = m[1];
                    }
                    break;
                }
                case 2:
                {
                    m = /^(\d+)(\D)(\d+)(\D)((\d+)(\D))?/.exec(time);
                    if (m !==  null)
                    {
                        hours = parseInt(m[1], 10);
                        hend = m[2];
                        minutes = parseInt(m[3], 10);
                        mend = m[4];
                        if (includeSeconds && m[5] != null)
                        {
                            seconds = parseInt(m[6], 10);
                            send = m[7];
                        }
                        else
                            seconds = 0;         
                    }
                    break;
                }
            }
            if (isNaN(hours) || isNaN(minutes) || isNaN(seconds) || hours >= 24 || hours < 0 || minutes >= 60 || minutes < 0 || seconds >= 60 || seconds < 0)
                return NaN;

            if (hend != delimitors.hend || (includeSeconds && (mend != null && mend != delimitors.mend) || (send != null && send != delimitors.send)))
                return NaN;

            if (ampm != null)
            {
                var is_pm = (ampm.toLowerCase() == window.datetime_pm_string);
                if (!is_pm && hours == 12)
                    hours = 0;
                else if (is_pm && hours < 12)
                    hours += 12;
            }
            flddate.setHours(hours, minutes, seconds, 0);
        } else
           flddate = NaN;        
    }
    return flddate;
}



function stringtotime(date, time)
{
    var flddate = date != null ? stringtodate(date) : new Date();
    if (time != null && new String(time).length != 0 && new String(time).search(/\S/) >= 0)
    {
        var hours, minutes, seconds, is_pm;
        var hour_char_index;
        var minute_char_index;
        format = window.timeformat.replace(/fm/g, "");
        if (format == "HH:MI am" || format == "HH-MI am" || format == "HH24:MI" || format == "HH24-MI")
        {
            var m = /^\s*(\d+)[-:](\d+)\s*(.*)/.exec(time);
            if (!m) return NaN;
            hours = parseInt(m[1], 10);
            minutes = parseInt(m[2], 10);
            if (format.substring(6) == "am")
            {
                is_pm = (m[3].toLowerCase() == window.datetime_pm_string);
                if (!is_pm && hours == 12)
                    hours = 0;
                else if (is_pm && hours < 12)
                    hours += 12;
            }
        }
        else if(format == "amHH時MI分" || format == "amHH点MI分" || format == "amHH시MI분")
        {
            hour_char_index = time.indexOf("時");
            if(hour_char_index < 0)
                hour_char_index = time.indexOf("点");
            if(hour_char_index < 0)
                hour_char_index = time.indexOf("시");
            var hour_start_index = 0;
            is_pm = false;
            if(time.indexOf(window.datetime_am_string) == 0)
                hour_start_index = window.datetime_am_string.length;
            else if(time.indexOf(window.datetime_pm_string) == 0)
            {
                hour_start_index = window.datetime_pm_string.length;
                is_pm = true;
            }
            hours = parseInt(time.substring(hour_start_index, hour_char_index));
            if (!is_pm && hours == 12)
                hours = 0;
            else if(is_pm && hours < 12)
                hours += 12;
            minutes = parseInt(time.substring(hour_char_index + 1, time.length - 1));
        }
        else if(format == "HH24時MI分" || format == "HH24点MI分" || format == "HH24시MI분")
        {
            hour_char_index = time.indexOf("時");
            if(hour_char_index < 0)
                hour_char_index = time.indexOf("点");
            if(hour_char_index < 0)
                hour_char_index = time.indexOf("시");
            hours = parseInt(time.substring(0, hour_char_index));
            minutes = parseInt(time.substring(hour_char_index + 1, time.length - 1));
        }
        if(isNaN(hours) || isNaN(minutes) || hours >= 24 || hours < 0 || minutes >= 60 || minutes < 0 || seconds >= 60 || seconds < 0)
            return NaN;
        flddate.setHours(hours, minutes, 0, 0);
    }
    return flddate;
}

function hhmmtotime( hhmm )
{
    return stringtotime( null, hhmmtotimestring( hhmm ) );
}

// -- handle shorthand time notation i.e. 5p -> 5:00 pm, 18 -> 6:00 pm, 900 -> 9:00 am, 1433p -> 2:33 pm
function hhmmtotimestring( hhmm )
{
    var fldvalue = hhmm;
	var hour, minute;
	if ( window.datetime_am_string.charAt(0) == window.datetime_pm_string.charAt(0) )
		re = new RegExp("^[0-9]{1,4}("+window.datetime_am_string+"|"+window.datetime_pm_string+")*$", "i");
	else
		re = new RegExp("^[0-9]{1,4}(["+window.datetime_am_string.charAt(0)+"|"+window.datetime_pm_string.charAt(0)+"]?)$","i");
    if ( re.test(fldvalue) )
    {
		var aorp = '';
		if ( RegExp.$1 )
		{
			if ( window.datetime_am_string.charAt(0) == window.datetime_pm_string.charAt(0) )
				aorp = RegExp.$1.toLowerCase() == window.datetime_pm_string ? window.datetime_pm_string : window.datetime_am_string;
			else
				aorp = RegExp.$1.toLowerCase().charAt(0) == window.datetime_pm_string.charAt(0) ? window.datetime_pm_string : window.datetime_am_string;
		}
		if ( fldvalue.length < 3 || ( fldvalue.length == 3 && RegExp.$1 ) )
        {
            var hh = RegExp.$1 ? fldvalue.substring(0,fldvalue.length-1) : fldvalue;
            hour = parseInt( hh, 10 ) == 0 ? 12 : ( parseInt( hh, 10 ) > 12 ? parseInt( hh, 10 ) % 12 : hh ) ;
			minute = 0;
            var ampm = RegExp.$1 ? aorp :
					   ( parseInt( fldvalue, 10 ) > 11 ? window.datetime_pm_string : window.datetime_am_string );
        }
		else if (fldvalue.length == 3 || (fldvalue.length == 4 && RegExp.$1) )
        {
            var hh = fldvalue.substring(0,1) == "0" ? "12" : fldvalue.substring(0,1);
			hour = parseInt( hh, 10 );
			var mm = RegExp.$1 ? fldvalue.substring(1,3) : fldvalue.substring(1);
			minute = parseInt( mm, 10 );
			var ampm = RegExp.$1 ? aorp : window.datetime_am_string;
        }
        else
        {
            var hh = fldvalue.substring(0,2);
			hour = parseInt( hh, 10 ) == 0 ? 12 : ( parseInt( hh, 10 ) > 12 ? parseInt( hh, 10 ) % 12 : hh );
			var mm = RegExp.$1 ? fldvalue.substring(2,4) : fldvalue.substring(2);
			minute = parseInt( mm, 10 );            
			var ampm = parseInt( fldvalue.substring(0,2), 10 ) > 11 ? window.datetime_pm_string : window.datetime_am_string;
            ampm = RegExp.$1 ? aorp : ampm;
		}
		if (ampm == window.datetime_am_string && hour == 12)
			hour = 0;
		else if(ampm == window.datetime_pm_string && hour != 12)
			hour = parseInt(hour) + 12;
		var time = new Date();
		time.setHours(hour,minute,0,0);        
        fldvalue = gettimestring(time, window.datetime_am_string, window.datetime_pm_string);
	}
	return fldvalue;
}

function adddays(d, daystoadd)
{
    var d2 = new Date(d.getTime() + 86400 * daystoadd * 1000);
    if (d2.getHours() != d.getHours())
    {
        if ((d.getHours() > 0 && d2.getHours() < d.getHours()) || (d.getHours() == 0 && d2.getHours() == 23))
          d2.setTime(d2.getTime() + 3600*1000);
        else
          d2.setTime(d2.getTime() - 3600*1000);
    }
    d.setTime(d2.getTime());
    return d;
}

function daysBetween(dEarly, dLate) // ignores time
{
	return get_julian_date(dLate) - get_julian_date(dEarly);
}

function monthsBetween(dEarly, dLate) // ignores DOM and time
{
	return 12*(dLate.getFullYear() - dEarly.getFullYear()) + (dLate.getMonth() - dEarly.getMonth());
}

function isDOWIM(dDate, nDOWIM)
{
	return (nDOWIM >= 1 && nDOWIM == (1 + Math.floor((dDate.getDate()-1)/7))) ||
		((nDOWIM == -1 || nDOWIM == 5) && daysBetween(dDate, addmonths(new Date(dDate.getFullYear(), dDate.getMonth(), 1), 1)) <= 7);
}

function isLeapYear(year)
{
    return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
}

MONTH_LENGTH = [[31,28,31,30,31,30,31,31,30,31,30,31],[31,29,31,30,31,30,31,31,30,31,30,31]];

function getMonthLength(year, month)
{
	return MONTH_LENGTH[isLeapYear(year)?1:0][month];
}

/**
 *  setDateComponents: set the month and day of the given date.  If noRollover is given and true,
 *  the day will not exceed the last day of the final month and thus will not trigger a month rollover.
 */
function setDateComponents(theDate, monthsToAdd, theDay, noRollover)
{
  var newDate  = new Date(theDate);

  if (typeof(noRollover) != 'boolean')
      noRollover = false;
  addmonths(newDate,monthsToAdd);
  setDate(newDate, theDay, noRollover);

  return newDate;
}

function addmonths(d, mtoadd)
{
	if (mtoadd != 0)
	{
		var year = nlGetFullYear(d);
		var dom = d.getDate();
		var month = d.getMonth() + mtoadd;
		if (month < 0)
		{
			month += 1;
			year = year + Math.ceil(month / 12) - 1;
			nlSetFullYear(d, year);
			month = 11 + (month % 12);
		}
		else if (month > 11)
		{
			year = year + Math.floor(month / 12);
			nlSetFullYear(d, year);
			month %= 12;
		}
		eom = getMonthLength(year, month);
		if (dom > eom) d.setDate(eom);
		d.setMonth(month);
    }
    return d;
}

function addhours(d, hourstoadd, truncate)
{
    var d2 = new Date(d.getTime() + 3600 * hourstoadd * 1000);
    d.setTime(d2.getTime());
	if (truncate)
	{
		d.setMinutes(0);
		d.setSeconds(0);
		d.setMilliseconds(0);
	}
	return d;
}

function setDate(d, day, noRollover)
{
    if (noRollover)
    {
        var eom = getMonthLength(nlGetFullYear(d), d.getMonth());
        day = Math.min(eom, day);
    }
    d.setDate(day);
}

m_j_d = [[0,31,59,90,120,151,181,212,243,273,304,334],[0,31,60,91,121,152,182,213,244,274,305,335]];

function getMonthJulian(year, month)
{
	return m_j_d[isLeapYear(year)?1:0][month];
}

var j_d=new Array();
j_d[1970]=0;
j_d[1971]=365;
j_d[1972]=730;
j_d[1973]=1096;
j_d[1974]=1461;
j_d[1975]=1826;
j_d[1976]=2191;
j_d[1977]=2557;
j_d[1978]=2922;
j_d[1979]=3287;
j_d[1980]=3652;
j_d[1981]=4018;
j_d[1982]=4383;
j_d[1983]=4748;
j_d[1984]=5113;
j_d[1985]=5479;
j_d[1986]=5844;
j_d[1987]=6209;
j_d[1988]=6574;
j_d[1989]=6940;
j_d[1990]=7305;
j_d[1991]=7670;
j_d[1992]=8035;
j_d[1993]=8401;
j_d[1994]=8766;
j_d[1995]=9131;
j_d[1996]=9496;
j_d[1997]=9862;
j_d[1998]=10227;
j_d[1999]=10592;
j_d[2000]=10957;
j_d[2001]=11323;
j_d[2002]=11688;
j_d[2003]=12053;
j_d[2004]=12418;
j_d[2005]=12784;
j_d[2006]=13149;
j_d[2007]=13514;
j_d[2008]=13879;
j_d[2009]=14245;
j_d[2010]=14610;
j_d[2011]=14975;
j_d[2012]=15340;
j_d[2013]=15706;
j_d[2014]=16071;
j_d[2015]=16436;
j_d[2016]=16801;
j_d[2017]=17167;
j_d[2018]=17532;
j_d[2019]=17897;
j_d[2020]=18262;
j_d[2021]=18628;
j_d[2022]=18993;
j_d[2023]=19358;
j_d[2024]=19723;
j_d[2025]=20089;
j_d[2026]=20454;
j_d[2027]=20819;
j_d[2028]=21184;
j_d[2029]=21550;
j_d[2030]=21915;

function get_julian_date(d)
{
    return j_d[d.getFullYear()]+getMonthJulian(d.getFullYear(),d.getMonth())+d.getDate()-1;   
}

function getMonthIndex(sMonth)
{
    var m = -1;
    sMonth = sMonth.toUpperCase()
    for ( var i=0; i < NLDate_short_months.length; i++ )
    {
        if ( NLDate_short_months[i].toUpperCase() == sMonth )
        {
            m = i + 1; break;
        }
    }
    if(m != -1)
    	return m;
    for ( var i=0; i < NLDate_months.length; i++ )
    {
        if ( NLDate_months[i].toUpperCase() == sMonth )
        {
            m = i + 1; break;
        }
    }
    if(m != -1)
    	return m;
    else
    {
        var ms = "JANFEBMARAPRMAYJUNJULAUGSEPOCTNOVDEC";
        m = (ms.indexOf(sMonth)+3)/3;
    }
    return m;
}

function _hhmm_to_mins(time) {
    return time.hrs * 60 + time.mins;
}

function round_hhmm_nearest(hrs, mins, round_by) {
    var up_time = round_hhmm_up(hrs, mins, round_by);
    var down_time = round_hhmm_down(hrs, mins, round_by);

    orig_mins = _hhmm_to_mins({
        hrs: hrs,
        mins: mins
    });
    up_mins = _hhmm_to_mins(up_time);
    down_mins = _hhmm_to_mins(down_time);

    if (up_mins - orig_mins > orig_mins - down_mins) {
        return down_time;
    } else {
        return up_time;
    }
}

function round_hhmm_up(hrs, mins, round_by) {
    mins += (mins % round_by > 0 ? (round_by - (mins % round_by)) : 0);
    if (mins >= 60) {
        var _hhmm_delta = Math.floor(mins / 60);
        mins -= (_hhmm_delta * 60);
        hrs += _hhmm_delta;
    }
    return {
        hrs: hrs,
        mins: mins
    };
}

function round_hhmm_down(hrs, mins, round_by) {
    mins -= (mins > 0 ? (mins % round_by) : 0);
    return {
        hrs: hrs,
        mins: mins
    };
}

function round_hhmm(val, round_by, direction) {
    if (val == "") return val;
    var re = /^([0-9]+?):([0-9]+)$/;
    var result = re.exec(val);
    if (result == null) {
        result = format_hhmm(val);
        if (result == null) return val;
    }
    var hrs = parseFloat(result[1]);
    var mins = parseFloat(result[2]);
    var time;
    if (direction == 'UP') {
        time = round_hhmm_up(hrs, mins, round_by);
    } else if (direction == 'DOWN') {
        time = round_hhmm_down(hrs, mins, round_by);
    } else if (direction == 'NEAR') {
        time = round_hhmm_nearest(hrs, mins, round_by);
    } else {
        throw direction + ' is not vald direction: [UP,DOWN,NEAREST]';
    }
    if (time.mins < 10) time.mins = '0' + time.mins;
    return time.hrs + ':' + time.mins;
}

function format_hhmm(val) {
      var hours;
      var minutes;

      var re = /([0-9][0-9]?)?(:[0-9][0-9]+)?/
      var result = re.exec(val)
      if (result == null || result.index > 0 || result[0].length != val.length) {
          timeval = parseFloat(val);
          if (isNaN(timeval)) hours = -1;
          else {
              hours = Math.floor(timeval);
              minutes = Math.floor((timeval - hours) * 60 + 0.5);
          }
      } else {
          if (RegExp.$1.length > 0) hours = parseInt(RegExp.$1, 10);
          else hours = 0;
          if (typeof (RegExp.$2) != "undefined" && RegExp.$2.length > 0) {
              minutes = parseInt(RegExp.$2.substr(1), 10);
              // if the user entered a value >= 60 for minutes, add the extra hours to the hours var and reduce
              // minutes to be less than 60
              if (minutes >= 60) {
                  var hours_delta = Math.floor(minutes / 60);
                  minutes -= (hours_delta * 60);
                  hours += hours_delta;
              }
          } else minutes = 0;
      }
      if (hours >= 0 && minutes >= 0 && minutes < 60) {
          return [val, hours, minutes];
      }
}

function hhmmtofloat( val )
{
    if ((val == null) || (val == ""))
        return 0;
    var re = /^([0-9]+?):([0-9]+)$/;
    var result = re.exec(val);
    if (result == null)
    {
        result = format_hhmm(val);
        if (result == null)
            return 0;
    }
    var hrs = parseFloat(result[1]);
    var mins = parseFloat(result[2]);

    return 60*hrs + mins;
}



function createTDWindow(dest)
{

  var wide = screen.width*(0.35);
  var high = screen.height*(0.3);
  if(wide<150 || high<150)
  {
    wide = 150;
    high = 150;
  }
  var leftpos = screen.width-(wide+20);
  var toppos =  screen.height-(high+60);
  window.open(dest,'test','scrollbars=yes,width='+wide+',height='+high+',left='+leftpos+',top='+toppos);
}

function DoFieldFocus(form)
{
    if (form == null)
        return;
    var i;
    for (i=0;i< form.elements.length;i++)
    {
        var el = form.elements[i];
        if (el.type == "text" || el.type == "select-one" || el.type == "checkbox")
        {
            el.focus();
            return;
        }
    }
}


function clearMultiSelect(sel)
{
    if ( isNLMultiDropDown( sel ) )
        getMultiDropdown( sel ).removeAll();
    else if (sel.type == "select-multiple")
    {
        for ( i=sel.length-1; i >=0 ; i-- )
            sel.options[i].selected = false;
    }
    else
    {
        sel.value='';
        if (sel.form.elements[sel.name+'_display'] != null)
            sel.form.elements[sel.name+'_display'].value='';
    }
}

function getnamevaluelisttext(val,delim,alllabels)
{
    if (val.length == 0)
        return "";
    var nvarray = val.split(String.fromCharCode(4));
    var result = "";
    for (var i=0; i < nvarray.length; i++)
    {
        var nv = nvarray[i].split(String.fromCharCode(3));
        var dv = nv.length==5?nv[4]:nv[3];
        if ((dv != null && dv.length > 0) || alllabels == true)
        {
            if (!isValEmpty(result)) result += delim;
            result += nv[2]+": "+dv;
        }
    }
    return result;
}

function getnamevaluelistdata(val)
{
    if (val.length == 0)
        return "";
    var nvarray = val.split(String.fromCharCode(4));
    var result = "";
    for (var i=0; i < nvarray.length; i++)
    {
        if (i>0)
            result += String.fromCharCode(4);
        var nv = nvarray[i].split(String.fromCharCode(3));
        var v = nv.length>3?nv[3]:"";
        result += nv[0]+String.fromCharCode(3)+v;
    }
    return result;
}

function getnamevaluelistvalue(nvlist,name)
{
    if (nvlist.length == 0)
        return null;
    var nvarray = nvlist.split(String.fromCharCode(4));
    for (var i=0; i < nvarray.length; i++)
    {
        var nv = nvarray[i].split(String.fromCharCode(3));
        if (nv[0].toLowerCase() == name.toLowerCase())
            return nv[3];
    }
    return null;
}

function getnamevaluelistdisplayvalue(nvlist,name)
{
    if (nvlist.length == 0)
        return null;
    var nvarray = nvlist.split(String.fromCharCode(4));
    for (var i=0; i < nvarray.length; i++)
    {
        var nv = nvarray[i].split(String.fromCharCode(3));
        if (nv[0].toLowerCase() == name.toLowerCase())
            return nv.length==5?nv[4]:nv[3];
    }
    return null;
}

function setnamevaluelistvalue(nvlist,name,value)
{
    if (nvlist.length == 0)
        return "";
    var nvarray = nvlist.split(String.fromCharCode(4));
    for (var i=0; i < nvarray.length; i++)
    {
        var nv = nvarray[i].split(String.fromCharCode(3));
        if (nv[0].toLowerCase() == name.toLowerCase())
        {
            nv[3] = value;
            nvarray[i] = nv.join(String.fromCharCode(3));
            break;
        }
    }
    return nvarray.join(String.fromCharCode(4));
}

function syncnamevaluelist(list)
{
    var fldDisp = list.form.elements[list.name+"_display"];
    fldDisp.value = getnamevaluelisttext(list.value,"\n", true);
    if(fldDisp.onchange)
    {
        fldDisp.onchange();
    }
}

function syncpopupmachinefield(machine, fld, line, value)
{
    if (machine == null)
        nlapiSetFieldValue(fld, value);
    else if (line != null)
        nlapiSetLineItemValue(machine, fld, line, value);
    else
        nlapiSetCurrentLineItemValue(machine, fld, value);
}


function NLNameValueList_onKeyPress(evt, sFieldName, sOptionHelperSuffix)
{
    var keyCode = getEventKeypress(evt);

    if( keyCode == 32 ) 
    {
        
        var ndAction = document.getElementById(sFieldName + '_helper_' + sOptionHelperSuffix);
        if( ndAction && ndAction.click)
        {
            ndAction.click();
        }
    }
    return true;
}

function synclist(list,val,makedefault)
{
    if (isNLDropDown(list))
    {
        var dd = getDropdown(list);
        if(dd != null)
        {
            var idx = dd.getIndexForValue(val);
            dd.setIndex(idx, true );
            if (makedefault)
            {
                dd.setDefaultIndex(idx);
                list.setAttribute("defaultValue", val); 
            }
        }
    }
    else if (list.type == 'select-one')
    {
        for (var i=0; i < list.length; i++)
        {
            if (list.options[i].value == val)
            {
                list.selectedIndex=i;
                if (makedefault)
                {                                                                                                                                        
                    list.options[i].defaultSelected = true;
                    list.setAttribute("defaultValue", val); 
                }
                break;
            }
        }
    }
    else
    {
        list.value = val;
        if (makedefault)
            list.setAttribute("defaultValue", val); 

    }
}
function syncpopup(list,val,name,makedefault)
{
    var i;
    if (isNLDropDown(list))
    {
        var dd = getDropdown(list);
        var idx = dd.getIndexForValue(val);
        dd.setIndex(idx, true );
        if (makedefault)
            dd.setDefaultIndex(idx);
    }
    else if (isNLMultiDropDown(list))
    {
        var dd = getMultiDropdown(list);
        dd.setValues(val);
    }
    else if (list.type == "select-one" || list.type == "select-multiple")
    {
        for (i=0; i < list.length; i++)
        if (list.options[i].value == val)
        {
            list.selectedIndex=i;
            if (makedefault)
                list.options[i].defaultSelected = true;
            break;
        }
    }
    else if ( isPopupSelect( list ) )
    {
        list.value = val;
        if (makedefault)
            list.defaultValue = val;
        var dispfld = list.form.elements[list.name+"_display"];
        if ((val != null && val.length > 0) || (name != null && name.length > 0))
        {
            if (typeof name != "undefined" && name != null)
            {
                dispfld.value = name;
                dispfld.style.color='#000000';
                if (makedefault)
                    dispfld.defaultValue = name;
            }
        }
        else if (list.getAttribute('onlyAllowExactMatch') == null)
        {
            dispfld.value = dispfld.type == 'text' ? _popup_help : _mult_popup_help;
            dispfld.style.color='#999999';
        }
    }
    else
    {
        list.value = val;
        if (makedefault)
            list.defaultValue = val;
    }
}

function syncmultiselectlist(list,val,labels, bDontFireOnChange)
{
    clearMultiSelect(list);
	if ( typeof val != "string" && !isArray(val) )
		val = ""+val;
	if (isNLMultiDropDown(list))
    {
        if ( typeof val != "string" )
            val = val.join( String.fromCharCode(5) );
        var dd = getMultiDropdown(list);
        dd.setValues(val, bDontFireOnChange);
    }
    else if (list.type != "select-multiple")
    {
        list.form.elements[list.name].value = val;
		labels = emptyIfNull(labels);
		var delimiter = labels.indexOf(String.fromCharCode(5)) != -1 ? String.fromCharCode(5) : "\n"
		var labelsfld = list.form.elements[list.name+"_labels"];
		if (labelsfld != null)
			labelsfld.value = isValEmpty(val) ? "" : labels.split(delimiter).join(String.fromCharCode(5));
		var displayfld = list.form.elements[list.name+"_display"];
		if (displayfld != null && list.getAttribute('onlyAllowExactMatch') == null)
			displayfld.value = labels ? labels.split(delimiter).join('\n') : _mult_popup_help;
    }
    else
    {
        if ( typeof val == "string" )
            val = val.split( String.fromCharCode(5) );
        for ( var i=0; i < val.length; i++)
        {
            for ( var j=0; j < list.length; j++)
            {
                if (list.options[j].value == val[i])
                    list.options[j].selected = true;
            }
        }
    }
}



function syncradio(radio,val,makedefault)
{
    var i;
    var selected;
    for (i=0; i < radio.length; i++)
    {
     	selected = radio[i].value == val;
		radio[i].checked=selected;
		if (makedefault)
			radio[i].defaultChecked = selected;
    }
}
function getlisttext(list, val, frommultisel)
{
    if (isNLDropDown(list))
        return getDropdown(list).getTextForValue(val);
    if (list.type != "select-one" && !frommultisel)
        return '';
    for (var i=0; i < list.length; i++)
        if (list.options[i].value == val)
            return list.options[i].text;
    return "";
}
function getmultiselectlisttext(list, val, delim)
{
    if (!delim)
        delim = '<br>';

    if ( isNLMultiDropDown(list) )
    {
        return getMultiDropdown(list).getSelectedTextFromValues(val, delim);
    }
    else if (list.type != "select-multiple")
    {
        return '';
    }
    else
    {
        var selvals = val.split(String.fromCharCode(5));
        var label = '';
        for (var i=0; i < selvals.length; i++)
        {
            if (i > 0) label += delim;
                label += getlisttext(list, selvals[i], true);
        }
        return label;
    }
}
function getradiotext(radio, val)
{
    var i;
    for (i=0;i< radio.length;i++)
        if (radio[i].value == val)
            return radio[i].textValue;
    return "";
}
function getRadioValue(radio)
{
    var val = '';
    if (typeof radio.length=="undefined") 
        radio = radio.ownerDocument.getElementsByName(radio.name);
    for (var i=0; i < radio.length; i++)
    {
        if (radio[i].checked == true)
        {
            val = radio[i].value;
            break;
        }
    }
    return val;
}
function getSelectedRadio(radio)
{
    var val = null;
    if (typeof radio.length == "undefined") 
        radio = radio.ownerDocument.getElementsByName(radio.name);
    for (var i=0; i < radio.length && val == null; i++)
		val = radio[i].checked ? radio[i] : null;
    return val;
}


function getSelectValue(sel)
{
    var returnMe;
    if (sel.type != null && sel.type == "select-one")
        returnMe = (sel.options.length == 0 || sel.selectedIndex == -1 || sel.selectedIndex >= sel.options.length) ? '' :  sel.options[sel.selectedIndex].value;
    else if (isMultiSelect(sel))
        returnMe = getMultiSelectValues(sel);
    else if (isNLDropDown(sel))
        returnMe = getDropdown(sel).getValue();
    else if (isNLMultiDropDown(sel))
        returnMe = getMultiDropdown(sel).getSelectedValues();
    else
        returnMe = sel.value;
    return returnMe;
}
function getSelectValueArray(sel)
{
    var returnMe;
    if (sel.type == "select-one" || sel.type == "select-multiple")
    {
        returnMe = new Array(sel.length);
        for ( var i = 0; i < sel.length; i++ )
            returnMe[i] = sel.options[i].value;
    }
    else if (isNLDropDown(sel))
        returnMe = getDropdown(sel).valueArray;
    else if (isNLMultiDropDown(sel))
        returnMe = getMultiDropdown(sel).valueArray;
    return returnMe;
}

function getIndexForValue(sel,val)
{
    var returnMe=-1;
    if (sel.type == "select-one" || sel.type == "select-multiple")
    {
        for ( var i = 0; i < sel.length; i++ )
            if(sel.options[i].value==val)
            {
                returnMe=i;
                break;
            }
    }
    else if (isNLDropDown(sel))
        returnMe = getDropdown(sel).getIndexForValue(val);
    else if (isNLMultiDropDown(sel))
        returnMe = getMultiDropdown(sel).getIndexForValue(val);
    if (typeof(returnMe) == "undefined")
     	returnMe = -1;
	return returnMe;

}
function getSelectTextForValue(  sel, val )
{

    var textArray = getSelectValueArray(sel);
    var i;
    for (i = 0; i < textArray.length; i++)
    {
        if (textArray[i] == val)
            return getSelectTextAtIndex(sel, i);
    }
    return null;

}
function getSelectTextArray(sel)
{
    var returnMe;
    if (sel.type == "select-one" || sel.type == "select-multiple")
    {
        returnMe = new Array(sel.length);
        for ( var i = 0; i < sel.length; i++ )
            returnMe[i] = sel.options[i].text;
    }
    else if (isNLDropDown(sel))
        returnMe = getDropdown(sel).textArray;
    else if (isNLMultiDropDown(sel))
        returnMe = getMultiDropdown(sel).textArray;
    return returnMe;
}
function getSelectText(sel, returnArray)
{
	var val = getSelectValue(sel);
	if (sel.type == "select-one")
        return (sel.options.length == 0 || sel.selectedIndex == -1 || sel.selectedIndex >= sel.options.length) ? null : sel.options[sel.selectedIndex].text;
    else if (isNLDropDown(sel))
        return getDropdown(sel).getText();
    else if ( isMultiSelect(sel) || isPopupMultiSelect( sel ) )
        return getMultiSelectText( sel, null, returnArray );
    else if ( isPopupSelect( sel ) )
        return isValEmpty(val) ? '' : getFormElement(sel.form,sel.name+'_display').value.replace(/\s$/,'');
    else if ( isDisplayOnlySelect( sel ) )
        return getInlineTextValue(document.getElementById(sel.name+"_displayval"));
    else
        return sel.text;
}
function setSelectValue(sel, val)
{
    if (window.virtualBrowser)
    {
        sel.value = val;
    }
    else if (isNLDropDown(sel))
    {
        var dd = getDropdown(sel);
        var idx = dd.getIndexForValue(val);
        if (idx == null)
            return false;
        dd.setIndex(idx, true );
        
        if(dd.isOpen)
            dd.setCurrentCellInMenu(dd.divArray[idx]);

    }
    else if (isNLMultiDropDown(sel))
    {
        var dd = getMultiDropdown(sel);
        var idx = dd.getIndexForValue(val);
        if (idx == null)
            return false;
        dd.setIndex(idx);
    }
    else if (sel.type == "select-one")
    {
        var opt = sel.options;
        for (var i=0; i < opt.length; i++)
        {
            if (opt[i].value==val)
            {
                sel.selectedIndex=i;
                return true;
            }
        }
        return false;
    }
    else if (sel.type == "select-multiple")
    {
        var opts = sel.options;
        var result = false;
        for (var i=0; i < opts.length; i++)
        {
            opts[i].selected = opts[i].value == val;
            result = result || opts[i].value == val;
        }
        return result;
    }
    else
    {
        sel.value = val;
        if (val.length == 0 && isPopupSelect( sel ) )
        {
            var dispfld = sel.form.elements[sel.name+"_display"];
            dispfld.value = dispfld.type == 'text' ? _popup_help : _mult_popup_help;
            dispfld.style.color = '#999999';
        }
    }
    return true;
}

function addMultiSelectValue(sel, val, name)
{
    if (isNLMultiDropDown(sel))
    {
        var dd = getMultiDropdown(sel);
        var idx = dd.getIndexForValue(val);
        dd.addIndex(idx);
    }
    else if (sel.type == "select-multiple")
    {
        var opts = sel.options;
        for (var i=0; i < opts.length; i++)
            if ( opts[i].value == val )
                opts[i].selected = true;
    }
    else
    {
        var values = sel.value.split(String.fromCharCode(5));
        for (var i=0;i < values.length;i++)
            if (values[i] == val) return;
        sel.form.elements[sel.name+"_display"].style.color = '#000000';
        if (values.length == 0 || values[0].length == 0)
        {
            sel.value = val;
            sel.form.elements[sel.name+"_display"].value = name;
            sel.form.elements[sel.name+"_labels"].value = name;
        }
        else
        {
            sel.value += String.fromCharCode(5)+val;
            sel.form.elements[sel.name+"_labels"].value += String.fromCharCode(5)+name;
            var lines = sel.form.elements[sel.name+"_display"].value.split(/\n|\r/);
            if (lines.length == values.length)
                sel.form.elements[sel.name+"_display"].value += "\n"+name;
            else
            {
                lines[values.length] = name;
                sel.form.elements[sel.name+"_display"].value = lines.join("\n");
            }
        }
    }
}


function getCurrentMultiSelectUserInputValue (inputField)
{
    var selectionStartPos = getSelectedTextRange(inputField)[0];
    var subStrBefore = inputField.value.substr(0, selectionStartPos);
    var startPos = Math.max(subStrBefore.lastIndexOf('\n'), subStrBefore.lastIndexOf('\r')) + 1;
    var endPos = inputField.value.substr(selectionStartPos).search(/\n|\r/);
    endPos = endPos == -1? inputField.value.length : selectionStartPos + endPos;
    userEnteredValue = inputField.value.substring(startPos, endPos);
    return userEnteredValue;
}

function getSelectValueForText(sel, txt)
{
    var textArray = getSelectTextArray(sel);
    var i;
    for (i = 0; i < textArray.length; i++)
    {
        if (textArray[i] == txt)
            return getSelectValueAtIndex(sel, i);
    }
    return null;
}

function deleteAllSelectOptions(sel, win)
{
    if (isNLDropDown(sel))
    {
        getDropdown(sel, win).deleteAllOptions();
    }
    else if (isNLMultiDropDown(sel))
    {
        getMultiDropdown(sel, win).deleteAllOptions();
    }
    else if (sel.type == 'select-one' || sel.type == 'select-multiple')
    {
        sel.options.length = 0;
    }
    else if ( sel.form.elements[sel.name+"_display"] != null )
    {
        sel.form.elements[sel.name+"_display"].value = "";
        sel.value = "";
    }
}


function deleteOneSelectOption(sel, value, bDontSetWidth)
{
    if (isNLDropDown(sel))
    {
        getDropdown(sel).deleteOneOption(value, bDontSetWidth);
    }
    else if (isNLMultiDropDown(sel))
    {
        getMultiDropdown(sel).deleteOneOption(value);
    }
    else if (sel.type == 'select-one' || sel.type == 'select-multiple')
    {
        var opts = sel.options;
        for (var i=0; i < opts.length; i++)
            if (opts[i].value == value)
                opts[i] = null;
    }
    else if ( sel.form.elements[sel.name+"_display"] != null )
    {
        sel.form.elements[sel.name+"_display"].value = "";
        sel.value = "";
    }
}

function getSelectIndex(sel,win)
{
    if (isNLDropDown(sel))
    {
        return getDropdown(sel,win).getIndex();
    }
    else
    {
        return sel.selectedIndex;
    }
}
function setSelectIndex(sel, val)
{
    if (isNLDropDown(sel))
    {
        return getDropdown(sel).setIndex(val, true );
    }
    else if (isNLMultiDropDown(sel))
    {
        return getMultiDropdown(sel).setIndex(val);
    }
    else
    {
        sel.selectedIndex = val;
    }
}
function setMultiSelectValues(sel, val)
{
    syncmultiselectlist( sel, val );
}
function getMultiSelectValues( sel, returnArray )
{
    var val = null;
    if (isMultiSelect(sel))
    {
        if ( isNLMultiDropDown(sel) )
            val = getMultiDropdown(sel).getSelectedValues();
        else
        {
            val = '';
            for (var i=0; i < sel.length; i++)
            {
                if (sel.options[i].selected)
                    val += ((val == '' ? '' : String.fromCharCode(5)) + sel.options[i].value);
            }
        }
    }
    else
        val = sel.value;
    return returnArray ? (isValEmpty( val ) ? [] : val.split( String.fromCharCode(5) )) : val;
}
function getMultiSelectText(sel,inmachine,returnArray)
{
	var val = '';
	var delim = returnArray ? String.fromCharCode(5) : ", ";
	if ( isMultiSelect(sel) )
    {
		delim = inmachine ? '\n' : delim;
		if ( isNLMultiDropDown(sel) )
            val = getMultiDropdown(sel).getSelectedText( delim );
        else
        {
            var i, numParams = 0;
            for (i=0; i < sel.length; i++)
            {
                if (sel.options[i].selected)
                    val += ((numParams++ == 0 ? '' : ( delim )) + sel.options[i].text);
            }
        }
    }
    else if ( isPopupMultiSelect( sel ) )
    {
        val = getFormElement(sel.form,sel.name+'_labels').value;
        if ( val != null && delim != String.fromCharCode(5) )
            val = val.replace( new RegExp( String.fromCharCode(5), "g" ), delim )
    }
    else
        val = sel.text;
	return returnArray ? (isValEmpty( val ) ? [] : val.split( delim )) : val;
}
function updateMultiSelectValue(fld,displayfld,val,displayval,labelsfld)
{
    fld.value = val;
    labelsfld.value = displayval;
    var sellabels = displayval.split(String.fromCharCode(5));
    var displaytempval = '', numParams = 0;
    for (i=0; i < sellabels.length; i++)
    {
        displaytempval += ((numParams==0 ? '' : '\n') + sellabels[i]) ;
        numParams++;
    }
    displayfld.value = displaytempval;
}

function addSelectOption(doc,sel,text,value,selected,win,idx)
{

    if (isNLDropDown(sel))
	{
		var dd = getDropdown(sel,win);
        if (dd == null)
            return;

		dd.addOption(text, value, idx);
		if (selected !== false)
		{
			var idx = dd.getIndexForValue(value);
			dd.setIndex(idx, true );
		}
	}
	else if (isNLMultiDropDown(sel))
	{
		var dd = getMultiDropdown(sel,win);
        if (dd == null)
            return;

		dd.addOption(text, value, selected, idx);
	}
	else
	{
		var opt = doc.createElement('OPTION');
		opt.text= text;
		opt.value= value;
		if (isIE)
        {
            if (typeof(idx)=='undefined') idx = sel.length;
            sel.add(opt, idx);
        }
		else
        {
            var optInsertBefore = null;
            if (typeof(idx)!='undefined' && idx >=0 && idx < sel.length)
                optInsertBefore = sel.options[idx];
            sel.add(opt, optInsertBefore);
        }
		if (selected !== false)
		{
			opt.selected = true;
			
			if (isIE)
				sel.selectedIndex = idx;
		}
	}

}

function setSelectOptionText(sel,value,text,win)
{
    if (isNLDropDown(sel))
    {
        var dd = getDropdown(sel,win);
        dd.setOptionText(value,text);
    }
    else if (sel.type == 'select-one' || sel.type == 'select-multiple')
    {
        var opts = sel.options;
        for (var i=0; i < opts.length; i++)
            if (opts[i].value == value)
                opts[i].text = text;
    }
}


function getCascadedStyle(object, property, attribute)
{
    if ( object.currentStyle )
        return object.currentStyle[property];
    else if ( window.getComputedStyle )
    {
        
        if ( object.nodeType != 1 )
            return null;
        var objStyle = window.getComputedStyle(object, "");
        if (objStyle)
            return objStyle.getPropertyValue( attribute );
    }
    return null;
}

function isFocusable( fld )
{
    if ( fld == null || (typeof fld.type == "undefined" && !isNLDropDownSpan(fld)) || fld.type == "hidden" || fld.disabled || fld.type == "button")
        return false;
    return elementIsFocusable(fld);
}


function elementIsFocusable(elem)
{
    while ( elem != null )
    {
        var visibility = getCascadedStyle(elem, "visibility", "visibility");
        var display = getCascadedStyle(elem, "display", "display");
        if ( display == 'none' || visibility == 'hidden' || visibility == 'hide' )
            return false;
        elem = elem.parentNode;
    }
    return true;
}


function NLIsButton(elem)
{
    if (elem)
    {
        if (elem.tagName == "BUTTON" || (elem.tagName == "INPUT" && ( elem.type == "submit" || elem.type == "button" || elem.type == "reset")))
            return true;
    }
    return false;
}

function NLIsSubmitButton(elem)
{
	if (elem)
    {
    	if (elem.tagName == "INPUT" && elem.type == "submit" )
        	return true;
    }
    return false;
}

function NLDisableButton(elem, val)
{
    elem.disabled = val;
    if (elem.className.indexOf("nlbutton") >= 0 || elem.className.indexOf("bgbutton") >= 0 || elem.className.indexOf("nlinlineeditbutton") >= 0)
        elem.className = elem.className.split("Disabled")[0] + (val ? "Disabled" : "");
        
        
    
    if ((elem.className.indexOf('bntBgT') >= 0) && (elem.name))
    {
        var trElem = document.getElementById('tr_' + elem.name);
        if (trElem && trElem.className)
        {
        	if (val)
        	{
        		
        		if (trElem.className.indexOf('Dis') < 0)
        			trElem.className = trElem.className +'Dis';
        	}
        	else
        		trElem.className = trElem.className.replace('Dis', '');
        
        }
    }
}

 
 
function NLInvokeButton(elem)
{
	if (elem)
    {
    	
    	if (elem.disabled)
    		return;

        elem.click();

    }

}

function NLAddButtonDisabledMessage(container, name, message)
{
	var obj = document.getElementById(container);
    var elem = document.getElementById(name);
	if (obj == null || elem == null)
		return;

	var positionX = findGlobalPosX(obj);
	var positionY = findGlobalPosY(obj);
	var objWidth = obj.offsetWidth;
	var objHeight = obj.offsetHeight;
	
	var tDiv = document.createElement('div');
	tDiv.style.position = "absolute";
	tDiv.style.left = positionX + 'px';
	tDiv.style.top = positionY + 'px';
	tDiv.style.width = objWidth  + 'px';
	tDiv.style.height = objHeight  + 'px';
	tDiv.style.background = '#000000';
	tDiv.style.opacity = '0';
	tDiv.style.zindex = '100';
	
	attachEventHandler('mouseover', tDiv, function(){ nlShowMessageTooltip(elem, message);} );
	attachEventHandler('mouseout', tDiv, function(){ closePopup();} );
    attachEventHandler('click', tDiv, function() {if (!elem.disabled)	elem.onClick();} );

	obj.appendChild(tDiv);		
}

function getSubmitButton(name, value)
{
    var allInputs = document.getElementsByName(name);
    for (var i = 0; i < allInputs.length; i++)
    {
        var input = allInputs[i];
        if (NLIsSubmitButton(input) && (value == null || value == input.value))
        {
            return input;
        }
    }

    return null;
}

function isDisplayOnlySelect(sel)
{
    return sel != null && sel.type == "hidden" && document.getElementById(sel.name+'_displayval' ) != null;
}
function isPopupSelect(sel)
{
    return sel != null && sel.type == "hidden" && getFormElement(sel.form, sel.name+'_display' ) != null && getFormElement(sel.form, sel.name+'_display' ).type == "text";
}
function isPopupMultiSelect(sel)
{
    return sel != null && sel.type == "hidden" && getFormElement(sel.form, sel.name+'_display' ) != null && getFormElement(sel.form, sel.name+'_display' ).type == "textarea" && getFormElement(sel.form, sel.name+'_labels' ) != null;
}

function NLPopupSelect_setExactMatchQuery(sel, b)
{
    sel.setAttribute('exactMatchQuery', b ? 'T' : 'F');
}
function NLPopupSelect_getExactMatchQuery(sel)
{
    return sel.getAttribute('exactMatchQuery') == 'T';
}
function isSelect(sel)
{
    return  sel != null && ( sel.type == "select-one" || isNLDropDown( sel ) );
}
function isNLDropDown(sel)
{
    return sel.className && sel.className.indexOf('nldropdown')>=0;
}
function isNLDropDownSpan(span)
{
    return span != null && span.tagName == 'SPAN' && window.getDropdown != null && getDropdown(span) != null;
}
function isMultiSelect(sel)
{
    return  sel != null && (isNLMultiDropDown(sel) || sel.multiple || sel.type == 'select-multiple');
}
function isNLMultiDropDown(sel)
{

    return sel != null && sel.getAttribute && !isValEmpty(sel.getAttribute("nlmultidropdown"));
}
function isRichTextEditor(fld)
{
	return  fld != null && window.getHtmlEditor != null && getHtmlEditor( fld.name ) != null;
}

/*
This method detects the rich text even in case it has not been registered yet.
*/
function isRichTextEditorUnregisteredSafe(fld)
{
	if (fld == null)
		return false;
    return fld.className != null && fld.className.indexOf('rteditor') != -1;
}

function isSummaryField(fld)
{
	return  fld.className && fld.className.indexOf('nlsummary')>=0;
}

function resetlist(sel)
{
    if ( sel != null )
    {
        if (sel.type == "select-one" || sel.type == 'select-multiple')
        {
            var i;
            for (i=0; i < sel.length; i++)
            {
                if (sel.options[i].defaultSelected)
                {
                    sel.selectedIndex=i;
                    return;
                }
            }
            sel.selectedIndex=0;
        }
        else if (isNLDropDown(sel))
        {
            getDropdown(sel).resetDropDown();
        }
        else if (isNLMultiDropDown(sel))
        {
            getMultiDropdown(sel).resetDropDown();
        }
        else
        {
            sel.value = sel.defaultValue;
            sel.form.elements[sel.name+"_display"].value = sel.form.elements[sel.name+"_display"].defaultValue;
        }
    }
}

function setFieldFocus(fld)
{
    if ( isSelect( fld ) || isMultiSelect( fld ) || isPopupSelect( fld ) || isPopupMultiSelect( fld ) )
        setSelectFocus( fld )
    else if ( window.getHtmlEditor != null && window.getHtmlEditor( fld.name ) != null )
        window.getHtmlEditor( fld.name ).setFocus();
    else if ( isFocusable( fld ) )
        fld.focus();
}

function setSelectFocus(sel,win)
{
    if ( sel != null )
    {
        if (sel.type == "select-one" || sel.type == "select-multiple")
        {
            if ( isFocusable( sel ) )
                sel.focus();
        }
        else if (isNLDropDown(sel))
        {
            if ( isFocusable( getDropdown(sel,win).getContainer( ) ) )
                getDropdown(sel,win).setFocus();
        }
        else if (isNLMultiDropDown(sel))
        {
            if ( isFocusable( getMultiDropdown(sel,win).getContainer( ) ) )
                getMultiDropdown(sel,win).setFocus();
        }
        else
        {
            if ( isFocusable( sel.form.elements[sel.name+"_display"] ) )
                sel.form.elements[sel.name+"_display"].focus();
        }
    }
}


function restoreSelectToOriginalValue(sel, win)
{
    if(sel != null)
    {
        if (sel.type == "select-one" || sel.type == "select-multiple")
        {
            var valueWhenRendered = sel.getAttribute("valuewhenrendered");
            if(valueWhenRendered != null && valueWhenRendered.length > 0)
                setSelectValue(sel, valueWhenRendered);
        }
        else if (isNLDropDown(sel))
        {
            getDropdown(sel, win).restoreToOriginalValue();
        }
    }
}

function getSelectValueAtIndex(sel, idx)
{
    if ( sel != null )
    {
        if (sel.type == "select-one" || sel.type == "select-multiple")
        {
            if ((sel.options != null) && (sel.options.length > idx))
                return sel.options[idx].value;
            else
                return null;
        }
        else if (isNLDropDown(sel))
        {
            return getDropdown(sel).getValueAtIndex(idx);
        }
        else if (isNLMultiDropDown(sel))
        {
            return getMultiDropdown(sel).getValue(idx);
        }
    }
}

function getSelectTextAtIndex(sel, idx)
{
    if ( sel != null )
    {
        if (sel.type == "select-one" || sel.type == "select-multiple")
        {
            if ((sel.options != null) && (sel.options.length > idx))
                return sel.options[idx].text;
            else
                return null;
        }
        else if (isNLDropDown(sel))
        {
            return getDropdown(sel).getTextAtIndex(idx);
        }
        else if (isNLMultiDropDown(sel))
        {
            return getMultiDropdown(sel).getText(idx);
        }
    }
}


function setNLCheckboxValue( fld, value)
{
	if (!fld)
    	return;
    
    if (typeof(value) == 'string')
	    fld.checked = value == 'T';
	else
    	fld.checked = value;
        
    
    NLCheckboxOnChange(fld);
}


function getNLCheckboxValue( fld )
{
	if (!fld)
    	return;

	return fld.checked;
}

function getNLCheckboxSpan(fld)
{
	var span = fld.parentNode;
    if (span && span.nodeName == 'SPAN' && span.className && (span.className.indexOf('checkbox') == 0))
    	return span;

	return null;
}

function setNLCheckboxDisabled( fld, bDisabled)
{
	if (!fld || fld.type != 'checkbox')
		return;

	var sClassName = 'checkbox'+(bDisabled? '_disabled' : '')+(fld.checked? '_ck' : '_unck');
	fld.disabled = bDisabled;

	var span = getNLCheckboxSpan(fld);
    if (span)
	    span.className = sClassName;	
}

function setNLCheckboxReadOnly(fld, bReadOnly)
{
	if (!fld || fld.type != 'checkbox')
		return;

	var sClassName = 'checkbox'+(bReadOnly? '_read' : '')+(fld.checked? '_ck' : '_unck');
	fld.readonly = bReadOnly;

	var span = getNLCheckboxSpan(fld);
    span.className = sClassName;	
}


function NLCheckboxOnClick(span)
{
    var origSpanClass = span.className;
	var inpt = null;
    
	// Find the input.
    for (var i=0; i<span.childNodes.length; i++)
    {
    	if (span.childNodes[i].type == 'checkbox')
        {
        	inpt = span.childNodes[i]; 
            break;
        }
	}            
    
    if (!inpt || inpt.disabled)
		return;    
    
	if (inpt.type == 'checkbox' && inpt.checked) {
        
	    span.className = span.className.replace('_ck', '_unck');
		inpt.checked = false;
	}
	else {
        
	    span.className = span.className.replace('_unck', '_ck');
		inpt.checked = true;
	}

    inpt.focus();

    	
	var origChecked = inpt.checked;
	if (inpt.onclick)
        inpt.onclick();
	var newChecked = inpt.checked;
    
    
    if (origChecked != newChecked)
    	span.className = origSpanClass;
    else if (inpt.onchange)
    	inpt.onchange();
}


function NLCheckboxOnChange(fld)
{
    if (!fld)
		return;
	
	var span = getNLCheckboxSpan(fld);
    if (span)
    {
        if (fld.checked)
            span.className = span.className.replace('_unck', '_ck'); 
        else
            span.className = span.className.replace('_ck', '_unck');
    }
}

function NLCheckboxSetParentState(fld, state)
{
    if (!fld)
		return;
	
	var span = getNLCheckboxSpan(fld);
    if (span)
    {
    	if (state)
			span.className = span.className.replace('_unck', '_ck'); 
    	 else
       		 span.className = span.className.replace('_ck', '_unck');
     }
}

function NLCheckboxOnKeyPress(evt)
{
	if(window.event) // IE
	{
    	evt = getEvent(evt);
		if(evt.keyCode == 32 && evt.srcElement) 
        {
           if (evt.srcElement.onclick)  evt.srcElement.onclick();
    		NLCheckboxSetParentState(evt.srcElement, !evt.srcElement.checked);
        }
	}
    
    return true;
}


function getNLSummaryFieldContent(fld)
{
	if (!isSummaryField(fld))
		return "";

    var docObj = (fld.document) ? fld.document : document;
    var textElement = docObj.getElementById(fld.id+"_val");
    if(textElement && textElement.parentNode)
        return textElement.parentNode.innerHTML;
     return "";
}


function setNLSummaryFieldTextValue(fld, val)
{
    if (!isSummaryField(fld))
        return "";

    var docObj = (fld.document) ? fld.document : document;
    var textElement = docObj.getElementById(fld.id+"_val");
    if(textElement)
        textElement.innerHTML = val;
}

function getNLSummaryFieldTextValue(fld)
{
	if (!isSummaryField(fld))
		return "";

    var docObj = (fld.document) ? fld.document : document;
    var textElement = docObj.getElementById(fld.id+"_val");
    if(textElement)
        return textElement.innerHTML;
     return "";
}

function setNLSummaryFieldDisabled( fld, bDisabled)
{
	if (!isSummaryField(fld))
		return;

	fld.disabled = bDisabled;

    var docObj = (fld.document) ? fld.document : document;
    var helperLink = docObj.getElementById(fld.name+"_helper_popup");
    if(helperLink != null)
        helperLink.style.visibility = bDisabled ? "hidden" : "inherit";
}


function isNLNumericOrCurrencyDisplayField( fld )
{
    if (!fld)
        return false;
    if (!(isNumericField(fld) ||isCurrencyField(fld)))
        return false;

    return (fld.name.indexOf("_formattedValue")>0);
}

function getNLNumericOrCurrencyDisplayField( fld )
{
    if (!fld) {
        return null;
    }

    var name = fld.name+"_formattedValue";
    return findNLNumericFieldByName(fld, name);
}

function getNLNumericOrCurrencyValueField( fld )
{
    if (!fld) {
        return null;
    }

    var name = fld.name.replace("_formattedValue", "");
    return findNLNumericFieldByName(fld, name);
}

function findNLNumericFieldByName(fld, name) {
    if (!fld.form) {
        var elements = fld.ownerDocument.getElementsByName(name);
        for(var i = 0; i < elements.length; i++) {
            if(elements[i].parentNode == fld.parentNode) {
                return elements[i];
            }
        }
        return fld.ownerDocument.getElementById(name);
    }
    return fld.form.elements[name];
}

function isCurrencyField( fld )
{
    if (!fld)
        return false;
    var dataType = "";
    if(typeof fld.getAttribute != 'undefined')
        dataType = fld.getAttribute("dataType");
    if (dataType == "currency" || dataType == "poscurrency" || dataType == "currency2")
        return true;
    return false;
}

function setNLCurrencyValue(fld, value)
{
    fld.value = value;
    var displayField = getNLNumericOrCurrencyDisplayField(fld);
    if (!displayField)
        return;
    displayField.value = NLNumberToString(value);
}

function isNumericField( fld )
{
    if (!fld)
        return false;
    var dataType = "";
    if(typeof fld.getAttribute != 'undefined')
        dataType = fld.getAttribute("dataType");
    if (dataType == "float" || dataType == "posfloat" || dataType == "nonnegfloat" || dataType == "integer" || dataType == "posinteger" || dataType == "rate" || dataType == "ratehighprecision" || dataType == "percent")
        return true;
    return false;
}

function setNLNumericValue(fld, value)
{
    fld.value = value;
    var displayField = getNLNumericOrCurrencyDisplayField(fld);
    if (!displayField)
        return;
    displayField.value = NLNumberToString(value);
}

function setNLNumericOrCurrencyFieldDisabled(fld, val)
{
    var displayField = getNLNumericOrCurrencyDisplayField(fld);
    if (!displayField)
        return;
    displayField.disabled = val;
}

function getNLNumericOrCurrencyFieldDisabled(fld)
{
    var displayField = getNLNumericOrCurrencyDisplayField(fld);
    if (!displayField)
        return false;
    return displayField.disabled;
}


function setDefaultOrNotRequired(fld, val)
{
    setRequired(fld, val ? getRequired(fld) : false);
}

function hasAttribute(fld,flag)
{
    if ( isNLDropDown(fld) )
        return getDropdown(fld).hasAttribute(flag);
    else if ( isNLMultiDropDown( fld ) )
        return getMultiDropdown(fld).hasAttribute(flag);
    else if ( window.getHtmlEditor != null && getHtmlEditor( fld.name ) != null )
        return getHtmlEditor(fld.name).hasAttribute(flag);
    else
        return (fld.getAttribute("flags") & flag) != 0;
}

function disableField(fld, val)
{

    if (fld == null)
        return;
    
    
    if (!isSelect( fld ) && fld.length > 1)
    {
        for ( var i = 0; i < fld.length; i++ )
            if ( fld[i].type == 'radio' )
                disableField( fld[i], val);
		return;
    }
    else if (isSelect( fld ) || isPopupSelect( fld ) || isMultiSelect( fld ) || isPopupMultiSelect(fld))
        disableSelect(fld, val);
    else if ( window.getHtmlEditor != null && getHtmlEditor( fld.name ) != null )
        getHtmlEditor( fld.name ).setDisabled( val );
    else if (NLIsButton( fld ))
        NLDisableButton(fld, val);
    else if (fld.type=='checkbox')
        setNLCheckboxDisabled(fld, val);
    else if (isSummaryField(fld))
        setNLSummaryFieldDisabled(fld, val);
    else if (isNumericField(fld) || isCurrencyField(fld))
        setNLNumericOrCurrencyFieldDisabled(fld, val);
    else
    {
        fld.disabled = val;
        
        var docObj = (fld.document) ? fld.document : document;
        var datelink = docObj.getElementById(fld.name+"_helper_calendar");
        if(datelink != null)
            datelink.style.visibility = val ? "hidden" : "inherit";
    }


	
}

function getFieldDisabled(fld)
{
    if (fld == null)
        return;
    
    
    if (!isSelect( fld ) && fld.length > 1)
    {
        for ( var i = 0; i < fld.length; i++ )
            if ( fld[i].type == 'radio' )
                return fld[i].disabled;
    }
    else if (isSelect( fld ) || isPopupSelect( fld ) || isMultiSelect( fld ))
	{
		if (fld.type == "select-one" || fld.type == "select-multiple")
			return fld.disabled;
		else if (isNLDropDown(fld))
			return getDropdown(fld, window).disabled;
		else if (isNLMultiDropDown(fld))
			return getMultiDropdown(fld, window).disabled;
		else if ( isPopupSelect( fld ) )
			return getFormElement(fld.form, fld.name+'_display' ).disabled
	}
    else if ( window.getHtmlEditor != null && getHtmlEditor( fld.name ) != null )
        return getHtmlEditor( fld.name ).disabled;
    else if (isNumericField(fld) || isCurrencyField(fld))
        return getNLNumericOrCurrencyFieldDisabled(fld);
    else
        return fld.disabled;
	return false;
}

function setFieldReadOnly(fld, val)
{
	if (fld != null && fld.type == "textarea")
	{
		fld.readOnly = val;
	}

	
}

function isDisplayOnlyField(fld)
{
    if (fld == null)
        return;
	if ( isDisplayOnlySelect(fld) )
		return true;
	else if (fld.type == "hidden" && document.getElementById(fld.name+'_val') != null)
		return true;
	return false;
}

function setOptionsFromMachineField( machine_name, field_name, selectObject, alternate_label, test_field, test_value )
{
    deleteAllSelectOptions( selectObject, window );
    var doc = window.document;
    var mch = eval( machine_name + '_machine');
    addSelectOption( doc, selectObject, "",  "", true, window );
    var bNewOptions = false;
    for ( var i = 1; i <= getLineCount(machine_name); i++)
    {
        if (mch.getMachineIndex() == i || ( test_field != null && getEncodedValue( machine_name, i, test_field) != test_value ) )
            continue;
        bNewOptions = true;
        addSelectOption( doc, selectObject,  getEncodedValue( machine_name,i, alternate_label != null ? alternate_label :field_name + '_display'),  getEncodedValue( machine_name,i,field_name ), false, window);
    }
    return bNewOptions;
}


function getSyncFunctionName(fldname, machine)
{
    var syncFuncName = "Sync"+fldname;
    if ( machine != null )
    {
        var machSyncFunc = syncFuncName + machine;
        if ( eval( "window." + machSyncFunc ) != null )
            return machSyncFunc;
    }
    return syncFuncName;
}

function safeSetDocumentLocation(url)
{
    try {
        document.location = url;
    } catch (e) {}
}

function addParamToURL(url, param, value,replace)
{
    if ( url == null )
        return null;
    if (url.length && url.charAt(url.length - 1) == '#')
        url = url.substring(0, url.length - 1);
    if (url.length && url.indexOf('#') > -1)
        url = url.substring(0, url.indexOf('#'));
    if ( isValEmpty( param ) )
        return url;
    if (replace == true)
        url = removeParamFromURL(url,param);
    return addNextParamPrefixToURL( url ) + param + "=" + emptyIfNull(value);
}

function addNextParamPrefixToURL( url )
{
    return url + ( url.indexOf("?") == -1 ? "?" : "&" );
}

function removeParamFromURL(url, param)
{
    var sep = "&";
    var startIndex = url.indexOf("&"+param+"=");
    if (startIndex == -1)
    {
        startIndex = url.indexOf("?"+param+"=")
        sep = "?";
    }
    if (startIndex != -1)
    {
        var endIndex = url.indexOf("&",startIndex+1);
        return url.substring(0,startIndex)+ (endIndex > 0 ? (sep == "?" ? "?"+url.substr(endIndex+1) : url.substr(endIndex)) : "");
    }
    return url;
}
function formEncodeURLParams( params )
{
    var paramString = '';
    for ( var param in params )
        paramString += (isValEmpty(paramString) ? '' : '&') + escape( param ) + '=' + escape( emptyIfNull( params[param] ) );
    return paramString;
}
function previewMedia(mediaid, bIsHref, document)
{
    if (bIsHref)
        mediaid = mediaid.substr(mediaid.lastIndexOf('/')+1);
    var url = '/core/media/previewmedia.nl?id='+mediaid;
    preview(url, 'prevmedia');
}

function downloadMedia(mediaid)
{
    var url = '/core/media/previewmedia.nl?id='+mediaid+'&'+'_xd'+'=T';
    preview(url, 'prevmedia');
}

function previewTemplate(id, entity)
{
    var url = '/app/crm/common/merge/previewtemplate.nl?id='+id;
    if ( !isValEmpty(entity) )
        url = addParamToURL( url, 'entity', entity );
    preview(url, 'previewtemplate');
}

function siteMedia(mediaid, bIsHref, document)
{
    if (bIsHref)
        mediaid = mediaid.substr(mediaid.lastIndexOf('/')+1);
    var url = '/app/site/media/sitemedia.nl?id='+mediaid;
    preview(url, 'sitemedia');
}

function preview(url, winname)
{
    var prms = 'location=no,width=600,height=500,menubar=yes,scrollbars=yes,resizable=yes';
    var win = window.open(url, winname, prms);
    win.focus();
}

function getCookieVal(offset)
{
    var endstr = document.cookie.indexOf (';', offset);
    if (endstr == -1)
        endstr = document.cookie.length;
    return unescape(document.cookie.substring(offset, endstr));
}

function GetCookie(name)
{
    var arg = name + '=';
    var alen = arg.length;
    var clen = document.cookie.length;
    var i = 0;
    while (i < clen)
    {
        var j = i + alen;
        if (document.cookie.substring(i, j) == arg)
        {
            
            return getCookieVal(j);
        }
        i = document.cookie.indexOf(' ', i) + 1;
        if (i == 0) break;
    }
    return null;
}

function getStickyTag( pageName )
{
    var cbody = GetCookie('stickytags');
    if (cbody != null)
    {
        
        var b=cbody.indexOf(','+pageName+':') + 1;
        if (b>=1)
        {
             var e=cbody.indexOf(',',b);
             if (e<0)
                e=cbody.length;
             return unescape(cbody.substring(b+pageName.length+1, e));
        }
    }
    return null;
}

function addStickyTagToUrl(url, pageName)
{
    return url + (url.indexOf('?') >= 0 ? '&t=' : '?t=') + getStickyTag(pageName);
}

function redirectToStickyPage(url,pageName,framed)
{
    var newUrl = addStickyTagToUrl(url, pageName);
    try {
        if (typeof(framed) == "number")
            parent.frames[framed].document.location = newUrl;
        else if (framed)
            parent.document.location = newUrl;
        else
            document.location = newUrl;
    
    } catch (e) { }
}



var SelectKeyPressMaxKeyPause = 2000;   
function SelectKeyPressHandler (evnt, sorted)
{
    keyString = String.fromCharCode (getEventKeypress(evnt)).toUpperCase();
    if (!(keyString >= " "  &&  keyString <= "_"))
    {
        SelectKeyPressTypedString = "";
        return true;
    }
    if (SelectKeyPressTimeoutID != null)
        window.clearTimeout (SelectKeyPressTimeoutID);
    SelectKeyPressTimeoutID = window.setTimeout ("SelectKeyPressTimeout()",
                                                SelectKeyPressMaxKeyPause);
    SelectKeyPressTypedString += keyString;
    if (sorted)
    {
        if (SelectKeyPressTypedString.length == 1)
            option = SelectKeyPressLookupFirst (evnt, SelectKeyPressTypedString);
        else
            option = SelectKeyPressLookupNext (evnt, SelectKeyPressTypedString);
    }
    else
        option = SelectKeyPressLookupLinear (evnt, SelectKeyPressTypedString);
    setEventPreventDefault(evnt);
    if (option != -1)
    {
        getEventTarget(evnt).selectedIndex = option;
        getEventTarget(evnt).onchange();
    }

    return false;
}
var SelectKeyPressTypedString = "";
    SelectKeyPressTimeoutID = null;
function SelectKeyPressTimeout ()
{
    SelectKeyPressTypedString = "";
    SelectKeyPressTimeoutID = null;
}
function SelectKeyPressLookupFirst (evnt, str)
{
    select = getEventTarget(evnt);
    options = select.options;
    low = 0;
    high = options.length;
    while (high - low > 1)
    {
        i = Math.floor ((high + low) / 2);
        if (str.charAt(0) <= options(i).text.charAt(0).toUpperCase())
            high = i;
        else
            low = i;
    }
    while (high > 0  &&
            str.charAt(0) == options(high - 1).text.charAt(0).toUpperCase())
        --high;
    if (high < options.length  &&
        str.charAt(0) == options(high).text.charAt(0).toUpperCase())
        return high;
    else
        return -1;
}
function SelectKeyPressLookupNext (evnt, str)
{
    select = getEventTarget(evnt);
    options = select.options;

    selIndex = select.selectedIndex;
    while (selIndex < options.length - 1  &&
            options(selIndex).text.toUpperCase() < str)
        ++selIndex;
    if (selIndex < options.length - 1  &&
            options(selIndex).text.substr(0, str.length).toUpperCase() == str)
        return selIndex;
    else
        return -1;
}
function SelectKeyPressLookupLinear (evnt, str)
{
    select = getEventTarget(evnt);
    options = select.options;

    for (i = 0; i < options.length; ++i)
        if (options(i).text.substr(0, str.length).toUpperCase() == str)
            return i;

    return -1;
}
function disableFilter(radio, disableVal, fld1,fld2)
{
    if (getRadioValue(radio) == disableVal)
    {
        fld1.disabled = true;
        if (fld2)
            fld2.disabled = true;
    }
    else
    {
        fld1.disabled = false;
        if (fld2)
            fld2.disabled = false;
    }
}


function NLDate_parseString(sDate, bDoAlert)
{
    var m=0;
    var d=0;
    var y=0;
    var val = sDate;
    var fmterr = "";
    var year="";
    var year_char_index, month_char_index, day_char_index;
    var rtnDate = null;

    if(!window.dateformat)
        window.dateformat = "MM/DD/YYYY";   

    if(sDate == "")
    {
        return new Date();
    }
    else if(window.dateformat == "MM/DD/YYYY")
    {
        if (val.indexOf("/") != -1)
        {
            var c = val.split("/");
            if(onlydigits(c[0])) m = parseInt(c[0],10);
            if(onlydigits(c[1])) d = parseInt(c[1],10);
    
            if ( d > 1970 )
            {
                year = y = d;
                d = 1;
            }
            else
            {
                if(onlydigits(c[2])) y = parseInt(c[2],10);
                year=c[2];
            }
        }
        else
        {
            var l = val.length, str;
            str = val.substr(0,2-l%2); if(onlydigits(str)) m = parseInt(str,10);
            str = val.substr(2-l%2,2); if(onlydigits(str)) d = parseInt(str,10);
            str = val.substr(4-l%2);   if(onlydigits(str)) y = parseInt(str,10);
            year=str;
        }
    }
    else if(window.dateformat == "DD/MM/YYYY")
    {
        if (val.indexOf("/") != -1)
        {
            var c = val.split("/");
            if(onlydigits(c[0])) d = parseInt(c[0],10);
            if(onlydigits(c[1])) m = parseInt(c[1],10);
            if(onlydigits(c[2])) y = parseInt(c[2],10);
            year=c[2];
        }
        else
        {
            var l = val.length, str;
            str = val.substr(0,2-l%2); if(onlydigits(str)) d = parseInt(str,10);
            str = val.substr(2-l%2,2); if(onlydigits(str)) m = parseInt(str,10);
            str = val.substr(4-l%2);   if(onlydigits(str)) y = parseInt(str,10);
            year=str;
        }
    }
    else if(window.dateformat == "YYYY/MM/DD")
    {
        if (val.indexOf("/") != -1)
        {
            var c = val.split("/");
            if(onlydigits(c[0])) y = parseInt(c[0],10);
            if(onlydigits(c[1])) m = parseInt(c[1],10);
            if(onlydigits(c[2])) d = parseInt(c[2],10);
            year=c[0];
        }
        else
        {
            var l = val.length, str;
            str = val.substr(0,2-l%2); if(onlydigits(str)) y = parseInt(str,10);
            str = val.substr(2-l%2,2); if(onlydigits(str)) m = parseInt(str,10);
            str = val.substr(4-l%2);   if(onlydigits(str)) d = parseInt(str,10);
            year=str;
        }
    }
    else if(window.dateformat == "DD.MM.YYYY")
    {
        if (val.indexOf(".") != -1)
        {
            var c = val.split(".");
            if(onlydigits(c[0])) d = parseInt(c[0],10);
            if(onlydigits(c[1])) m = parseInt(c[1],10);
            if(onlydigits(c[2])) y = parseInt(c[2],10);
            year=c[2];
        }
        else
        {
            var l = val.length, str;
            str = val.substr(0,2-l%2); if(onlydigits(str)) d = parseInt(str,10);
            str = val.substr(2-l%2,2); if(onlydigits(str)) m = parseInt(str,10);
            str = val.substr(4-l%2);   if(onlydigits(str)) y = parseInt(str,10);
            year=parseInt(str,10);
        }
    }
    else if(window.dateformat == "DD-Mon-YYYY")
    {
        if (val.indexOf("-") != -1)
        {
            var c = val.split("-");
            if(onlydigits(c[0])) d = parseInt(c[0],10);
            m = getMonthIndex(c[1]);
            <!--alert('month index....'+m+','+c[1]);-->
            if(onlydigits(c[2])) y = parseInt(c[2],10);
            year=c[2];
        }
        else
        {
            var l = val.length, str;
            str = val.substr(0,1+l%2); if(onlydigits(str)) d = parseInt(str,10);
            str = val.substr(1+l%2,3);
            m = getMonthIndex(str);
            str = val.substr(4+l%2);   if(onlydigits(str)) y = parseInt(str,10);
            year=str;
        }
    }
    else if(window.dateformat == "DD-MONTH-YYYY")
    {
        var comps = val.split("-");
        if(onlydigits(comps[0]))
            d = parseInt(comps[0]);
        m = arrayIndexOf(NLDate_months, comps[1], true) + 1;
        if(onlydigits(comps[2]))
        {
            y = parseInt(comps[2]);
            year = y;
        }
    }
    else if(window.dateformat == "YYYY-MM-DD")
    {
        var comps = val.split("-");
        if(onlydigits(comps[2]))
            d = parseInt(comps[2]);
        if(onlydigits(comps[1]))
            m = parseInt(comps[1]);
        if(onlydigits(comps[0]))
        {
            y = parseInt(comps[0]);
            year = y;
        }
    }
	else if(window.dateformat == "EEYY年MM月DD日")
    {
        year_char_index = val.indexOf(year_char_cn);
        month_char_index = val.indexOf(month_char_cn);
        day_char_index = val.indexOf(day_char_cn);
        if(onlydigits(val.substring(month_char_index+1,day_char_index)))
            d = parseInt(val.substring(month_char_index+1,day_char_index));
        if(onlydigits(val.substring(year_char_index+1,month_char_index)))
            m = parseInt(val.substring(year_char_index+1,month_char_index));
        var era = val.substring(0, 2);
        if(onlydigits(val.substring(2,year_char_index)))
        {
            y = get_gregorian_year(parseInt(val.substring(2,year_char_index)), era);
            year = y;
        }
    }
	else if(window.dateformat == "YYYY年MM月DD日")
    {
        year_char_index = val.indexOf(year_char_cn);
        month_char_index = val.indexOf(month_char_cn);
        day_char_index = val.indexOf(day_char_cn);
        if(onlydigits(val.substring(month_char_index+1,day_char_index)))
            d = parseInt(val.substring(month_char_index+1,day_char_index));
        if(onlydigits(val.substring(year_char_index+1,month_char_index)))
            m = parseInt(val.substring(year_char_index+1,month_char_index));
        if(onlydigits(val.substring(0,year_char_index)))
        {
            y = parseInt(val.substring(0,year_char_index));
            year = y;
        }
    }
    else if(window.dateformat == "EYY.MM.DD")
    {
        comps = val.split(".");
        if(onlydigits(comps[2]))
            d = parseInt(comps[2]);
        if(onlydigits(comps[1]))
            m = parseInt(comps[1]);
        var era = comps[0].substring(0, 1);
        if(onlydigits(comps[0].substring(1,comps[0].length)))
        {
            y = get_gregorian_year(parseInt(comps[0].substring(1,comps[0].length)), era);
            year = y;
        }
    }
    else if(window.dateformat == "DD. Mon YYYY")
    {
        comps = val.split(" ");
        if(onlydigits(comps[0].substring(0, comps[0].length - 1)))
            d = parseInt(comps[0].substring(0, comps[0].length - 1));
        m = getMonthIndex(comps[1]);
        if(onlydigits(comps[2]))
        {
            y = parseInt(comps[2]);
            year = y;
        }
    }
    else if(window.dateformat == "DD de MONTH de YYYY")
    {
        comps = val.split(" de ");
        if(onlydigits(comps[0]))
            d = parseInt(comps[0]);
        m = arrayIndexOf(NLDate_months, comps[1]) + 1;
        if(onlydigits(comps[2]))
        {
            y = parseInt(comps[2]);
            year = y;
        }
    }
	else if(window.dateformat == "YYYY년 MM월 DD?")
    {
        comps = val.split(" ");
        if(onlydigits(comps[2].substring(0, comps[2].length-1)))
            d = parseInt(comps[2].substring(0, comps[2].length-1));
        if(onlydigits(comps[1].substring(0, comps[1].length-1)))
            m = parseInt(comps[1].substring(0, comps[1].length-1)) - 1;
        if(onlydigits(comps[0].substring(0, comps[0].length-1)))
        {
            y = parseInt(comps[0].substring(0, comps[0].length-1));
            year = y;
        }
    }
	else if(window.dateformat == "DD MONTH YYYY")
	{
		comps = val.split(" ");
		if(onlydigits(comps[0]))
			d = parseInt(comps[0]);
		m = arrayIndexOf(NLDate_months, comps[1], true) + 1;
		if(onlydigits(comps[2]))
		{
			y = parseInt(comps[2]);
			year = y;
		}
	}
	else if(window.dateformat == "DD MONTH, YYYY")
	{
		comps = val.split(" ");
		if(onlydigits(comps[0]))
			d = parseInt(comps[0]);
		m = arrayIndexOf(NLDate_months, comps[1].substring(0, comps[1].length-1), true) + 1;
		if(onlydigits(comps[2]))
		{
			y = parseInt(comps[2]);
			year = y;
		}
	}

    if(m==0 || d==0)
    {
        if(bDoAlert)
        {
            if(fmterr == "")
                fmterr = window.dateformat;
            alert("Invalid date value (must be "+window.dateformat+")");
        }
    }
    else
    {
        if (y==0 && !onlydigits(year)) y = (new Date()).getFullYear();  
        if (m < 1 || m > 12 || d < 1 || d > 31 || (y >= 100 && y < 1000) || y > 9999)
            makeValidationQuirkLog('date', sDate, "Awkward Coersion of Date (Date Format is:" + window.dateformat + ")");
        if(m<1) m=1; else if(m>12) m=12;
        if(d<1) d=1; else if(d>31) d=31;
        if(y<100) y+=((y>=70)?1900:2000);
        if(y<1000) y*=10;
        if (y > 9999) y = (new Date()).getFullYear();

        year = y;
		rtnDate = validateDate(new Date(y, m-1, d), bDoAlert);
		if ( (rtnDate != null) && (y != nlGetFullYear(rtnDate) || m != rtnDate.getMonth() + 1 || d != rtnDate.getDate()))
		{
			rtnDate = validateDate(new Date(y, m-1, d, 12, 30), bDoAlert);
			if ( (rtnDate != null) && (y != nlGetFullYear(rtnDate) || m != rtnDate.getMonth() + 1 || d != rtnDate.getDate()))
			{
				rtnDate = null;
			}
		}        
    }

    return rtnDate;
}

function validateDate(dDate, bDoAlert)
{
	if (dDate.getTime() < -11636672400000)
	{
		dDate = null;
		if (bDoAlert)
			alert("Invalid date value (must be on or after "+getdatestring(new Date(-11636672400000))+")");
	}
	return dDate;
}


var NLDate_pnDaysInMonths = new Array(31,28,31,30,31,30,31,31,30,31,30,31);


function NLDate_getLastDayOfMonth(dDate)
{
    var m = dDate.getMonth();
    var days = NLDate_pnDaysInMonths[m];

    if(m == 1) 
    {
        var y = dDate.getYear();
        if ( (y% 400 == 0) || ((y % 4 == 0) && (y % 100 != 0)) )
            days++;
    }
    return days;
}

function setDisabledState(elementid,enable)
{
    
    elem = document.getElementById(elementid);
    if (typeof elem.disabled != "undefined" )
    {
        elem.disabled=!enable;
        return;
    }
    var childnodes=document.getElementById(elementid).getElementsByTagName('INPUT');
    for(var i=0;i< childnodes.length;i++)
    {
        if(childnodes[i].name.indexOf('_send')==-1)
            childnodes[i].disabled=!enable;
    }
    
    var childnodes=document.getElementById(elementid).getElementsByTagName('A');
    for(var i=0;i< childnodes.length;i++)
    {
        if(!enable && !childnodes[i].disabled)
        {
            childnodes[i].enabledonclick=childnodes[i].onclick;
            childnodes[i].onclick= new Function('return false;');
        }
        else if (enable && childnodes[i].enabledonclick!=null && childnodes[i].disabled)
        {
            childnodes[i].onclick=childnodes[i].enabledonclick;
        }
        childnodes[i].disabled=!enable;
    }
}

var NLAlertContext_CREDIT_CARD_NUMBERS_MUST_CONTAIN_BETWEEN_13_AND_20_DIGITS = "Credit card numbers must contain between 13 and 20 digits.";
var NLAlertContext_CREDIT_CARD_NUMBERS_MUST_CONTAIN_ONLY_DIGITS = "Credit card numbers must contain only digits.";
var NLAlertContext_EMAIL_ADDRESSES_MUST_MATCH = "Email addresses must match.";
var NLAlertContext_NETSUITE_DOES_NOT_ACCEPT_EMAIL_ADDRESSES_WITH_QUOTATION_MARKS_COMMAS_COLONS_SPACES_OR_GREATER_THAN_OR_LESS_THAN_SIGNS = "Please make sure there are no quotation marks, commas, colons, spaces, or greater than or less than signs.";
var NLAlertContext_PASSWORDS_DONT_MATCHN = "Passwords don\'t match.\n";
var NLAlertContext_PASSWORDS_CANNOT_BE_EMPTYN = "Passwords cannot be empty.\n";
var NLAlertContext_PASSWORDS_MUST_BE_AT_LEAST_1_CHARACTERS_LONGN = "Passwords must be at least {1} characters long.";
var NLAlertContext_PASSWORDS_MUST_CONTAIN_AT_LEAST_ONE_LETTER_AZN = "Passwords must contain at least one letter (A-Z).\n";
var NLAlertContext_PASSWORDS_MUST_CONTAIN_AT_LEAST_ONE_NUMBER_OR_SPECIAL_CHARACTERN = "Passwords must contain at least one number or special character.\n";
var NLAlertContext_PASSWORDS_MAY_CONTAIN_ONLY_LETTERS_NUMBERS_AND_SPECIAL_CHARACTERSN = "Passwords may contain only letters, numbers, and special characters.\n";
var NLAlertContext_OLD_AND_NEW_PASSWORDS_ARE_TOO_SIMILAR = "Old and new passwords are too similar.";
var NLAlertContext_PASSWORD_MUST_NOT_BE_THE_SAME_AS_THE_EMAIL_ADDRESS = "Password must not be the same as the email address";
var NLAlertContext_CREDIT_CARD_NUMBER_IS_NOT_VALID__PLEASE_CHECK_THAT_ALL_DIGITS_WERE_ENTERED_CORRECTLY = "Credit card number is not valid.  Please check that all digits were entered correctly.";
var NLAlertContext_NETSUITE_DOES_NOT_ACCEPT_EMAIL_ADDRESSES_WITH_QUOTATION_MARKS_COMMAS_COLONS_SPACES_OR_GREATER_THAN_OR_LESS_THAN_SIGNS = "Please make sure there are no quotation marks, commas, colons, spaces, or greater than or less than signs.";
var NLAlertContext_PLEASE_ENTER_A_VALID_EMAIL_ADDRESS = "Please enter a valid email address.";
var NLValidationUtil_SIMPLE_EMAIL_PATTERN = /^[-a-z0-9!#$%&'*+/=?^_`{|}~]+(?:\.[-a-z0-9!#$%&'*+/=?^_`{|}~]+)*@(?:[a-z0-9]+(?:-+[a-z0-9]+)*\.)+(?:xn--[a-z0-9]+|[a-z]{2,16})$/i;
var NLAlertContext_THE_SPECFIED_ROUTING_NUMBER_FAILED_VALIDATION_FOR_ABA_ROUTING_NUMBERS = "The specfied routing number failed validation for ABA Routing Numbers.";
var NLAlertContext_ABA_ROUTING_NUMBERS_MUST_BE_NINE_CHARACTERS = "ABA Routing Numbers must be nine characters.";
/**
 * check if the value is empty
 * @param val String being tested for whether it is empty (null or "")
 */
function isValEmpty(val)
{
    if (val === null || val === undefined)
        return true;
    val = new String(val);
    return (val.length == 0) || !/\S/.test(val);
}

/**
 * isHTMLValEmpty() returns true if the given string is empty or contains only whitespace, ignoring HTML markup
 * @param val String being tested for whether it is empty (null or "")
 */
function isHTMLValEmpty(val)
{
    if (isValEmpty(val))
        return true;
    val = val.replace(/&nbsp;|<(?!NL)[^>]*>/gi, '');
    return !/\S/.test(val);
}

/* works just like the SQL NVL function */
function nvl(val,val2)
{
    return val == null ? val2 : val;
}
// emptyIfNull(): return empty string if vall is null.
function emptyIfNull(val)
{
    return val == null ? '' : val;
}
// nullIfEmpty(): return null if val is null or empty.
function nullIfEmpty(val)
{
    return isValEmpty(val) ? null : val;
}
/*
 * Trims leading and trailing whitespace from a string.
 * Similar to Java's String.trim(), see corresponding doc there.
 */
function trim(str)
{
    return str.replace(/^\s+/,"").replace(/\s+$/,"");
}
function onlydigitsandchars(str)
{
    var re = new RegExp("([A-Za-z0-9]+)");
    return (re.exec(str)!=null && RegExp.$1==str);
}
function onlydigits(str)
{
    return /^[0-9]+$/.test(str);
}

/**
 * returns true if the value is null, empty, or evaluates to a math equivalent value of zero.
 * @param fieldval String being tested for whether it is empty or zero
 */
function isemptyorzero(fieldval)
{
    var val = fieldval;
    var isempty = isValEmpty(val);
    var iszero = val==0;
    return (isempty || iszero);
}

/**
 * returns true if the value is null, empty, or evaluates to a math equivalent value of zero.
 * @param fieldval String being tested for whether it is empty or zero
 */
function isNewRecord()
{
	var id = typeof nlapiGetField != undefined && nlapiGetField("id") != null ? nlapiGetFieldValue("id") :
			 typeof document != undefined && document.forms['main_form'].elements['id'] != null ? document.forms['main_form'].elements['id'] : "";
	return isValEmpty(id) || id == -1
}
/**
 * returns true if the current record is an existing record
 */
function isExistingRecord()
{
    return !isNewRecord();
}
/**
 * returns true if the current record is an existing record
 */
function getEditFlag()
{
    return isExistingRecord();
}
/**
 * Perform mandatory field check
 *
 * @param fields	Array of field names or field references (UI)
 * @param labels  	Array of field labels
 * @param values	Array of field values (only used during dynamic scripting contexts)
 * @param type		Sublist name if this is called for a machine (current line on an edit machine)
 */
function checkMandatoryFields(fields, labels, values, type)
{
	var result = "";
	for (var i = 0; i < fields.length; i++)
	{
		if (fields[i] == null)
			continue;
		var val = values != null ? values[i] : fields[i].value;
		if ((new String(val)).indexOf(String.fromCharCode(3)) != -1)
		{
			var nvarray = val.split(String.fromCharCode(4));
			for (var j = 0; j < nvarray.length; j++)
			{
				var nv = nvarray[j].split(String.fromCharCode(3));
				if (nv[1] == 'T' && nv[3].length == 0)
					result += (result.length ? ", " : "") + nv[2];
			}
			continue;
		}

		if (values != null)
		{
			if ((type != null && !Machine_isMandatoryOnThisLine(type, fields[i], nlapiGetCurrentLineItemIndex(type))) || (type == null && !nlapiGetFieldMandatory(fields[i])))
				continue;
			if (isValEmpty(val))
				result += (result.length ? ", " : "") + labels[i];
		}
		else
		{
			if (!getRequired(fields[i]))
				continue;

			if (isSelect(fields[i]) || isPopupSelect(fields[i]))
			{
				val = getSelectValue(fields[i]);
				if (isValEmpty(val))
					result += (result.length ? ", " : "") + labels[i];
			}
			else if (window.getHtmlEditor != null && getHtmlEditor(fields[i].name) != null)
			{
				if (isValEmpty(fields[i].value.replace("<DIV></DIV>", "")))
					result += (result.length ? ", " : "") + labels[i];
			}
			else
			{
				if (isempty(fields[i]))
					result += (result.length ? ", " : "") + labels[i];
			}
		}
	}
	return result;
}

/**
 * Perform unique field validation on an edit machine (executed during validateLine)
 *
 * @param name			machine name
 * @param uniquefields	Array of field names for unique fields
 * @param uniquelabels	Array of field labels for unique fields
 *
 * @return An array of the unique field labels if there is a validation error or null
 */
function checkUniqueFields(name, uniquefields, uniquelabels)
{
	if ( uniquefields == null || uniquefields.length == 0 )
		return null;
	for (var i=1; i<= nlapiGetLineItemCount(name)+1; i++)
	{
		if (i == nlapiGetCurrentLineItemIndex(name)) continue;
		var bAllEmpty = true, bMatch = true;
		for (var j=0; j < uniquefields.length; j++)
		{
			var f = uniquefields[j];
			if (!isValEmpty(getEncodedValue(name,i,f))) bAllEmpty = false;
			if (getEncodedValue(name,i,f) != nlapiGetCurrentLineItemValue(name, uniquefields[j]))
			{
				bMatch = false;
				break;
			}
		}
		if (bAllEmpty || !bMatch) continue;
		var labels = new Array();
		for (var k=0; k < uniquefields.length; k++)
		{
			labels.push(uniquelabels[k]);
		}
		return labels;
	}
    return null;
}

// checkccnumber(): check if value in form fld is valid credit card. If this is called from the UI (i.e. webstore) then fld is a DOM field
//					reference. Otherwise it is a String containing the name of the field (use SuiteScript API for setting field)
//               NOTE: this is not a perfect check by any means. it does
//                  not check that amex is 15 and visa/other is 16. it also
//                  doesn't do the visa checksum.
//            	DJ11sep2000 -- I added code to do the luhn checksum check.
//				YF10Nov2008 -- moved to NLRecordUtil.js from NLUtil.js (please keep this in sync with NLValidationUtil.luhnCheck(s))
function checkccnumber(fld)
{
//  Remove all spaces and dashes.
//  you must check for length 0 up front. if you don't
//  mac ie5 will crashes on the replace call below.
	var cardnum = typeof(fld) != "string" ? fld.value : nlapiGetFieldValue(fld);	
	if(cardnum.length > 0) cardnum = cardnum.replace(/ /gi,'');
    if(cardnum.length > 0) cardnum = cardnum.replace(/-/gi,'');

    if (cardnum.length<13 || cardnum.length>20)
    {
        alert(NLAlertContext_CREDIT_CARD_NUMBERS_MUST_CONTAIN_BETWEEN_13_AND_20_DIGITS);
        return false;
    }
    if (!onlydigits(cardnum))
    {
        alert(NLAlertContext_CREDIT_CARD_NUMBERS_MUST_CONTAIN_ONLY_DIGITS);
        return false;
    }

    // Perform Luhn check
    // http://www.ling.nwu.edu/~sburke/pub/luhn_lib.pl
    var no_digit = cardnum.length;
    var oddoeven = no_digit & 1;
    var sum = 0;

    for (var count = 0; count < no_digit; count++)
    {
        var digit = parseInt(cardnum.charAt(count),10);
        if (!((count & 1) ^ oddoeven))
        {
            digit *= 2;
            if (digit > 9)
            digit -= 9;
        }
        sum += digit;
    }
    if (sum % 10 != 0)
    {
        alert(NLAlertContext_CREDIT_CARD_NUMBER_IS_NOT_VALID__PLEASE_CHECK_THAT_ALL_DIGITS_WERE_ENTERED_CORRECTLY);
        return false;
    }

	eval( typeof(fld) != "string" ? "fld.value = cardnum" : "nlapiSetFieldValue(fld, cardnum, false)" );
    return true;
}

/**
 * Set preferred fields following the addition of a new line on an edit machine (executed after validateLine but before recalc)
 *
 * @param name 	sublist name
 * @param preferredfield	preferred field name
 * @param linenum	line number being added
 */
function setPreferredFields(name, preferredfield, preferredwithinfield, linenum)
{
	if (getEncodedValue(name,linenum,preferredfield) == 'T')
	{
		for (var i=1; i <= getLineCount(name)+1; i++)
		{
			if (i != linenum && getEncodedValue(name,i,preferredfield) == 'T')
            {
                if(preferredwithinfield == null || getEncodedValue(name,linenum,preferredwithinfield) == getEncodedValue(name,i,preferredwithinfield))
                    setEncodedValue(name,i,preferredfield,'F');
            }
        }
	}
	return true;
}

function escapeJSONChar(c)
{
    if(c == "\"" || c == "\\") return "\\" + c;
    else if (c == "\b") return "\\b";
    else if (c == "\f") return "\\f";
    else if (c == "\n") return "\\n";
    else if (c == "\r") return "\\r";
    else if (c == "\t") return "\\t";
    var hex = c.charCodeAt(0).toString(16);
    if(hex.length == 1) return "\\u000" + hex;
    else if(hex.length == 2) return "\\u00" + hex;
    else if(hex.length == 3) return "\\u0" + hex;
    else return "\\u" + hex;
}

function escapeJSONString(s)
{
    /* The following should suffice but Safari's regex is b0rken
       (doesn't support callback substitutions)
       return "\"" + s.replace(/([^\u0020-\u007f]|[\\\"])/g,
       escapeJSONChar) + "\"";
    */

    /* Rather inefficient way to do it */
    var parts = s.split("");
    for(var i=0; i < parts.length; i++) {
	var c =parts[i];
	if(c == '"' ||
	   c == '\\' ||
	   c.charCodeAt(0) < 32 ||
	   c.charCodeAt(0) >= 128)
	    parts[i] = escapeJSONChar(parts[i]);
    }
    return "\"" + parts.join("") + "\"";
}
toJSON = function toJSON(o)
{
    if (o == null) // note: if o is undefined, this statement is true
		return "null";
    else if(o.constructor == String || o.constructor.name == "String")
		return escapeJSONString(o);
    else if(o.constructor == Number || o.constructor.name == "Number")
		return o.toString();
    else if(o.constructor == Boolean || o.constructor.name == "Boolean")
		return o.toString();
    else if(o.constructor == Date || o.constructor.name == "Date")
		return '{javaClass: "java.util.Date", time: ' + o.valueOf() +'}';
    else if(o.constructor == Array || o.constructor.name == "Array"  || o.length >= 0)
	{
	    var v = [];
	    for (var i = 0; i < o.length; i++) v.push(toJSON(o[i]));
	    return "[" + v.join(", ") + "]";
    }
	else
	{
		var v = [];
		for(attr in o)
		{
	        if(o[attr] == null) v.push("\"" + attr + "\": null");
	        else if(typeof o[attr] == "function"); /* skip */
	        else v.push(escapeJSONString(attr) + ": " + toJSON(o[attr]));
		}
		return "{" + v.join(", ") + "}";
    }
}
// Used to parse quantity price schedules
function getQtyRate(schedstr,qty,marginal)
{
    var sched = schedstr.split(String.fromCharCode(5));
    var i;
    var cum_amount=0;
    var rate;
    for (i=0;i < sched.length;i+=2)
    {
       if (qty >= parseFloat(sched[i]) && (i+2>=sched.length || qty < parseFloat(sched[i+2])))
       {
          if (marginal && qty>0)
          {
            cum_amount+=(qty-parseFloat(sched[i]))*parseFloat(sched[i+1]);
            rate=cum_amount/qty;
          }
          else
            rate=sched[i+1];
          break;
       }
       else if (marginal && qty > 0)
          cum_amount += (parseFloat(sched[i+2])-parseFloat(sched[i]))*parseFloat(sched[i+1]);
    }
    return rate;
}

function parseFloatOrZero(f)
{
   var r=parseFloat(f);
   return isNaN(r) ? 0 : r;
}

function isValidUSZipCode(value)
{
    var re = /^\d{5}([\-]\d{4})?$/;
    return (re.test(value));
}

function checkemail(email,emptyok,alrt)
{
    // mirrors Java's String.trim() - remove leading and trailing whitespace
    email = trim(email);
    return checkemail2(email,email,emptyok,alrt);
}

function checkemail2(email_1,email_2,emptyok,alrt)
{
    var s_email = email_1;

    if (s_email != email_2)
    {
        alert(NLAlertContext_EMAIL_ADDRESSES_MUST_MATCH);
        return false;
    }
    if (emptyok && s_email.length==0)
    {
        return true;
    }
    return checkemailvalue(s_email,alrt);
}

function checkemailvalue(s_email,alrt)
{
	alrt = true;
	if (/\s|[,":<>]/.test(s_email))
	{
		if (alrt)
		{
			alert(NLAlertContext_PLEASE_ENTER_A_VALID_EMAIL_ADDRESS
					+ " " + NLAlertContext_NETSUITE_DOES_NOT_ACCEPT_EMAIL_ADDRESSES_WITH_QUOTATION_MARKS_COMMAS_COLONS_SPACES_OR_GREATER_THAN_OR_LESS_THAN_SIGNS);
		}
		return false;
	}

	if (!NLValidationUtil_SIMPLE_EMAIL_PATTERN.test(s_email))
	{
		if (alrt)
		{
			alert(s_email + ' ' + NLAlertContext_PLEASE_ENTER_A_VALID_EMAIL_ADDRESS);
		}
		return false;
	}

	return true;
}

function checkemailprefix(s_email)
{
	/*
	Return true if string appears to be an email prefix (eg. wbailey@netl).  Used by uber search.
	- Must have exactly one '@' preceded by one or more chars
	- Must not contain any of these chars: <space> , " : < >
	- Must not contain ".."
	NOTE: This is a rudimentary check, not full email validation. It can be upgraded to full validation by
	reusing logic from checkemailvalue().
	*/
	return /^[^@]+@[^@]*$/.test(s_email) && !/\s|[,":<>]|[.][.]/.test(s_email);
}


// checknotempty(): validate that field is not empty and return focus to offending field. %>
function checkvalnotempty(val,alertMessage)
{
	if (isValEmpty(val))
	{
		if (alertMessage)
		{
			alert(alertMessage);
		}
        return false;
    }
    return true;
}

function checkpassword(pwd1,pwd2,alrt,strictcheck,prevpwd,len,email)
{
    var strict = (strictcheck == true || strictcheck == null);
    var msg = getpassworderror(pwd1,pwd2,strict,prevpwd,len,email);
    if (msg != null)
    {
        if (alrt) alert(msg);
        return false;
    }
    else
        return true;
}

function getpassworderror(pwd1,pwd2,strictcheck,prevpwd,len,email)
{
    var strict = (strictcheck == true || strictcheck == null);
    var val = pwd1;
    if (len == null)
        len = 6;
    msg = "";

    if (pwd1 != pwd2)
    {
        msg += NLAlertContext_PASSWORDS_DONT_MATCHN;
    }
    else if (!strict)
    {
        if (val.length == 0)
            msg = NLAlertContext_PASSWORDS_CANNOT_BE_EMPTYN;
    }
    else
    {
        if (val.length < len)
        {
            msg += NLAlertContext_PASSWORDS_MUST_BE_AT_LEAST_1_CHARACTERS_LONGN.replace("{1}", String(len));
        }
        if (!/[A-Za-z]/.test(val))
        {
            msg += NLAlertContext_PASSWORDS_MUST_CONTAIN_AT_LEAST_ONE_LETTER_AZN;
        }
        if (!/[0-9!@#$%^&*.:;~'`*",_|= \<\>\/\\\+\?\-\(\)\[\]\{\}]/.test(val))
        {
            msg += NLAlertContext_PASSWORDS_MUST_CONTAIN_AT_LEAST_ONE_NUMBER_OR_SPECIAL_CHARACTERN;
        }
        if (!/^[A-Za-z0-9!@#$%^&*.:;~'`*",_|= \<\>\/\\\+\?\-\(\)\[\]\{\}]+$/.test(val))
        {
            msg += NLAlertContext_PASSWORDS_MAY_CONTAIN_ONLY_LETTERS_NUMBERS_AND_SPECIAL_CHARACTERSN;
        }
    }
    if (msg.length == 0 && prevpwd != null)
    {
        var oldval = prevpwd;
        var charDiffCount = 0;
        for (var i=0;i < val.length; i++)
        {
            var c = val.charAt(i);
            if (oldval.indexOf(c) == -1)
                charDiffCount++;
        }
        if (charDiffCount < 2)
            msg = NLAlertContext_OLD_AND_NEW_PASSWORDS_ARE_TOO_SIMILAR;
    }
	if (msg.length == 0 && email != null)
	{
		if (email == pwd1)
			msg = NLAlertContext_PASSWORD_MUST_NOT_BE_THE_SAME_AS_THE_EMAIL_ADDRESS;
	}
	if (msg.length > 0)
        return msg;
    else
        return null;
}

function validate_AbaRoutingNumber(routing)
{
	if (routing == null || routing.length == 0)
    {
        NS.form.setValid(true);
        return true;
    }
	var maxlen = 9;
	var validflag = true;
    var err = '';
    if (routing.length != maxlen)
    {
        err = NLAlertContext_ABA_ROUTING_NUMBERS_MUST_BE_NINE_CHARACTERS;
        validflag = false
    }
	var t = routing;
	var n = 0;
    for (i = 0; i < t.length; i += 3)
    {
        n += parseInt(t.charAt(i), 10) * 3 + parseInt(t.charAt(i + 1), 10) * 7 +  parseInt(t.charAt(i + 2), 10);
    }

	if (n != 0 && n % 10 == 0)
	{
        validflag = true;
	}
	else
	{
		err = NLAlertContext_THE_SPECFIED_ROUTING_NUMBER_FAILED_VALIDATION_FOR_ABA_ROUTING_NUMBERS +"("+routing+")";
        validflag = false;
	}


    if (err != '')
    {
		alert(err);
    }
    NS.form.setValid(validflag);
    return validflag;
}

//check if a character has Chinese/Japanese/Korean characters
function stringContainsCJKChar(str)
{
   if(str == null || str.length == 0)
      return false;
   var cjk = false;
   for (var i=0; i<str.length; i++)
   {
     var charcode = str.charCodeAt(i);
     if( (charcode >= 12352 && charcode <= 40959) || (charcode >= 44032 && charcode <= 55215))
     {
       cjk = true;
       break;
     }
   }
   return cjk;
}



function nlOpenWindow(url, winname, widthOrFeatures, height, fld, scrollbars)
{
    if ( window.doPageLogging ) 
        logStartOfRequest( 'popup' );
    if ( isValEmpty( widthOrFeatures ) )
        return window.open(url, winname);
    else if ( isNaN(parseInt( widthOrFeatures )) )
        return window.open(url, winname, widthOrFeatures);
    else if ( isIE )
        return window.open(url, winname, 'scrollbars='+(scrollbars ? 'yes' : 'no')+',width='+Math.min(screen.availWidth,widthOrFeatures)+',height='+Math.min( screen.availHeight-40,height)+',left='+Math.min(screen.availWidth-widthOrFeatures,getObjectLeft(fld))+',top='+Math.min( (screen.availHeight-40)-height,getObjectTop(fld))+',resizable=yes');
    else
        return window.open(url, winname, 'scrollbars='+(scrollbars ? 'yes' : 'no')+',width='+widthOrFeatures+',height='+height+',resizable=yes');
}

function nlExtOpenDivWindow(winname, width, height, fld, scrollbars, winTitle, listeners, html, triggerObj, chartHTML, winProperties)
{
    var divhtml = "<div id='" + winname + "_framediv'></div>";

    if (html != null && typeof html != 'undefined')
        divhtml = html;

    if(chartHTML != null && typeof chartHTML != 'undefined'){
        divhtml= chartHTML + "<div style='width:100%;float:left;clear:left;' id='" + winname + "_framediv'>";
    }

    var xPos = null;
    var yPos = null;
    if (triggerObj != null && typeof triggerObj != 'undefined')
    {
        xPos = findGlobalPosX(triggerObj);
        yPos = findGlobalPosY(triggerObj);
    }

    var defaultProperties = {
        title: (winTitle != undefined ? winTitle : winname),
        id: winname,
        name: winname,
        stateful: false,
        modal: true,
        autoScroll: false,
        width: width,
        height: height,
        style: 'background-color: #FFFFFF;',
        bodyStyle: 'background-color: #FFFFFF;',
        resizable: true,
        listeners : listeners,
        bodyCfg: {
            tag: 'center',
            name: winname+'_frame',
            id: winname+'_frame',
            html: divhtml,
            width: width+'px',
            height: height+'px',
            style: 'border:none;background-color: #FFFFFF;'
        }
    };
    jQuery.extend(defaultProperties, winProperties);
    var extWindow = new Ext.Window(defaultProperties);

	if ((!isValEmpty(xPos))&&(!isValEmpty(yPos)))
	{
		extWindow.x = xPos;
		extWindow.y = yPos;
	}

    extWindow.show();
    extWindow.syncSize();

    return extWindow;
}

function nlOpenIframe(url, winname, listeners)
{
    if (!listeners)
        listeners = new Object();

    var deferred = jQuery.Deferred();
    var id = winname;
    var iframe = jQuery("#" + id);
    if (iframe.length == 0)
    {
        //
        jQuery("<iframe/>", {id: id, tabindex: -1, style: "display: none", height: 0, width: 0}).appendTo("body");
        iframe = jQuery("#"  + id);

        if (listeners['onload']) {
            iframe.on('onload', function(event, iframe) {
                listeners['onload'](iframe);
            });
        }
        iframe.load(function() {
			deferred.resolve();
            jQuery(this).trigger('onload', [jQuery(this)]);
        });
        if (listeners['beforeclose']) {
            iframe.on('beforeclose', function(event) {
                listeners['beforeclose']();
            });
        }
    }

    iframe.load(deferred.resolve);
    iframe.data("iframeid", id);
    iframe.attr("src", url);
    return deferred.promise();
}

function nlExtOpenWindow(url, winname, width, height, fld, scrollbars, winTitle, listeners, triggerObj)
{
    //TODO: is the following needed for this style of popup?

    url = addParamToURL (url, "ifrmcntnr", "T", true );

    if (!listeners)
        listeners = {};

    if ( window.doPageLogging ) 
        logStartOfRequest( 'extpopup' );


    var xPos = null;
    var yPos = null;

    if (triggerObj != null && typeof triggerObj != 'undefined')
    {
        xPos = findPosX(triggerObj);
        yPos = findPosY(triggerObj);
    }

	var extWindow = new Ext.Window({
		title: (winTitle != undefined ? winTitle : winname),
		id: winname,
		name: winname,
		stateful: false,
		modal: true,
		autoScroll: scrollbars,
		width: parseInt(''+width) + 20,
		height: parseInt(''+height) + 30,
		style: 'background-color: #FFFFFF;',
		bodyStyle: 'background-color: #FFFFFF;',
		resizable: true,
		listeners : listeners,
		bodyCfg: {
			tag: 'iframe',
			name: winname+'_frame',
			id: winname+'_frame',
			src: url,
			width: (width+4)+'px',
			height: height+'px',
			style: 'border: 0 none; background-color: #FFFFFF;'
		 }
	});

    if ((!isValEmpty(xPos))&&(!isValEmpty(yPos)))
    {
        extWindow.x = xPos;
        extWindow.y = yPos;
    }

    extWindow.show();
    extWindow.syncSize();
}


function getObjectLeft(obj)
{
    var offset=0;
    while (obj != null && obj != document.body)
    {
        offset += obj.offsetLeft;
        obj = obj.offsetParent;
    }
    return offset + (isIE ? window.screenLeft : window.screenX + window.outerWidth - window.innerWidth);
}


function getObjectTop(obj)
{
    var offset=0;
    while (obj != null && obj != document.body)
    {
        offset += obj.offsetTop;
        obj = obj.offsetParent;
    }
    if (isIE)
    return offset + window.screenTop;

    //mozilla browsers
    var statusbarHeight = 0;
    if (typeof window.statusbar != "undefined" && window.statusbar != null && window.statusbar.visible)
        statusbarHeight = 20; //rough number

    return offset + window.screenY + window.outerHeight - window.innerHeight - statusbarHeight;

}

function setFieldVisibility ( spanId, on )
{
    var spanInput = document.getElementById( spanId  );
    visible ( spanInput, on );
}
function setLabelVisibility ( spanId, on )
{
    var spanLabel = document.getElementById( spanId + "_lbl" );
    visible( spanLabel, on );
}
function setFieldAndLabelVisibility( spanId, on )
{
    setLabelVisibility( spanId, on );
    setFieldVisibility( spanId, on );
}

function showLabel ( spanId, on )
{

    var spanLabel = document.getElementById( spanId + "_lbl" );
    if (on) {
        var elem = !!NS && !!NS.UI && !!NS.UI.Helpers && !!NS.UI.Helpers.getClosestAncestorFromClass &&
                NS.UI.Helpers.getClosestAncestorFromClass(document.getElementById(spanId), 'uir-field-wrapper');

        if (elem) {
            display(elem, on);
        }

    }

    display( spanLabel, on );

}
function showHelperText ( spanId, on )
{
    var spanLabel = document.getElementById( spanId + "_hlp" );
    display( spanLabel, on );
}
function setLabel( spanId, label)
{

    var spanLabel = document.getElementById( spanId + "_lbl" );
    if (spanLabel == null)
    	return;

    // span may contain inner anchor element
    var labelElement = spanLabel;
    var anchors = labelElement.getElementsByTagName("A");
    if (anchors.length > 0)
    {
        labelElement = anchors[0];
    }

    labelElement.innerHTML = label;

}
function getLabel( spanId )
{

    var spanLabel = document.getElementById( spanId + "_lbl" );
	if (spanLabel == null)
		return null;
	// cm: span often contains a link, which itself contains the label
	else if (spanLabel.getElementsByTagName('a') != null && spanLabel.getElementsByTagName('a').length == 1)
		return spanLabel.getElementsByTagName('a').item(0).innerHTML;
	else
		return spanLabel.innerHTML;

}
function showFieldAndLabel( spanId, on )
{

    if (window.nlentryform)
    	window.nlentryform.trackFieldVisibility(spanId, on);

    var elem = !!NS && !!NS.UI && !!NS.UI.Helpers && !!NS.UI.Helpers.getClosestAncestorFromClass &&
        NS.UI.Helpers.getClosestAncestorFromClass(document.getElementById(spanId), 'uir-field-wrapper');

    if(!!elem){
        display(elem, on);
    }

    showLabel( spanId, on );
    showField( spanId, on );

}

//module that encapsulates basic tab APIs
var ns_tabUtils = (function() {

    // this function is available only in Browser version of this jsp
    // legacy version of fields has no mechanism to get all visible fields on specific tab.
    // browser version has fields wrapped in div with specific class.
    function isEmpty(){
        return false;
    }

    function updateTabVisibility(tabName) {
        
            hideTab(tabName, this.isEmpty(tabName));
        
    }

    function isTabAreaVisible(tabName)
    {
        return (jQuery("#" + tabName + ":visible").length > 0);
    }

    
    function hideTab( tabName, hide )
    {
        
            var sufix = document.getElementById(tabName + '_pane') != null ? '_pane' : "lnk";
            // currently unlayered, look for the PANE element
            var currentlyDisplayed = ns_tabUtils.isTabAreaVisible(tabName + sufix );
            if (currentlyDisplayed !== hide)
                return;
        

        var displayVal = hide ? 'none' : '';
        var tableSuffixis = ['upperlt', 'uppermiddot', 'uppermid', 'upperrt', 'lt', 'lnkdot', 'lnk', 'rt', '_umh'];

        for(var i=0; i<tableSuffixis.length; ++i)
        {
            var elem = document.getElementById(tabName + tableSuffixis[i]);
            if (elem != null)
                elem.style.display = displayVal;
        }

        var elem = document.getElementById(tabName + '_pane');
        if (elem != null)
        {
            //show/hide tab in unlayered mode
            elem.style.display = displayVal;
        }
        else
        {
            //show/hide tab in layered mode
            elem = document.getElementById(tabName + '_layer');
            if (elem != null)
                elem.style.display = displayVal;
        }
    }

    return {
        updateTabVisibility: updateTabVisibility,
        isEmpty: isEmpty,
        isTabAreaVisible : isTabAreaVisible,
        hideTab: hideTab
    }
})();

function setRichTextEditorValue(fld, value, retries)
{
    var editor = getHtmlEditor(fld.name);

    // if HTML editor is already registered, set the value right away
    if (editor != null && fld == editor.hddn)
    {
        if (editor.initialized)
        {
            editor.setValue(value, true);
        }
        else // if editor is placed on inactive subtab, it won't be initialized yet => we have to use the hook
        {
            editor.on('initialize', function ()
            {
                editor.setValue(value, true);
            });
        }
    }
    else // otherwise we have to do it later
    {
        if (retries > 0) // limit the recursion
        {
            setTimeout(function () { setRichTextEditorValue(fld, value, retries - 1); }, 200);
        }
    }
}

function setFormValue(fld,value,text,firefieldchanged,synchronous)
{
	if (fld == null)
        return;
	if (fld.type == 'checkbox')
    {
     	setNLCheckboxValue(fld, value);
    }
    else if (fld.type == 'radio' || (fld.length > 0 && fld[0]!=null && fld[0].type == "radio"))
        syncradio(fld,value);
	else if (fld.type == 'select-one')
        synclist(fld,value);
    else if (isNLDropDown(fld))
        getDropdown(fld).setValue(value, true );
    else if (isMultiSelect(fld))
        syncmultiselectlist(fld, value, null, true );
    else if (isRichTextEditorUnregisteredSafe(fld))
    {
        
        if (window.getHtmlEditor != null)
        {
            setRichTextEditorValue(fld, value, 10);
        }
    }
    else if (fld.nodeName == 'INPUT' || fld.nodeName == 'TEXTAREA' || window.virtualBrowser)
    {
		var val = value != null && value.join != null && (isPopupMultiSelect( fld ) || isArray(value)) ? value.join( String.fromCharCode(5) ) : value;
        if ( isPopupSelect( fld ) )
            syncpopup( fld, val, text );
        else if ( isPopupMultiSelect( fld ) )
            syncmultiselectlist( fld, val, text, true );
        else if ( isCurrencyField(fld) )
            setNLCurrencyValue(fld, value);
        else if ( isNumericField(fld) )
            setNLNumericValue(fld, value);
        else
        {
            // Bug in quirks mode IE
            // when put null to fld.value, in IE is inserted "null" string
            fld.value = (val == null) ? "" : val;
            if ( isDisplayOnlySelect( fld ) && typeof text != "undefined" )
                document.getElementById(fld.name+'_displayval').innerHTML = text != null ? text.replace( new RegExp( String.fromCharCode(5), "g" ), '<BR>' ) : "";
        }
    }
    else
		fld.innerHTML = value;

    var uiField = fld;
    if ((isNumericField(fld) || isCurrencyField(fld)) && getNLNumericOrCurrencyDisplayField(fld) != null)
        uiField = getNLNumericOrCurrencyDisplayField(fld);

    if(uiField.machine)
        uiField.machine.setFieldInputValue(fld.name, value, firefieldchanged, text);
    else if (uiField.uiform)
        uiField.uiform.setFieldInputValue(fld.name ,value, firefieldchanged, text);

	if (firefieldchanged)
	{
		try
		{
			if (synchronous)
				setSlavingAsync(false)
			fireProperOnChange(fld);
		}
		finally
		{
			setSlavingAsync(true)
		}
	}
}
function getFormValue(fld, returnArray)
{
    if (fld == null)
        return null;
    if (fld.type == "checkbox")
        return fld.checked ? 'T' : 'F';
    else if (fld.type == "radio" || (fld.length > 0 && fld[0].type == "radio"))
        return getRadioValue(fld);
    else if (fld.type == "select-one" || isNLDropDown(fld))
        return getSelectValue(fld);
    else if (isMultiSelect(fld))
        return getMultiSelectValues(fld, returnArray);
    
    else if ( isRichTextEditor( fld ) )
        return fld.value;
    else
        return returnArray && fld.value != null && isPopupMultiSelect( fld ) ? fld.value.split( String.fromCharCode(5) ) : fld.value;
}


function getParameter( param, doc )
{
    if (typeof doc == "undefined" || doc == null)
        doc = document;
    var re = new RegExp(".*[?&]"+param+"=([^&]*)");
    var matches = re.exec( doc.location.href.toString() ) ;
    return matches != null && matches.length > 0 ? decodeURIComponent(matches[1]) : null;
}


function getParam(paramName)
{
	param = getParameter(paramName);
	if (param && param.indexOf('#') > -1)
	{
		param = param.substring(0, param.lastIndexOf('#'));
	}

	return param;
}


function getBooleanParameter( param )
{
    return getParameter( param ) == "T";
}

function getParameterValuesArray( )
{
    var url = document.location.href.toString();
    if ( url.indexOf('?') < 0 )
        return null;

    var pairs = url.substring( url.indexOf('?')+1 ).split("&");
    var a = new Array();
    for ( var i = 0; i < pairs.length; i++ )
    {
        var pair = pairs[i].split("=");
        a[a.length] = pair[0];
        a[a.length] = pair.length > 0 ? pair[1] : null;
    }
    return a;
}


function getFormElement(frm,fldname, fieldType)
{
    var returnMe = null;
    if ( frm != null )
    {
        if ( fldname == 'language' || (!isBackend && (fldname == 'item' || fldname == 'cash')) )
        {
            for ( var i = 0; i < frm.elements.length; i++ )
                if ( frm.elements[i].name == fldname )
                {
                    returnMe = frm.elements[i];
                    break;
                }
        }
        else if (fieldType && fieldType == 'inlinehtml')
        {
            returnMe = document.getElementById(fldname + "_val");
        }
        else if  (frm.elements != null)
            returnMe = frm.elements[fldname];
    }
    return returnMe;
}


function getFormElementViaFormName(frmName,fldname)
{
    return getFormElement( document.forms[ frmName ], fldname  );
}

var isBackend = false;
var isIE = isBackend || false;
var isIE11 = false;


var isNS = document.addEventListener ? true : false;




function findGlobalPosX(obj, container)
{
    var curtop = 0;
    if (document.getElementById || document.all)
    {
        while (obj.offsetParent)
        {
            curtop += obj.offsetLeft;
            obj = obj.offsetParent;
        }

        if (obj.document!=null && obj.document.parentWindow != null && obj.document.parentWindow.frameElement)
            curtop += findGlobalPosX(obj.document.parentWindow.frameElement)
    }
    else if (document.layers)
        curtop += obj.y;

    return curtop;
}


function findGlobalPosY(obj)
{
    var curtop = 0;
    if (document.getElementById || document.all)
    {
        while (obj.offsetParent)
        {
            curtop += obj.offsetTop;
            obj = obj.offsetParent;
        }

        if (obj.document!=null && obj.document.parentWindow != null && obj.document.parentWindow.frameElement)
            curtop += findGlobalPosY(obj.document.parentWindow.frameElement)
    }
    else if (document.layers)
        curtop += obj.y;

    return curtop;
}


function findAbsolutePosX(obj)
{
    var curleft = 0;
    if (document.getElementById || document.all)
    {
        while (obj.offsetParent)
        {
            curleft += obj.offsetLeft;
            if (obj.offsetParent != document.body)
                curleft -= obj.offsetParent.scrollLeft;
            obj = obj.offsetParent;
        }
    }
    else if (document.layers)
        curleft += obj.x;
    var isWindowContainedInDivFrame = window.parentAccesible && false; //(typeof parent != "undefined" && typeof parent.Ext != "undefined" && parent.Ext.WindowMgr.getActive()!=null);
    return (isWindowContainedInDivFrame ? parent.Ext.WindowMgr.getActive().x+curleft : curleft);
}


function findAbsolutePosY(obj)
{
    var curtop = 0;
    if (document.getElementById || document.all)
    {
        while (obj.offsetParent)
        {
            curtop += obj.offsetTop;
            if (obj.offsetParent != document.body)
                curtop -= obj.offsetParent.scrollTop;
            obj = obj.offsetParent;
        }
    }
    else if (document.layers)
        curtop += obj.y;

    var isWindowContainedInDivFrame = window.parentAccesible && false; //(typeof parent != "undefined" && typeof parent.Ext != "undefined" && parent.Ext.WindowMgr.getActive()!=null);
    return (isWindowContainedInDivFrame ? parent.Ext.WindowMgr.getActive().y+curtop : curtop);
    //return curtop;
}


function findPosX(obj)
{
    var curleft = 0;
    var isExtLoaded = (window.parentAccesible && parent && parent.Ext); //adding check for webstore Issue #203781
    var isWindowContainedInDivFrame = (isExtLoaded ?  parent.Ext.WindowMgr.getActive()!=null : false);
    //following conditional logic attempts to address Issue #200936 regarding date pickers in Chrome and Safari within new Ext popups
    if (isWindowContainedInDivFrame && (parent.Ext.isSafari || parent.Ext.isChrome)) {
        curleft = obj.offsetParent.offsetLeft;
    }
    else if (document.getElementById || document.all)
    {
        while (obj.offsetParent)
        {
            curleft += obj.offsetLeft
            obj = obj.offsetParent;
        }
    }
    else if (document.layers)
        curleft += obj.x;

    return curleft;
}


function findPosY(obj)
{
    var curtop = 0;
    if (document.getElementById || document.all)
    {
        while (obj.offsetParent)
        {
            curtop += obj.offsetTop;
            obj = obj.offsetParent;
        }
    }
    else if (document.layers)
        curtop += obj.y;

    return curtop;
}

function getParentElementByTag(tag, element)
{
    if(!tag)
        return null;

    var elem = element;

    while(elem != null)
    {
        if (elem.tagName.toLowerCase() == tag.toLowerCase())
            return elem;
        if (elem == elem.parentNode)
            break;
        elem = elem.parentNode;
    }
    return null;
}


function contains(parentElem, childElem)
{
    var elem = childElem;

    while(elem != null)
    {
        if (elem == parentElem)
            return true;
        elem = elem.parentNode;
    }
    return false;
}


function fireProperOnChange(elem, win)
{

    if (elem != null)
    {
        if (win == null)
            win = window;
        if (elem.getAttribute('onChangeFunc'))
            win.localEval(elem.getAttribute('onChangeFunc').replace(/this/g,'document.forms.'+elem.form.name+'.'+elem.name));
        else if ((elem.type == "checkbox" || elem.type == "radio") && elem.onclick)
            elem.onclick();
        else if (elem.onchange)
            elem.onchange();
    }

}


function getInlineTextValue(node)
{

 if (( typeof node == 'undefined') || node == null)
        return "";


        var textValue = "";
        if(node.innerText){ // IE, Chrome, Opera
            textValue = node.innerText;
        } else {
            // Firefox
            // Note: there's no need to check <BR>, <br/> etc. as innerHTML unifies that to <br>
            textValue = node.innerHTML.replace(/<br>/gi, '\n').replace(/(<([^>]+)>)/gi,"");
        }
        return textValue;

}

function setInlineTextValue(node, value)
{
    if ( node == null )
        return;
    node.innerHTML = value;

}

function findUp(node, type)
{
    while ((node != null) && (node.nodeName != type))
        node = node.parentNode;
    return node;
}




function getEvent(evnt)
{
    return (typeof(evnt)!='undefined' && evnt) ? evnt : ((typeof(event)!='undefined' && event) ? event : null);
}


function getEventKeypress(evnt)
{
    evnt = getEvent(evnt);

    return (evnt.which) ? evnt.which : evnt.keyCode;

}


function getEventAltKey(evnt)
{
    evnt = getEvent(evnt);

    if (evnt && typeof evnt.altKey != "undefined")
	{
        return evnt.altKey;
    }
    else if(typeof event != "undefined" && typeof event.altKey != "undefined")
    {
        return event.altKey;
    }

	return false;
}

function getEventMacCommandKey(evnt)
{
	
		return false;
	
}

function getEventCtrlKey(evnt)
{
    evnt = getEvent(evnt);
    return (evnt) ? evnt.ctrlKey : false;
}

function getEventShiftKey(evnt)
{
    evnt = getEvent(evnt);
    return (evnt) ? evnt.shiftKey : false;
}


function getEventTarget(evnt)
{
    evnt = getEvent(evnt);
    if (evnt)
    {
        if (evnt.srcElement)
            return evnt.srcElement;         
        if (evnt.target)
            return evnt.target;             
    }

    return null;                            
}


function getEventTargetType(evnt)
{
    evnt = getEventTarget(evnt);
    return (evnt) ? evnt.type : null;
}


function setEventPreventDefault(evnt)
{
    evnt = getEvent(evnt);
    if (evnt)
    {
        if (evnt.preventDefault)
            evnt.preventDefault();
        else
            evnt.returnValue = false;
    }
}


function setEventCancelBubble(evnt)
{
    evnt = getEvent(evnt);
    if (evnt)
    {
        if (evnt.stopPropagation)
            evnt.stopPropagation();
        else
            evnt.cancelBubble = true;
    }
}


function restoreHtmlEditors( frm )
{
    if ( typeof NetSuite == "object" && typeof NetSuite.RTEManager == "object" )
    {
		var vfFunc = document.forms['main_form'] != null && document.forms['main_form'].elements.nlapiVF != null ? document.forms['main_form'].elements.nlapiVF.value : null;
		try
		{
			if (vfFunc != null)
				document.forms['main_form'].elements.nlapiVF.value = '';
            NetSuite.RTEManager.getMap().eachKey(function (key, value) {
                var editor = value.obj;
				if ( frm == null || editor.hddn.form == frm ) {
                    editor.setValue( editor.hddn.value );
                }
             });
		}
		finally
		{
			if (vfFunc != null)
				document.forms['main_form'].elements.nlapiVF.value = vfFunc;
		}
	}
}

function nlFieldHelp(p,f,fld)
{
    var url = '/core/help/fieldhelp.nl?fld='+f+'&perm='+p;
    if (NS && NS.Dashboard)
    {
        nlExtOpenWindow(url, 'fieldhelp', 350, 100, fld, "no", "Field Help", {}, fld);
        return false;
    }

    var winname = 'fieldhelp';
    var width = 350;
    var height = 150;
    if (fld != null)
    {
        var left= Math.min(screen.availWidth-width,getObjectLeft(fld));
        var top = Math.min((screen.availHeight-40)-height,getObjectTop(fld) + fld.offsetHeight);
    }
    var win = window[winname];
    
    if (typeof win == "undefined" ||  win == null || win.closed )
        win = window.open(url, winname, 'scrollbars='+(isIE ? 'no' : 'yes')+',width='+Math.min(screen.availWidth,width)+',height=50,left=' + left + ',top=' + top + ',resizable=yes');
    else
    {
        win.location = url;
        win.moveTo(left, top);
    }
    win.focus();
    window[winname] = win;

    return false;
}


function dumpObj(obj)
{
    for(var prop in obj)
    {
        var str = prop + ": " + obj[prop];
        document.body.appendChild(document.createTextNode(str));
        document.body.appendChild(document.createElement("BR"));
    }
    if (obj.style)
    {
        document.body.appendChild(document.createTextNode("STYLE:"));
        document.body.appendChild(document.createElement("BR"));
        dumpObj(obj.style);
    }
}


function NLAlert(msg,ignoreServerSide)
{
    alert(msg);
}



/* Miscellaneous functions */
function nsapiIsString(obj)
{
    return typeof obj === 'string' || obj instanceof String || nsapiInstanceOf(obj, 'String');
}
function nsapiInstanceOf(obj, typeName)
{
	if (typeof obj === 'undefined' || obj === null)
		return false;
	var rep = Object.prototype.toString.call(obj);
	if (rep.slice(8, -1) === typeName)
		return true;
	if (typeof obj.constructor === 'undefined')
		return false;
	if (typeof obj.constructor.name !== 'undefined')
		return obj.constructor.name === typeName;
	var m = /^function ([^( ]+)/.exec(obj.constructor.toString());
	return !!(m && m[1] == typeName);
}
/* Array utilities */
function arrayIndexOf(array, val, ignorecase)
{
    for ( var i = 0; array != null && i < array.length; i++ )
        if ( val == array[i] || (ignorecase && val != null && array[i] != null && val.toLowerCase() == array[i].toLowerCase()) )
            return i;
    return -1;
}
function arrayContains(array, val)
{
    return arrayIndexOf(array, val) >= 0;
}
function arrayAdd(array, val)
{
    if ( !arrayContains(array, val) )
        array.push(val);
}
function arrayRemove(array, val)
{
    var newarray = new Array();
    for ( var i = 0; i < array.length; i++ )
        if ( val != array[i] )
            newarray.push(array[i]);
    return newarray;
}
function getArrayIntersection(array1, array2)
{
    var resultArray = new Array();
    for (var i = 0; i < array1.length; i++)
    {
        for (var j = 0; j < array2.length; j++)
        {
            if (array1[i] == array2[j])
            {
                resultArray[resultArray.length] = array1[i];
                array2[j] = null;
                break;
            }
        }
    }
    return resultArray;
}
function isArray(obj)
{
	return obj instanceof Array || nsapiInstanceOf(obj, 'Array');
}
function nsapiEveryElementIs(array, pred)
{
    if (!isArray(array))
        return false;
    for (var i=0; i<array.length; ++i)
    {
        if (!pred(array[i]))
            return false;
    }
    return true;
}
function nsapiMap(array, func)
{
	var result = [];
	for (var i=0; i<array.length; ++i)
	{
		result.push(func(array[i]));
	}
	return result;
}
/* Search filter expression functions */
function nsapiIsSearchFilterExpression(array)
{
    return nsapiEveryElementIs(array, nsapiIsSearchFilterTerm);
}
function nsapiIsFlatSearchFilterList(array)
{
    return nsapiEveryElementIs(array, nsapiIsSearchFilterObject);
}
function nsapiIsSearchFilterTerm(obj)
{
    if (typeof obj === 'undefined' || !obj)
        return false;
    if (nsapiIsString(obj))
        return /not|and|or/i.test(obj);
    if (nsapiIsSearchFilterArray(obj))
        return true;
    return nsapiIsSearchFilterExpression(obj);
}
function nsapiNormalizeFilters(filters)
{
	return nsapiIsSearchFilter(filters) ? [filters] : (typeof filters === 'undefined' ? null : filters);
}
function nsapiIsSearchFilter(obj)
{
	return nsapiIsSearchFilterObject(obj) || nsapiIsSearchFilterArray(obj);
}
function nsapiIsSearchFilterObject(obj)
{
	return obj instanceof nlobjSearchFilter || nsapiInstanceOf(obj, 'nlobjSearchFilter');
}
function nsapiIsSearchFilterArray(arr)
{
	return isArray(arr) && arr.length >= 3 && nsapiIsString(arr[0]) && nsapiIsString(arr[1]) && !/^not$/i.test(arr[0]);
}
function nsapiCheckSearchFilterExpression(arrayObj, name)
{
    nsapiAssertTrue(arrayObj === null || nsapiIsSearchFilterExpression(arrayObj), 'SSS_INVALID_SRCH_FILTER_EXPR_OBJ_TYPE', name);
}
function nsapiCheckSearchFilterListOrExpression(arrayObj, name)
{
    nsapiAssertTrue(arrayObj === null || nsapiIsFlatSearchFilterList(arrayObj) || nsapiIsSearchFilterExpression(arrayObj), 'SSS_INVALID_SRCH_FILTER_EXPR_OBJ_TYPE', name);
}

// Given a translation string containing zero or more parameter strings, and zero or more comment strings, remove them
// and replace parameter strings with corresponding parameters passed into this function.
// - Although it looks like this function takes one argument, it takes an arbitrary number.
//   Example: format_message("Is Not {1:boolean value}", "True").
// - This function also handles choice formats starting with @@@, e.g. "@@@is {1:value} || is not {1:value}". In that
//   case the selector is the first parameter.
// - In addition to separate param args, all param args can be passed in in an array. In this case, the selector
//   is still separate from the other parameters. Example: format_message("Day {1:dom} of {2:month}", [ 4, 'June' ]).
function format_message(pattern)
{
	var len = format_message.arguments.length;
	var offset = 1;

	// Handle choice formats (not the real ones; just simple NetSuite-style choice formats).
	if (pattern.length >= 3 && pattern.substring(0, 3) == '@@@')
	{
		var choicePatterns = pattern.substring(3).split(/\s*\|\|\s*/);
		var selector = 0;
		if (len >= 2)
		{
			selector = format_message.arguments[1];
			if (typeof(selector) == 'boolean')
				selector = selector ? 0 : 1;
			else if (typeof(selector) == 'string')
				selector = parseInt(selector);
			if (typeof(selector) != 'number')
				selector = 0;
		}
		if (selector >= choicePatterns.length)
			selector = 0;
		pattern = choicePatterns[selector];

		offset = 2;
	}

	else if (pattern.length >= 2 && pattern.substring(0, 2) == '@@')
	{
		// No good solution here -- this method doesn't support native JDK formats with nested ChoiceFormat patterns.
		return '?';
	}

	// Allow passing in a single array of all arguments. This does NOT include the selector, if there is one.
	var params = format_message.arguments;
	if (len == (offset + 1) && format_message.arguments[offset].constructor == Array)
	{
		params = format_message.arguments[offset];
		offset = 0;
		len = params.length;
	}

	return pattern.replace(/{(?:(\d+)|:)[^}]*}/g,
		function(match, id)
		{
			var n = id ? (parseInt(id) - 1 + offset) : len;
			return (n < len) ? params[n] : ''
		});
}



function nlInsertCanvas(insertCanvasDiv)
{
    
    var canvas = document.getElementById( getCanvasId(insertCanvasDiv) );
    if ( canvas == null )
    {
        canvas = document.createElement('IFRAME');
        canvas.id = getCanvasId(insertCanvasDiv);
        canvas.src = 'javascript:false';
        canvas.scrolling = 'no';
        canvas.style.display = 'none';
        canvas.style.frameBorder = '0';
        if ( isIE )
          canvas.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=0)";
        canvas.style.position = 'absolute';
        canvas.style.top = '0px';
        canvas.style.left = '0px';
        document.body.appendChild( canvas );
    }

    nlSyncCanvas( insertCanvasDiv );
    canvas.style.display = "block";
    
}

function nlSyncCanvas(syncCanvasDiv)
{
    
    var canvas = document.getElementById( getCanvasId(syncCanvasDiv) );
    if ( canvas == null )
        return;

    canvas.style.width = syncCanvasDiv.offsetWidth + "px";
    canvas.style.height = syncCanvasDiv.offsetHeight + "px";
    canvas.style.top = syncCanvasDiv.style.top + "px";
    canvas.style.left = syncCanvasDiv.style.left + "px";
    canvas.style.zIndex = syncCanvasDiv.style.zIndex - 1;
    
}

function nlRemoveCanvas(div)
{
    
    var canvas = document.getElementById( getCanvasId(div) );
    
    if (canvas != null)
        document.body.removeChild( canvas );
    
}

function getCanvasId(div)
{
    return div.id+'_canvas';
}

function findClassUp(node, clss)
{
    
    while ((node != null) && (node.className != clss && node.classAlias != clss))
        node = node.parentNode;
    return node;
}

function getScrollLeftOffset(btn)
{
    
    var scrollLeftOffset = 0;
    var scrollDiv;
    if(btn != null && (scrollDiv = findClassUp(btn,'scrollarea')) != null)
    {
        scrollLeftOffset = scrollDiv.scrollLeft;
    }
    else if ( (scrollDiv = document.getElementById('div__body')) != null )
    {
        scrollLeftOffset = scrollDiv.scrollLeft;
    }

    return scrollLeftOffset;
}

function getScrollTopOffset(btn)
{
    
    var scrollTopOffset = 0;
    var scrollDiv;
    if(btn != null && (scrollDiv = findClassUp(btn,'scrollarea')) != null)
    {
        scrollTopOffset = scrollDiv.scrollTop;
    }
    else if ( (scrollDiv = document.getElementById('div__body')) != null )
    {
        scrollTopOffset = scrollDiv.scrollTop;
    }

    return scrollTopOffset;
}

/**
 * remove all the child nodes
 */
function removeAllChildren(obj)
{
    while (obj.childNodes[0])
    {
        obj.removeChild(obj.childNodes[0]);
    }
}


function StringBuffer() { this.buffer = []; }
StringBuffer.prototype.append = function(string)
{
    this.buffer.push(string);
    return this;
}
StringBuffer.prototype.toString = function()
{
    return this.buffer.join("");
}


function setObjectOpacity(opacity, styleElem)
{
    var style = styleElem.style;
    style.opacity = (opacity / 100);
    style.MozOpacity = (opacity / 100);
    style.filter = "alpha(opacity=" + opacity + ")";
}

function fadeObjectOpacity(styleElem, startOpacity, endOpacity, elapsedTime)
{
    var speed = Math.round(elapsedTime / 100);
    var timer = 0;

    if(startOpacity > endOpacity)
    {
        for(i = startOpacity; i >= endOpacity; i--)
        {
            setTimeout(function(){setObjectOpacity(i, styleElem);}, (timer * speed));
            timer++;
        }
    }
    else if(startOpacity < endOpacity)
    {
        for(i = startOpacity; i <= endOpacity; i++)
        {
            setTimeout(function(){setObjectOpacity(i, styleElem);}, (timer * speed));
            timer++;
        }
    }
}

function tellafriend(strSubject, strAddress, strBodyMain, strBodyName, strBodyPrice, strBodyLink, strPrice)
{
var strBody = escape(strAddress)+ ",%0d%0a%0d%0a";
strBody += escape(strBodyMain) + escape(location.hostname) + ".%0d%0a%0d%0a";
strBody += escape(strBodyName) + escape(document.title) + ".%0d%0a";
strBody += escape(strBodyPrice) + escape(strPrice)+ "%0d%0a";
strBody += escape(strBodyLink) + escape(location.href) + "%0d%0a";
location.href = "mailto:?subject=" + escape(strSubject) + "&body=" + strBody;
}


function isLeftButtonDown(evnt)
{
    var bLeftClick = false;
    var e = getEvent(evnt);

    if(isIE && e.button==1 || (!isIE && e.button==0))
        bLeftClick = true;

    return bLeftClick;

}

function isRightButtonDown(evnt)
{
    var bRightClick = false;
    var e = getEvent(evnt);

    if(e.button==2) // ie, mozilla (ctrl-click on mac)
        bRightClick = true;

    return bRightClick;

}


function getSelectedTextRange (elem)
{
    var startPos;
    var endPos;
    if (document.all)
    {
        var selectedText = document.selection.createRange();
        var range = selectedText.duplicate();
        range.moveToElementText(elem);
        range.setEndPoint('EndToEnd', selectedText);
        startPos = range.text.length - selectedText.text.length;
        endPos   = startPos + selectedText.text.length;
    }
    else
    {
        startPos = elem.selectionStart;
        endPos   = elem.selectionEnd;
    }
    var range = new Array();
    range[0] = startPos;
    range[1] = endPos;
    return range;
}


function insertTextAtCursor (elem, text)
{
    elem.focus();
    if (document.all)
    {
        var sel = document.selection.createRange();
        sel.text = text;
        sel.scrollIntoView(true);
    }
    else
    {
        var startPos = elem.selectionStart;
        var endPos   = elem.selectionEnd;
        elem.value = elem.value.substring(0, startPos) + text + elem.value.substring(endPos);
        
        elem.selectionEnd = elem.selectionStart + text.length;
        elem.selectionStart = elem.selectionEnd;
    }
}

function setWindowChanged(win, bChanged)
{
    win.NS.form.setChanged(bChanged);
}

function escapeHTML (text)
{
    var div = document.createElement('div');
    var textNode = document.createTextNode(text);
    div.appendChild(textNode);
    return div.innerHTML;
}

function escapeHTMLAttr (text)
{
    var text = escapeHTML(text);
    return text.replace(/"/g, "&quot;").replace(/'/g, "&#39;");
}


function getRuntimeSize(el, styleProp)
{
    var val = getRuntimeStyle(el, styleProp);
    if (!val)
        return 0;
    val = val.replace("px", "")
    if (isNaN(val)) 
        return 0;
    return val*1.0; //return number only
}


function getRuntimeStyle(el, styleProp)
{
    var val = null
    if (typeof el == "string")
        el = document.getElementById(el);
    if (el == null)
        return val;

    
	if (window.getComputedStyle)
	    val = document.defaultView.getComputedStyle(el, null)[styleProp];
    else if (el.currentStyle)
        val = el.currentStyle[styleProp];

    if (val == "auto")
    {
        if (styleProp == "height")
            val = el.offsetHeight;
        else if (styleProp == "width")
            val = el.offsetWidth;
    }
	return val;
}



function camelize(str)
{
    var parts = str.split('-')
    var len = parts.length;
    if (len == 1) return parts[0];

    var camelized = str.charAt(0) == '-'
      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
      : parts[0];

    for (var i = 1; i < len; i++)
      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);

    return camelized;
}

function eval_js(sScript)
{
	sScript = sScript.replace(/^\s*<!--[\s\S]*?-->\s*$/gm, '');

    try {
        return eval(sScript);
        } catch (e) {
            

            if (e instanceof SyntaxError) {
                //alert(e.message);
            }
        }
	//return eval(sScript);
}

var slave_machines = new Array();
function extractMachineHtmlFromText(components)
{
	for (var i=0;i<components.length;i++)
	{
		var idx = components[i].indexOf("name='")+6;
		var name = components[i].substring(idx, components[i].indexOf("'>", idx));
		slave_machines[name] = components[i].substring(components[i].indexOf("'>")+2, components[i].lastIndexOf("</machine>"));
	}
}
function isFunction(obj)
{
    return Object.prototype.toString.call(obj) === '[object Function]';
}
function process_slaving_result(response)
{
    var sText = response.getBody();
    var components=sText.split("<machine");
    extractMachineHtmlFromText(components);
    var script = components[0];

    if(response.getHeaders()['newslaving'] != null)
	{
        eval(script);

        if(slaveValues['machinesData'])
    {
			slavingUtil.redrawEditMachines(slaveValues['machinesData']);
		}
        slavingUtil.processSlavingValues(slaveValues['body']);
        if(slaveValues['aspectScript'] != null)
            if(isFunction(slaveValues['aspectScript']))
                slaveValues['aspectScript'].call();
		NS.form.setInited(true);
		window.status = '';
    }
	else
	{
	eval_js(script);
	}

	slave_machines = new Array();

}
var process_slaving_result_original = process_slaving_result;

var performSlavingAsync = true;
function setSlavingAsync(async)
{
    performSlavingAsync = async;
}
function getSlavingAsync()
{
    return performSlavingAsync;
}


function loadSlavingResults(url, callbacks, asynch)
{

    var func = process_slaving_result;
    if(!!callbacks){
        if(typeof callbacks === 'function'){
            func = function(){
                process_slaving_result.apply(this, arguments);
                callbacks.apply(this, arguments);
            };
        } else if (Object.prototype.toString.call(callbacks) === '[object Array]'){
            func = function(x){
                var i = 0;

                process_slaving_result.apply(this, arguments);;
                while(i < callbacks.length){
                    callbacks[i++].apply(this, arguments);
                }
            };
        }
    }
    /*if the caller doesn't want to override the asynch - just for this call, use the default value*/
    /*more common way to change asynch is to use setSlavingAsync(boolean) before calling this method*/
    if (typeof asynch === 'undefined' || asynch === null)
    {
        asynch = getSlavingAsync();
    }
	nlXMLRequestURL(url, null, null, func, asynch);

}

function execute_js(response, postResponseFn)
{
	eval_js(response.getBody());
	if (postResponseFn)
		postResponseFn();
}


function NLGetCurrentScriptFileHostName()
{
   var scripts = document.getElementsByTagName('script');
   if (!scripts || scripts.length == 0)
       return null;

   var currentScriptFileUrl = scripts[scripts.length - 1].src;
   if (!currentScriptFileUrl)
       return null;

   var hostName = currentScriptFileUrl.match(/^((http|https):\/\/)?[^\/]+/g);
   if (hostName && hostName.length>0)
       hostName = hostName[0];
   if (!hostName)
       hostName = "";

   return hostName;
}


function NLLoadScriptInScriptTag(sUrl, id, doc)
{
   if (!doc)
       doc = document;

   var script = doc.getElementById(id);
   if (!script)
   {
       var head= doc.getElementsByTagName('head')[0];   
       script= doc.createElement('script');
       script.type= 'text/javascript';
       head.appendChild(script);
   }
   script.src= sUrl;
}

function loadXMLJSDoc(url, postResponseFn)
{
	nlXMLRequestURL(url, null, null, function(response) { execute_js(response, postResponseFn); }, true);
}

/*
issue a GET or POST request for an Internal URL resource
support for external resources can be added later if needed.
copied from nlapiRequestURL to avoid unnecessary dependency
*/
function nlXMLRequestURL(url, postdata, headers, responseHandler, async)
{
    var request = new NLXMLHttpRequest();
    if ( responseHandler instanceof Function )
        request.setResponseHandler( responseHandler );
    var nsResponse = request.requestURL( url, postdata, headers, async )
    return nsResponse;
}

/*--------------- NLHttpXMLRequest class definition ------------*/
function NLXMLHttpRequest( ignoreErrors )
{
	this.requestPending = false;
	this.callbackFunc = null;
    this.ignoreResponseErrors = ignoreErrors;
    if ( window.XMLHttpRequest )
		this.xmlrequest = new XMLHttpRequest();
	else
	{
		try	{ this.xmlrequest = new ActiveXObject("Msxml2.XMLHTTP.4.0"); }
		catch ( e )	/* OLC requires at least MSXML v4.0 */	{ this.xmlrequest = isOffline() ? null : new ActiveXObject("Msxml2.XMLHTTP"); }
	}
}
NLXMLHttpRequest.prototype.setResponseHandler = function( callbackFunc )
{
    this.callbackFunc = typeof callbackFunc == "function" ? callbackFunc : null;
}
NLXMLHttpRequest.prototype.requestURL = function( url, postdata, requestHeaders, async, httpMethod )
{
	if ( this.requestPending )
		return;

	this.requestPending = true;
	var method;

	if (!isValEmpty(httpMethod))
	    method = httpMethod;
	else
	    method = postdata != null ? "POST" : "GET";

	this.xmlrequest.open( method, url, (async != null ? async : false) );
	for ( var header in requestHeaders )
		this.xmlrequest.setRequestHeader( header, requestHeaders[ header ] );
    this.xmlrequest.setRequestHeader("NSXMLHttpRequest", "NSXMLHttpRequest");
    if ( method == 'POST' || method == 'PUT')
    {
        if ( postdata instanceof String || typeof postdata == "string" || nsInstanceofDocument( postdata ) )
            this.xmlrequest.setRequestHeader("Content-Type", "text/xml; charset=UTF-8");
        else
        {
            postdata = formEncodeURLParams( postdata );
            this.xmlrequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        }
    }
    var response = null;
	if ( async )
	{
		this.xmlrequest.onreadystatechange = this.handleResponse.bindAsEventListener( this );
		this.xmlrequest.send( postdata );
	}
	else
	{
		this.xmlrequest.send( postdata );
		response = this.handleResponse( );
	}
	return response;
}
NLXMLHttpRequest.prototype.handleResponse = function()
{
	var response = null;
	if ( this.xmlrequest.readyState == 4 )  /* For now, we'll not worry about the Loading, Loaded, Interactive readyStates  */
	{
		var responseCode = this.xmlrequest.status;
		var responseBody = this.xmlrequest.responseText;
		var responseHeaders = new Array();
		var responseHeadersArray = this.xmlrequest.getAllResponseHeaders();
		var trim = String.prototype.trim || function(){
            return this.replace(/^\s+|\s+$/gm,'');
        };
        var isJson = function(body)
        {
            if(!body)
                return false;
            body = trim.call(body);
            return body && body.indexOf('{') === 0 && body.lastIndexOf('}') === body.length - 1;
        }

		responseHeadersArray = responseHeadersArray.replace(/^\s+/,"").replace(/\s+$/,"").split("\n");
		for ( var i = 0; i < responseHeadersArray.length; i++ )
		{
			var responseArray = responseHeadersArray[i].split(":");
			var header = responseArray[0];
            var valueArray = responseHeaders[ header ];
            if ( valueArray == null )
            {
                valueArray = new Array();
                responseHeaders[ header ] = valueArray
            }
            valueArray[valueArray.length] = responseArray[1];
		}
        /* Extract Netsuite Server Error (if one exists)  */
        /*
            kevinng 4/7/2011
            responseCode must be 200 or 206 with non-empty responseBody (see NLErrorPage.prepResponse())
            the changes include the fix for issue 193944 (CL 401296)
         */
		var responseError = null;
        if (responseBody && responseBody.toLowerCase().indexOf('error')>=0)
        {
            if (isJson(responseBody))
            {
                if (responseBody.indexOf('{"error"') >= 0)
                {
                    var onlineError = JSON.parse(responseBody);
                    responseError = new NLXMLResponseError(onlineError.error.code, onlineError.error.message);
                }
            }
            else if ( responseBody.indexOf('<onlineError>') >= 0 )
            {
                var onlineError = nsStringToXML( responseBody );
                responseError = new NLXMLResponseError( nsSelectValue( onlineError, '/onlineError/code' ), nsSelectValue( onlineError, '/onlineError/detail' ), nsSelectValue( onlineError, '/onlineError/id' ) );
            }
            else if ( responseBody.indexOf('<error>') >= 0 )
            {
                var onlineError = nsStringToXML( responseBody );
                responseError = new NLXMLResponseError( nsSelectValue( onlineError, '/error/code' ), nsSelectValue( onlineError, '/error/message' ) );
            }
            // This error is returned for restlet and the error code is set to 4xx(client error) or 5xx(server error) and won't be 200. Not exclude 206 because it is returned as an error in NLErrorPage.
            else if ( responseBody.indexOf('error code:') >= 0 && responseBody.indexOf('error message:') >= 0 && responseCode != 200)
            {
                var onlineError = responseBody.split("\n");
                responseError = new NLXMLResponseError( onlineError[0].substring("error code: ".length), onlineError[1].substring("error message: ".length) );
            }
        }
        else if ( responseCode != 200 && responseCode != 206 )
            responseError = new NLXMLResponseError( 'SERVER_RESPONSE_ERROR', responseBody );
		try
		{
			if ( responseError != null && this.callbackFunc == null && !this.ignoreResponseErrors )
				throw responseError;
			response = new NLXMLResponse( responseCode, responseBody, responseHeaders, responseError );
			if ( this.callbackFunc != null )
			    this.callbackFunc( response );
		}
		finally
		{
			this.requestPending = false;
		}
	}
	return response;
}
/*--------------- NLXMLResponse class definition ------------*/
function NLXMLResponse( responseCode, responseBody, responseHeaders, responseError )
{
	this.code = responseCode;
	this.body = responseBody;
	this.headers = responseHeaders;
	this.error = responseError;

	this.getCode = function() { return this.code };
	this.getBody = function() { return this.body };
	this.getError = function() { return this.error };
	this.getHeaders = function() { return this.headers };
}
/*--------------- NLXMLResponse class definition ------------*/
function NLXMLResponseError( errorCode, errorBody, errorId )
{
	this.id = errorId;
	this.code = errorCode;
	this.details = errorBody;

	this.getId = function() { return this.id };
	this.getCode = function() { return this.code };
	this.getDetails = function() { return this.details };
}

/**
 * @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 Specify GET or POST.  GET is the default.
 */
function nsServerCall(url, methodName, methodParams, asyncCallback, httpMethod)
{
	var client = new NLJsonRpcClient(url);
	return client.sendRequest(methodName, methodParams, asyncCallback, httpMethod);
}

NLJsonRpcClient = function (serverURL)
{
	if (serverURL.indexOf("?") > 0)
		serverURL = serverURL + "&jrr=T";
	else
		serverURL = serverURL + "?jrr=T";
	this.serverURL = serverURL;
	this.responseCallbackMap = {};
};
NLJsonRpcClient.requestId = 0;
NLJsonRpcClient.prototype =
{
	sendRequest : function (methodName, args, callback, httpMethod)
	{
		httpMethod = httpMethod || "GET";
		var jsonRpcReq = {
			id : NLJsonRpcClient.requestId++,
			method : "remoteObject." + methodName,
			params : args || []
		};
		if (callback != null)
			this.responseCallbackMap[jsonRpcReq.id] = callback;
		var request = new NLXMLHttpRequest();
		if (callback != null)
			request.setResponseHandler(this.handleResponseAsync.bindAsEventListener(this));

		var url = this.serverURL;
		var postData = null;
		if ("GET" == httpMethod)
		{
		 	url += "&jrid=" + jsonRpcReq.id;
		 	url += "&jrmethod=" + jsonRpcReq.method;
		 	if (jsonRpcReq.params.length > 0)
		 		url += "&jrparams=" + encode(toJSON(jsonRpcReq.params));
		}
		if ("POST" == httpMethod || ("GET" == httpMethod && url.length > 2083)) // 2083 is max url length in IE
		{
			url = this.serverURL;
			postData = toJSON(jsonRpcReq);
		}
       	var response = request.requestURL(url, postData, null, callback != null ? true : false);
		if (callback == null)
		{
			var jsonRpcResp = this.getJsonRpcResponse(response);
			if (jsonRpcResp.error)
				throw new NLXMLResponseError(jsonRpcResp.error.code, jsonRpcResp.error.trace, jsonRpcResp.error.msg);
			response = jsonRpcResp.result;
		}
		return response;
	},

	getJsonRpcResponse : function (nlXMLResponseObj)
	{
		var jsonRpcResp = nlXMLResponseObj.getBody();
		if (jsonRpcResp != null)
			jsonRpcResp = jsonRpcResp.replace(/^\s*<!--[\s\S]*?-->\s*$/gm, '');
		eval("jsonRpcResp = " + jsonRpcResp + ";");
		return jsonRpcResp;
	},

	handleResponseAsync : function (nlXMLResponseObj)
	{
		var jsonRpcResp = this.getJsonRpcResponse(nlXMLResponseObj);
		var callback = this.responseCallbackMap[jsonRpcResp.id];
		this.responseCallbackMap[jsonRpcResp.id] = null;
		callback(jsonRpcResp.result, jsonRpcResp.error);
	}
}

if (typeof Function.prototype.bind !== 'function') {
    Function.prototype.bind = function(object) {
        var __method = this;
        return function() {
            __method.apply(object, arguments);
        }
    }
}

Function.prototype.bindAsEventListener = function(object) {
  var __method = this;
  return function(event) {
    __method.call(object, event || window.event);
  }
}

function isOffline()
{
	return window.isOLC != null;
}
function clone(srcobj)
{
	if(typeof(srcobj) != 'object') return srcobj;
	if(srcobj == null) return srcobj;

	var newObj = new Object();

	for(var i in srcobj)
		newObj[i] = clone(srcobj[i]);

	return newObj;
}

function hoverEffectOnFocus(fld)
{
    if (fld.parentNode.className.indexOf('_focus') >= 0)
        return;

    if (fld.parentNode.className.indexOf('_roll') == -1)
    {
        fld.parentNode.className=fld.parentNode.className+'_focus';
    }
    else
    {
       fld.parentNode.className=fld.parentNode.className.replace('_roll', '_focus');
    }
}


function hoverEffectOnBlur(fld)
{
  fld.parentNode.className = fld.parentNode.className.replace('_focus', '');
}

function leftPadWithWrapping(input, pad, colsAvail)
{
    // safety-inits, and check for edge cases
    if(pad==null) pad = '';
    if(input==null)
        input = '';
    else
        input = trim(input);

    // if colsAvail not longer than pad, we will never get through input.
    // input just gets truncated in this case and we return one line of pad
    if( colsAvail <= pad.length )
        return pad.substring(0,colsAvail);


    var newlen =  pad.length+input.length;  // len after padding
    if( newlen <= colsAvail ) { // we need not wrap
        return pad+input;
    }
    else{                       // we must wrap
        var i = input.length- (newlen-colsAvail);
        return (pad+input.substring(0,i)) + '\n' + leftPadWithWrapping(input.substring(i), pad, colsAvail);
    }
}

function nlFireEvent(element,event) {
        var eventType = 'HTMLEvents';
        if (event == 'click' || event.indexOf('mouse') == 0) {
            eventType = 'MouseEvents';
        }
        var evt = document.createEvent(eventType);
        evt.initEvent(event, true, true ); // event type,bubbling,cancelable
        return !element.dispatchEvent(evt);
}

function getOuterHTML(object)
{
    var element;
    if (!object) return null;

    if (object.outerHTML)
        return object.outerHTML;
    element = document.createElement("div");
    element.appendChild(object.cloneNode(true));
    return element.innerHTML;
}

function NLNumberToString(number, win)
{
    if (typeof win == 'undefined'){
        win = window;
    }

    str = number + '';
    if(win.groupseparator == '')
        return str;
    parts = str.split('.');
    integerPart = parts[0];
    decimalPart = parts.length > 1 ? win.decimalseparator + parts[1] : '';
    var regex = /(\d+)(\d{3})/;
    while (regex.test(integerPart))
    {
        integerPart = integerPart.replace(regex, '$1' + win.groupseparator + '$2');
    }

    if(number < 0 && win.negativeprefix != '-')
        return win.negativeprefix + integerPart.replace('-', '') + decimalPart + win.negativesuffix;
    else
        return integerPart + decimalPart;
}

function NLStringToNumber(str, addZeroPadding)
{
    if(isValEmpty(str))
        return "";
    // handle percentage string
    if(str.indexOf('%') >= 0)
        return NLStringToNumber(str.replace('%',''),addZeroPadding) + '%';
    if(window.groupseparator && window.groupseparator != '')
        str = str.replace(new RegExp( '\\' + window.groupseparator, 'g'), '');
    if(window.negativeprefix != '-' && str.indexOf(window.negativeprefix) == 0)
        str = '-' + str.replace(window.negativeprefix, '').replace(window.negativesuffix, '');
    if(window.decimalseparator == ',')
        str = str.replace(',', '.');

    var number = parseFloat(str);
    if (isNaN(number))
    {
        return NaN;
    }

    if (addZeroPadding)
    {
        var paddingLength = 0;
        var decimalSeperatorIndex = str.indexOf(".");
        if (decimalSeperatorIndex != -1)
            paddingLength = str.length - decimalSeperatorIndex - 1;
        number = number.toFixed(paddingLength);
    }
    return number;
}

// first convert string to number, then pad trailing 0's to match the original string's trailing 0's
function NLStringToNormalizedNumberString(str)
{
    var decimalSeperatorIndex = str.indexOf(window.decimalseparator);
    return NLStringToNumber(str, decimalSeperatorIndex != -1) + "";
}


    //Function to show field in the form.
//  on base of the name of element, call display function
//  display for element and parent element
function showField ( spanId, on )
{
    var spanInput = document.getElementById(spanId);
    display(spanInput, on );

    var elem = !!NS && !!NS.UI && !!NS.UI.Helpers && !!NS.UI.Helpers.getClosestAncestorFromClass &&
            NS.UI.Helpers.getClosestAncestorFromClass(document.getElementById(spanId), 'uir-field-wrapper');

    if (on && elem) {
        display(elem, on);
    }

    if (spanInput != null) {
        var parent = spanInput.parentNode;
        if(parent.nodeName == "LI" || (parent.nodeName == "TD" && parent.style.height == "22px"))
            display(parent, on);
    }
}

//Function to display or hide element
function display(elem, on )
{
    if (elem != null)
        elem.style.display = on ? '' : 'none';
}

function isNLNumericOrCurrencyFieldRequired(fld)
{
    var displayField = getNLNumericOrCurrencyDisplayField(fld);
    if (!displayField)
        return false;
    return isRequiredFieldClassName(displayField);
}

function setNLNumericOrCurrencyFieldRequired(fld, required)
{
    var displayField = getNLNumericOrCurrencyDisplayField(fld);
    if (!displayField)
        return false;
    return doSetRequired(displayField, fld.name, required);
}


function setRequired(fld,required)
{
    if ( isNLDropDown(fld))
        getDropdown(fld).setRequired(required);
    else if ( isNLMultiDropDown( fld ) )
        getMultiDropdown(fld).setRequired(required);
    else if ( window.getHtmlEditor != null && getHtmlEditor( fld.name ) != null && getHtmlEditor(fld.name).setMandatory)
        getHtmlEditor( fld.name ).setMandatory( required );
    else if ( fld.form != null && fld.form.elements[fld.name+"_display"] != null )
    {
        if (typeof fld.form.elements[fld.name+"_display"].className == "undefined")
            fld.form.elements[fld.name+"_display"].className = "";
        var className = fld.form.elements[fld.name+"_display"].className;
        var fromClassName = (getRequired(fld) ? 'inputreq' : 'input');
        var toClassName = (required ? 'inputreq' : 'input');
        if (className.indexOf(fromClassName) < 0)
            className = toClassName + " " + className;
        else
            className = className.replace(fromClassName, toClassName);
        fld.form.elements[fld.name+"_display"].className = className;
        setFieldLabelRequired(fld.id, required);
    }
    else if (isNumericField(fld) || isCurrencyField(fld))
        return setNLNumericOrCurrencyFieldRequired(fld, required);
    else
        doSetRequired(fld, fld.id, required);
}

// internal method, do not call directly
function doSetRequired(fld, fldName, required)
{
    if (typeof fld.className == "undefined")
        fld.className = "";
    var className = fld.className;
    var alignRight = (className.indexOf('inputrt') >= 0);
    var fromClassName = 'input' + (alignRight ? 'rt' : '') + (getRequired(fld) ? 'req' : '');
    var toClassName = 'input' + (alignRight ? 'rt' : '') + (required ? 'req' : '');
    if (className.indexOf(fromClassName) < 0)
        className = toClassName + " " + className;
    else
        className = className.replace(fromClassName, toClassName);
    fld.className= className;
    if(fld.machine != undefined) {
        fldName = fld.machine.name + "_" + fldName;
    }
    setFieldLabelRequired(fldName, required);
}


function setFieldLabelRequired(fldName, required, fldForm)
{
    if (fldName)
    {
        fldName = fldName.replace('inpt_', '');
        fldName = fldName.replace('hddn_', '');
        fldName = fldName.replace('_fs', '');

        var label = document.getElementById(fldName + '_fs_lbl');

        if (label)
        {
        
            if (label.parentNode && label.parentNode.firstChild != label)
                return;

        
            if (fldForm)
            {
                var labelForm = getParentElementByTag("form", label);
                if (labelForm && labelForm != fldForm)
                {
                    return;
                }
            }

            var labels = label.getElementsByTagName("label");
            var asteriskLabel;
            for (var i = 0; i < labels.length; i++)
            {
                if (labels[i].className == 'uir-required-icon')
                {
                    asteriskLabel = labels[i];
                    break;
                }
            }

            if (required && !asteriskLabel)
            {
                asteriskLabel = document.createElement('label');
                asteriskLabel.className = 'uir-required-icon';
                asteriskLabel.textContent = '*';

                if (NS && NS.UI && NS.UI.Preferences && NS.UI.Preferences.horizontalLabelsEnabled)
                {
                    label.insertBefore(asteriskLabel, label.firstChild);
                }
                else
                {
                    label.appendChild(asteriskLabel);
                }
            }
            else if (!required && asteriskLabel)
            {
                label.removeChild(asteriskLabel);
            }
        }
    }
}

function getRequired(fld)
{
    if ( isNLDropDown(fld) )
        return getDropdown(fld).getRequired( );
    else if ( isNLMultiDropDown( fld ) )
        return getMultiDropdown(fld).getRequired( );
    else if ( window.getHtmlEditor != null && getHtmlEditor( fld.name ) )
        return getHtmlEditor( fld.name ).getMandatory( );
    else if ( fld.form != null && fld.form.elements[fld.name+"_display"] != null )
        return fld.form.elements[fld.name+"_display"].className != null && fld.form.elements[fld.name+"_display"].className.indexOf('inputreq') != -1;
    else if ( (isNumericField(fld) || isCurrencyField(fld)) && fld.name.indexOf("_formattedValue")==-1)
        return isNLNumericOrCurrencyFieldRequired(fld);
    else
        return isRequiredFieldClassName(fld);

}

function isRequiredFieldClassName(fld){
    return fld.className != null && (fld.className.indexOf('inputreq') != -1 || fld.className.indexOf('inputrtreq') != -1);
}

function disableSelect(sel, val, win)
{
	
	if ( sel != null )
	{
		var doc = win != null ? win.document : sel.document != null ? sel.document : window.document;
		if (sel.type == "select-one" || sel.type == "select-multiple")
			sel.disabled = val;
		else if (isNLDropDown(sel))
			getDropdown(sel, win).setDisabled(val);
		else if (isNLMultiDropDown(sel))
			getMultiDropdown(sel, win).setDisabled(val);
		else
		{
			var displaytext = sel.form.elements[sel.name+"_display"];
			if (displaytext != null)
				displaytext.disabled=val;
			var listlink = doc.getElementById(sel.name+"_popup_list");
			if (listlink != null)
				listlink.style.visibility = val ? "hidden" : "inherit";
			var searchlink = doc.getElementById(sel.name+"_popup_search");
			if (searchlink != null)
				searchlink.style.visibility = val ? "hidden" : "inherit";
			var alllink = doc.getElementById(sel.name+"_popup_all");
			if (alllink != null)
				alllink.style.visibility = val ? "hidden" : "inherit";
		}
		var newlink = doc.getElementById(sel.name+"_popup_new");
		if (newlink != null)
			newlink.style.visibility = val ? "hidden" : "inherit";
		var linklink = doc.getElementById(sel.name+"_popup_link");
		if (linklink != null)
			linklink.style.visibility = val ? "hidden" : "inherit";
	}
	
}

var setLabelLegacy = setLabel;
setLabel = function(spanId, label)
{
    
    setLabelLegacy(spanId, label);
    var spanLabel = document.getElementById( spanId + "_lbl_uir_label" );
    if (spanLabel)
    {
        var elementClass = spanLabel.className;
        var classNameEmpty = "uir-label-empty";
        if (label.length > 0)
        {
            elementClass = elementClass.replace(classNameEmpty, "");
        }
        else
        {
            if (elementClass.indexOf(classNameEmpty) == -1)
            {
                elementClass += " " + classNameEmpty;
            }
        }
        spanLabel.className = elementClass;
    }
    
}



// Hide the div element
function NLHideDiv(divName)
{
	var divEle = document.getElementById(divName);
	divEle.style.display = "none";
}

function NLCreateCookie(name,value,days)
{
    var expires = "";
    if (days)
    {
        var date = new Date();
        date.setTime(date.getTime()+(days*24*60*60*1000));
        expires = "; expires="+date.toGMTString();
    }

    document.cookie = name+"="+value+expires+"; path=/";
}

function escapeJSChars (content)
{
    var returnStr = '';
    for (var i = 0; i < content.length; i++)
    {
        var c = content.substr(i, 1);
        if (c == "\'" || c== "\"" || c== "\\")
            returnStr += "\\";

        returnStr += c;
    }
    return returnStr;
}

function expandOrCollapseRows(machine, rownum, shouldCollapse)
{
    var EXPAND_ICON_URL = '/images/forms/plus.svg';
    var COLLAPSE_ICON_URL = '/images/forms/minus.svg';

    var expandOrCollapseIcon = document.getElementById(machine + 'row' + rownum + 'collapse');
    if (!expandOrCollapseIcon)
        return;

    if (typeof shouldCollapse == 'undefined')
        shouldCollapse = (expandOrCollapseIcon.src.indexOf(COLLAPSE_ICON_URL) != -1);

    for (var i = rownum + 1; !document.getElementById(machine + 'row' + i + 'collapse'); i++)
    {
        var currentRow = document.getElementById(machine + 'row' + i);
        if (!currentRow)
            break;

        currentRow.style.display = shouldCollapse ? 'none' : '';
    }

    expandOrCollapseIcon.src = shouldCollapse ? EXPAND_ICON_URL : COLLAPSE_ICON_URL;
}

function expandOrCollapseAllRows(machine, shouldCollapse)
{
    for (var i = 0; document.getElementById(machine + 'row' + i); i++)
        expandOrCollapseRows(machine, i, shouldCollapse);
}

function checkIsNotNegativeTime(field)
{
    var valid = true;
    if (field.value != null && field.value.match(/^\s*-/)) {
        alert('Invalid: Please enter a number greater than or equal to 0.');
        valid = false;
    }

    NS.form.setValid(valid);
    return valid;
}

function globalFunctionOrDummy(name, defaultResult) {
    return (name in window) ? window[name] : function () { return defaultResult; };
}

function validateRescheduleDate(dateString, input) {
    if (validate_date(dateString, false).validflag === false)
    {
        alert("Invalid reschedule date");
        window.setTimeout(function () {
            input.select();
            input.focus();
            input.scrollIntoView();
        }, 0);
    }
}
