Function Em(cString)
	If (IsNull(cString)) Then
		Em = True
	Else
		Em = (Len(Trim(cString)) = 0)
	End If
End Function

Function Min(nOne, nTwo)
	If nOne < nTwo Then
		Min = nOne
	Else
		Min = nTwo
	End If
End Function

Function Max(nOne, nTwo)
	If nOne > nTwo Then
		Max = nOne
	Else
		Max = nTwo
	End If
End Function

Function IsModal()
	on error resume next
	window.returnValue = ""
	If Err.Number <> 0 Then
		IsModal = False
	Else
		IsModal = True
	End If
	on error goto 0
End Function

Function QuestionBox(cTitle, cMessage, cChoice1, cChoice2, cChoice3)
	cURL = "/dialog/questionBox.asp?Title=" & cTitle & _
	                 "&Message=" & cMessage & _
					 "&Choice1=" & cChoice1 & _
					 "&Choice2=" & cChoice2 & _
					 "&Choice3=" & cChoice3
	nResult = window.showModalDialog(cURL,,"dialogHeight=200px;dialogWidth=400px;center=yes;help=no;resizable=no;status=no")
	QuestionBox = nResult
End Function

Sub SetSelect(oSelect, cValue)
	For nI = 0 To (oSelect.length - 1)
		cOption = oSelect.item(nI).value
		If InStr(cOption, "|") > 0 Then
			cOption = Left(cOption, InStr(cOption, "|") - 1)
		End If
		If cOption = cValue Then
			oSelect.selectedIndex = nI
		End If
	Next
End Sub

Sub SetSelectText(oSelect, cText)
	For nI = 0 To (oSelect.length - 1)
		cOption = oSelect.item(nI).text
		If InStr(cOption, "|") > 0 Then
			cOption = Left(cOption, InStr(cOption, "|") - 1)
		End If
		If cOption = cText Then
			oSelect.selectedIndex = nI
		End If
	Next
End Sub

Function FormatMinToDur(nMin)
	nHours = Int(nMin / 60)
	cHours = Right("00" & nHours,2)
	nMinutes = nMin Mod 60
	cMinutes = Right("00" & nMinutes,2)
	FormatMinToDur = cHours & ":" & cMinutes
End Function

Function FormatDate(dDate)
	If Em(dDate) Or IsNull(dDate) Then
		FormatDate = ""
	ElseIf Year(dDate) <= 1900 Then
		FormatDate = ""
	Else
		FormatDate = Right("00" & DatePart("m", dDate),2) & "/" & _
		             Right("00" & DatePart("d", dDate),2) & "/" & _
		             DatePart("yyyy", dDate)
	End If
End Function

Function FormatDateShort(dDate)
	If Em(dDate) Or IsNull(dDate) Then
		FormatDateShort = ""
	ElseIf Year(dDate) <= 1900 Then
		FormatDateShort = ""
	Else
		FormatDateShort = Right("0" & DatePart("m", dDate),2) & "/" & _
		             	  Right("0" & DatePart("d", dDate),2) & "/" & _
		             	  Right(DatePart("yyyy", dDate),2)
	End If
End Function

Function FormatTime(dTime)
	If Em(dTime) Or IsNull(dTime) Then
		FormatTime = ""
	ElseIf Hour(dTime) = 0 And Minute(dTime) = 0 Then
		FormatTime = ""
	Else
		nHour = Hour(dTime)
		If nHour > 12 Then nHour = nHour - 12
		cHour = CStr(nHour)
		If nHour = 0 Then cHour = "12"
		cHours = Right("00" & cHour,2)
		nMinutes = Minute(dTime)
		cMinutes = Right("00" & nMinutes,2)
		FormatTime = cHours & ":" & cMinutes
	End If
End Function

Function FormatAmPm(dTime)
	If Em(dTime) Or IsNull(dTime) Then
		FormatAmPm = "AM"
	Else
		nHour = Hour(dTime)
		If nHour > 11 Then
			FormatAmPm = "PM"
		Else
			FormatAmPm = "AM"
		End If
	End If
End Function

Function Coalesce(cString1, cString2)
	If Not Em(cString1) Then
		Coalesce = cString1
	Else
		Coalesce = cString2
	End If
End Function

Function URLEncode(cString)
	cCodeChars = "%#_&=+ "
	cRet = ""
	For nI = 1 To Len(cString)
		cChar = Mid(cString, nI, 1)
		If InStr(1, cCodeChars, cChar) > 0 Then
			cChar = "%" & Hex(Asc(cChar))
		End If
		cRet = cRet & cChar
	Next
	URLEncode = cRet
End Function

Function PCase(cString)
	nPosition = 1

	Do While InStr(nPosition, cString, " ", 1) <> 0
		nSpace = InStr(nPosition, cString, " ", 1)
		strOutput = strOutput & UCase(Mid(cString, nPosition, 1))
		strOutput = strOutput & LCase(Mid(cString, nPosition + 1, nSpace - nPosition))
		nPosition = nSpace + 1
	Loop

	strOutput = strOutput & UCase(Mid(cString, nPosition, 1))
	strOutput = strOutput & LCase(Mid(cString, nPosition + 1))

	PCase = strOutput
End Function

Function DurationToMinutes(cDuration)
    If InStr(1, cDuration, ":") = 0 Then
        DurationToMinutes = 0
    Else
        aDuration = Split(cDuration, ":")
        nHours = CDbl("0" & aDuration(0))
        nMinutes = CDbl("0" & aDuration(1))
        DurationToMinutes = (nHours * 60) + nMinutes
    End If
End Function

Function lValidDate(oDate)
	cDateString = oDate.value
	Dim aDate

	lOkDate = True

	If Len(cDateString) = 0 Then
		lValidDate = True
	ElseIf Not IsNumeric(Replace(cDateString,"/","")) Then
		lValidDate = False
	Else
		aDate = Split(cDateString, "/")

		Select Case UBound(aDate)
			Case 0
				ReDim Preserve aDate(2)

				Select Case Len(aDate(0))
					Case 4
						aDate(2) = CStr(Year(Date))
						aDate(1) = Right(aDate(0), 2)
						aDate(0) = Left(aDate(0), 2)

						If aDate(2) < 1800 Or aDate(2) > 9999 Then
							lOkDate = False
						Else
							lOkDate = IsDate(aDate(0) & "/" & aDate(1) & "/" & aDate(2))
						End If
					Case 6
						If Len(Right(aDate(0), 2)) <> 0 Then
							nYear = CDbl(Right(aDate(0), 2))

							If (nYear >= 0 And nYear < 50) Then
								nYear = nYear + 2000
							ElseIf nYear < 100 Then
								nYear = nYear + 1900
							End If

							aDate(2) = CStr(nYear)
							aDate(1) = Mid(aDate(0), 3, 2)
							aDate(0) = Left(aDate(0), 2)

							If aDate(2) < 1800 Or aDate(2) > 9999 Then
								lOkDate = False
							Else
								lOkDate = IsDate(aDate(0) & "/" & aDate(1) & "/" & aDate(2))
							End If
						Else
							lOkDate = False
						End If
					Case 8
						aDate(2) = Right(aDate(0), 4)
						aDate(1) = Mid(aDate(0), 3, 2)
						aDate(0) = Left(aDate(0), 2)

						If aDate(2) < 1800 Or aDate(2) > 9999 Then
							lOkDate = False
						Else
							lOkDate = IsDate(aDate(0) & "/" & aDate(1) & "/" & aDate(2))
						End If
					Case Else
						lOkDate = False
				End Select
			Case 1
				ReDim Preserve aDate(2)

				aDate(2) = CStr(Year(Date))

				If aDate(2) < 1800 Or aDate(2) > 9999 Then
					lOkDate = False
				Else
					lOkDate = IsDate(aDate(0) & "/" & aDate(1) & "/" & aDate(2))
				End If
			Case 2
				ReDim Preserve aDate(2)

				If Len(aDate(2)) <> 0 Then
					nYear = CDbl(aDate(2))

					If (nYear >= 0 And nYear < 50) Then
						nYear = nYear + 2000
					ElseIf nYear < 100 Then
						nYear = nYear + 1900
					End If

					aDate(2) = CStr(nYear)

					If aDate(2) < 1800 Or aDate(2) > 9999 Then
						lOkDate = False
					Else
						lOkDate = IsDate(aDate(0) & "/" & aDate(1) & "/" & aDate(2))
					End If
				Else
					lOkDate = False
				End If
			Case Else
				lOkDate = False
		End Select

		If lOkDate Then
			oDate.value = Right("00" & aDate(0), 2) & "/" & Right("00" & aDate(1), 2) & "/" & aDate(2)
			lValidDate = True
		Else
			lValidDate = False
		End If
	End If
End Function

Function lValidNum(oField, nWidth, nDec, lLead, lNegative, lAllowBlank, lBlankZero)
	cNum = oField.value

	If (lNegative) And (Left(cNum,1) = "-") Then
		cNum = Mid(cNum,2)
	End If

	lOKNum = True

	nBeforeDecimal = 0
	nAfterDecimal = 0

	lBeforeDecimal = True

	For nI = 1 To Len(cNum)
		cChar = Mid(cNum,nI,1)

		If (cChar = ".") And (lBeforeDecimal) Then
			lBeforeDecimal = False
		ElseIf Not IsNumeric(cChar) Then
			lOKNum = False
			Exit For
		ElseIf lBeforeDecimal Then
			nBeforeDecimal = nBeforeDecimal + 1
		Else
			nAfterDecimal = nAfterDecimal + 1
		End If
	Next

	If nDec = 0 Then
		nDecNum = nDec
	Else
		' Potentially remove +1
		nDecNum = nDec + 1
	End If

	If (nBeforeDecimal > (nWidth - nDecNum)) Or (nAfterDecimal > nDec) Then
		lOKNum = False
	End If

	If lOKNum Then
		cRet = ""
		cPre = "0"
		cPost = ""

		cNum = oField.value

		If (nWidth = 10) And (nDec = 0) And (CDbl(Coalesce(cNum,"0")) > 2147483647) Then
			window.alert ("Invalid Format: Value must be less than 2,147,483,648")

			oField.focus()
			lValidNum = False
		Else
			nDecimalPlace = InStr(cNum,".")

			If nDecimalPlace = 0 Then
				cPre = cNum
			Else
				cPre = Mid(cNum,1, nDecimalPlace - 1)
				cPost = Mid(cNum, nDecimalPlace + 1)
			End If

			If lBlankZero Then
				If CDbl(Coalesce(cPre,"0")) = 0 And Left(cPre,1) <> "-" Then
					If lLead Then
						cRet = "0"
					Else
						cRet = ""
					End If
				Else
					cRet = cPre
				End If
			Else
				If cPre = "" Then
					If lLead Then
						cRet = "0"
					Else
						cRet = ""
					End If
				Else
					cRet = cPre
				End If
			End If

			If Len(cPost) > nDec Then
				cPost = Mid(cPost,nDec + 1)
			End If

			If Not (lAllowBlank And cRet = "" And cPost = "") Then
				For nI = Len(cPost) To (nDec - 1)
					cPost = cPost & "0"
				Next

				If nDec > 0 Then
					cRet = cRet & "." & cPost
				End If
			End If
			oField.value = cRet
			lValidNum = True
		End If
	Else
		lValidNum = False
	End If
End Function

Function lUserDefValidNum (oField)
	lFoundNumber = False

	cNum = oField.value

	For nI = 1 To Len(oField.value)
		cChar =  Mid(cNum, nI, 1)

		If IsNumeric(cChar) Then
			lFoundNumber = True
			Exit For
		End If
	Next

	If Not lFoundNumber Then
		oField.value = ""
		lUserDefValidNum = True
	Else
		'negative first
		If InStr(cNum,"-") > 1 Then
			lUserDefValidNum = False
		ElseIf ((InStr(cNum,"-")) <> (InStrRev(cNum,"-"))) Or _
			((InStr(cNum,".")) <> (InStrRev(cNum,"."))) Then
			lUserDefValidNum = False
		Else
			lUserDefValidNum = True
		End If
	End If
End Function

Function XMLEncode(strText)
	sTemp = strText
	If InStr(1, sTemp, "&", vbBinaryCompare) Then
		sTemp = Replace(sTemp, "&", "&amp;")
	End If
	If InStr(1, sTemp, "<", vbBinaryCompare) Then
		sTemp = Replace(sTemp, "<", "&lt;")
	End If
	If InStr(1, sTemp, ">", vbBinaryCompare) Then
		sTemp = Replace(sTemp, ">", "&gt;")
	End If
	If InStr(1, sTemp, "'", vbBinaryCompare) Then
		'&apos; works for XML but not HTML; &#39; works for both -dbb 2/20/08
		'sTemp = Replace(sTemp, "'", "&apos;")
		sTemp = Replace(sTemp, "'", "&#39;")
		'-
	End If
	If InStr(1, sTemp, """", vbBinaryCompare) Then
		sTemp = Replace(sTemp, """", "&quot;")
	End If
	XMLEncode = sTemp
End Function

Function FormToXML(ByRef oForm, cRoot)
	cRet = "<" & cRoot & ">"
	For nI = 0 To oForm.elements.length - 1
		Set oElement = oForm.elements(nI)
		If oElement.type = "checkbox" Or oElement.type = "radio" Then
			If oElement.checked Then
				cRet = cRet & "<" & oElement.name & ">" & XMLEncode(oElement.value) & "</" & oElement.name & ">"
			End If
		Else
			cRet = cRet & "<" & oElement.name & ">" & XMLEncode(oElement.value) & "</" & oElement.name & ">"
		End If
	Next
	cRet = cRet + "</" & cRoot & ">"
	FormToXML = cRet
End Function

Function lValidTime(oTime, oAmPm)
	cTimeString = oTime.value
	Dim aTime

	lOkTime = True

	If Len(cTimeString) = 0 Then
		lValidTime = True
	ElseIf Not IsNumeric(Replace(cTimeString,":","")) Then
		lValidTime = False
	Else
		aTime = Split(cTimeString, ":")

		Select Case UBound(aTime)
			Case 0
				ReDim Preserve aTime(2)

				Select Case Len(aTime(0))
					Case 4
						aTime(1) = Right(aTime(0), 2)
						aTime(0) = Left(aTime(0), 2)

						If CInt(aTime(0)) < 1 Or CInt(aTime(1)) > 59 Then
							lOkTime = False
						Else
							lOkTime = True
						End If

					Case 3
						aTime(1) = Right(aTime(0), 2)
						aTime(0) = Right("00" & Left(aTime(0), 1), 2)

						If CInt(aTime(0)) < 1 Or CInt(aTime(1)) > 59 Then
							lOkTime = False
						Else
							lOkTime = True
						End If

					Case Else
						lOkTime = False
				End Select

			Case 1
				If CInt(aTime(0)) < 1 Or CInt(aTime(0)) > 12 Or CInt(aTime(1)) > 59 Then
					lOkTime = False
				Else
					lOkTime = True
				End If

			Case Else
				lOkTime = False

		End Select

		If lOkTime Then
			oTime.value = Right("00" & aTime(0), 2) & ":" & Right("00" & aTime(1), 2)

			If CInt(aTime(0)) < 7 Or CInt(aTime(0)) > 11 Then
				'oAmPm(1).selected = True
			Else
				'oAmPm(0).selected = True
			End If

			lValidTime = True
		Else
			lValidTime = False
		End If
	End If
End Function

Function lValidDur(oTime)
	cTimeString = oTime.value
	Dim aTime

	lOkTime = True

	If Len(cTimeString) = 0 Then
		lValidDur = True
	ElseIf Not IsNumeric(Replace(cTimeString,":","")) Then
		lValidDur = False
	Else
		aTime = Split(cTimeString, ":")

		Select Case UBound(aTime)
			Case 0
				ReDim Preserve aTime(2)

				Select Case Len(aTime(0))
					Case 4
						aTime(1) = Right(aTime(0), 2)
						aTime(0) = Left(aTime(0), 2)

						If CInt(aTime(1)) > 59 Then
							aTime(0) = Right("00" & Trim(CStr(CInt(aTime(0))+1)), 2)
							aTime(1) = Right("00" & Trim(CStr(CInt(aTime(1))-60)), 2)
						End If

						lOkTime = True

					Case 3
						aTime(1) = Right(aTime(0), 2)
						aTime(0) = Right("00" & Left(aTime(0), 1), 2)

						If CInt(aTime(1)) > 59 Then
							aTime(0) = Right("00" & Trim(CStr(CInt(aTime(0))+1)), 2)
							aTime(1) = Right("00" & Trim(CStr(CInt(aTime(1))-60)), 2)
						End If

						lOkTime = True

					Case 2
						aTime(1) = Trim(aTime(0))
						aTime(0) = "00"

						If CInt(aTime(1)) > 59 Then
							aTime(0) = Right("00" & Trim(CStr(CInt(aTime(0))+1)), 2)
							aTime(1) = Right("00" & Trim(CStr(CInt(aTime(1))-60)), 2)
						End If

						lOkTime = True

					Case Else
						lOkTime = False

				End Select

			Case 1
				If CInt(aTime(1)) > 59 Then
					aTime(0) = Right("00" & Trim(CStr(CInt(aTime(0))+1)), 2)
					aTime(1) = Right("00" & Trim(CStr(CInt(aTime(1))-60)), 2)
				End If

				lOkTime = True

			Case Else
				lOkTime = False

		End Select

		If lOkTime Then
			oTime.value = Right("00" & aTime(0), 2) & ":" & Right("00" & aTime(1), 2)

			lValidDur = True
		Else
			lValidDur = False
		End If
	End If
End Function

Function TaxCodeValidate(cTaxCode, cCompanyID, cDatabase)
	If Not Em(cTaxCode) Then
		Set oXMLHTTP = CreateObject("Microsoft.XMLHTTP")
		oXMLHTTP.open "GET", "/xml/taxCodeValidate.asp?CompanyID=" & cCompanyID & "&Database=" & cDatabase & "&TaxCode=" & cTaxCode, False
		oXMLHTTP.send
		cTaxCodeID = CStr(oXMLHTTP.responseText)
		If cTaxCodeID = "-1" Then
			alert("Invalid Tax Code")
			document.all("TaxCodeID").value = ""
			document.all("TaxCode").value = ""
			document.all("TaxCode").focus
		Else
			document.all("TaxCodeID").value = cTaxCodeID
		End If
	End If
End Function

Function lUserDefValidPick(oCodeField, oIDField, nLine, nBranchID, lUserDefByBranch)
	If Not Em(oCodeField.value) And Browse.style.visibility <> "visible" Then
		If lUserDefByBranch Then
			Set oNode = XMLValidate("/lookups/userdefchoicebranches" & nBranchID & "/fieldnum" & nLine & "/userdefchoice", "code", Trim(oCodeField.value))
			If oNode Is Nothing Then
				Call XMLOnBlur(oCodeField, oIDField, "/lookups/userdefchoicebranches" & nBranchID & "/fieldnum" & nLine & "/userdefchoice")
				lUserDefValidPick = False
				Exit Function
			End If
		Else
			Set oNode = XMLValidate("/lookups/userdefchoices" & nLine & "/userdefchoice" & nLine, "code", Trim(oCodeField.value))
			If oNode Is Nothing Then
				Call XMLOnBlur(oCodeField, oIDField, "/lookups/userdefchoices" & nLine & "/userdefchoice" & nLine)
				lUserDefValidPick = False
				Exit Function
			End If
		End If
	End If

	lUserDefValidPick = True
End Function

Function WordWrap(cString, nLineLen)
	Dim aWrap(20)

	cString = Replace(cString, Chr(10), "")
	nRow = 0
	nStart = 1
	nLastSpace = 1
	nPos = 1

	Do While nPos <= Len(cString) And nRow < UBound(aWrap)
		cChar = Mid(cString,nPos,1)
		If cChar = " " Or cChar = Chr(13) Then nLastSpace = nPos
		If (nPos - nStart + 1) > nLineLen Or cChar = Chr(13) Then
			'-- added to wrap text that has no spaces  -jek 04/21/2003
			' --- modified to correct extra lines when chr(13) exists on 1st character. -fgd 07/01/03
			'If nLastSpace = nStart Then
			If nLastSpace = nStart And cChar <> Chr(13) Then
			' --- endfgd
				nLastSpace = nStart + nLineLen
				cRow = Mid(cString, nStart, nLastSpace - nStart)
				nStart = nLastSpace
			Else
				cRow = Mid(cString, nStart, nLastSpace - nStart)
				nStart = nLastSpace + 1
			End If
			'--
			nLastSpace = nStart
			nPos = nStart
			aWrap(nRow) = Trim(cRow)
			nRow = nRow + 1
		Else
			nPos = nPos + 1
		End If
	Loop
	aWrap(nRow) = Trim(Mid(cString, nStart))

	WordWrap = aWrap
End Function

Function WordWrapLong(cString, nLineLen)
	Dim aWrap(80)

	cString = Replace(cString, Chr(10), "")
	nRow = 0
	nStart = 1
	nLastSpace = 1
	nPos = 1

	Do While nPos <= Len(cString) And nRow < UBound(aWrap)
		cChar = Mid(cString,nPos,1)
		If cChar = " " Or cChar = Chr(13) Then nLastSpace = nPos
		If (nPos - nStart + 1) > nLineLen Or cChar = Chr(13) Then
			'-- added to wrap text that has no spaces  -jek 04/21/2003
			' --- modified to correct extra lines when chr(13) exists on 1st character. -fgd 07/01/03
			'If nLastSpace = nStart Then
			If nLastSpace = nStart And cChar <> Chr(13) Then
			' --- endfgd
				nLastSpace = nStart + nLineLen
				cRow = Mid(cString, nStart, nLastSpace - nStart)
				nStart = nLastSpace
			Else
				cRow = Mid(cString, nStart, nLastSpace - nStart)
				nStart = nLastSpace + 1
			End If
			'--
			nLastSpace = nStart
			nPos = nStart
			aWrap(nRow) = Trim(cRow)
			nRow = nRow + 1
		Else
			nPos = nPos + 1
		End If
	Loop
	aWrap(nRow) = Trim(Mid(cString, nStart))

	WordWrapLong = aWrap
End Function

Function FirstOfMonth(dDate)
	If Not IsDate(dDate) Then
		FirstOfMonth = ""
	Else
		FirstOfMonth = Right("00" & DatePart("m", dDate),2) & "/01/" & DatePart("yyyy", dDate)
	End If
End Function

Function GetPrintTarget()
	If Mid(navigator.userAgent, InStr(navigator.userAgent, "MSIE") + 5, 1) = "6" Or cPF_FormType = "DotMatrix" Or cPF_FormType = "7Inch" Then
		cPF_FormType = ""
		GetPrintTarget = "PrintFrame"
	Else
		cPF_FormType = ""
		GetPrintTarget = "_blank"
	End If
End Function

Function ConvertVersionToNum(cStrVersion)
	aSplitVer = Split(cStrVersion, ".")
	nMult = 1
	If Len(cStrVersion) > 0 Then
		For nI = (UBound(aSplitVer)) To 0 STEP -1
			ConvertVersionToNum = ConvertVersionToNum + (aSplitVer(nI) * nMult)
			If Len(aSplitVer(nI)) = 2 Then
				nMult = nMult * 100
			Else
				nMult = nMult * 10
			End If
		Next
	Else
		ConvertVersionToNum = 0
	End If
End Function

Function lValidPhone(oPhone)
	If cCustomFlag = "TERMAPEST" Then
		lValidPhone = True
		Exit Function
	End If

	cValue = oPhone.value

	If Em(cValue) Then
		lValidPhone = True
		Exit Function
	End If

	cDigits = ""
	For nI = 1 To Len(cValue)
		If Mid(cValue, nI, 1) <> "-" And Mid(cValue, nI, 1) <> " " Then
			cDigits = cDigits & Mid(cValue, nI, 1)
		End If
	Next

	If Len(cDigits) <> 10 Then
		lValidPhone = False
	Else
		oPhone.value = Left(cDigits, 3) & "-" & Mid(cDigits, 4, 3) & "-" & Right(cDigits, 4)
		lValidPhone = True
	End If
End Function

Function lValidLookup(oCodeField, oIDField, cDataPath)
	If Em(oCodeField.value) Then
		oIDField.value = ""
	ElseIf Browse.style.visibility <> "visible" Then
		Set oNode = XMLValidate(cDataPath, "code", Trim(oCodeField.value))
		If oNode Is Nothing Then
			lValidLookup = False
			Exit Function
		Else
			Call XMLOnBlur(oCodeField, oIDField, cDataPath)
		End If
	End If

	lValidLookup = True
End Function

Function EscapeForHTML(cData)
	If Not Em(cData) Then
		Set oBadChars = CreateObject("Scripting.Dictionary")
		For iLoop = 1 To Len(cData)
			nChar = Mid(cData, iLoop, 1)
			nAscii = Asc(nChar)
			If (nAscii >= 127 Or nAscii = 39 Or nAscii= 96 Or nAscii < 32) And (Not oBadChars.Exists(nAscii)) Then
				oBadChars.Add nAscii, nChar
			End If
		Next
 		For Each oBadChar in oBadChars
			If CInt(oBadChar) < 32 Then
		 		cData = Replace(cData, oBadChars(oBadChar), "")
			Else
		 		cData = Replace(cData, oBadChars(oBadChar), "&#" & cStr(oBadChar) & ";")
			End If
 		Next
 		EscapeForHTML = cData
	Else
		EscapeForHTML = ""
 	End If
End Function

Function StripHTML(myStr)
	myStr = Replace(myStr,"&nbsp;"," ")
	StrLen = Len(myStr)
	If IsNull(StrLen) Or IsNull(myStr) Then
		StripHTML = ""
		Exit Function
	End If

	myNewStr = ""
	For nStartChar = 1 to StrLen
		myChar = Mid(myStr, nStartChar, 1)
		If myChar = "<" Then
			nSkipChars = 0
			Do While myChar <> ">" And nStartChar + nSkipChars <= StrLen
				myNewStr = myNewStr & ""
				myChar = Mid(myStr, nStartChar + nSkipChars, 1)
				nSkipChars = nSkipChars + 1
			Loop
			nStartChar = nStartChar + nSkipChars - 1
		Else
			myNewStr = myNewStr + myChar
		End If
	Next
	StripHTML = myNewStr
End Function

Sub ShowMeasurements(nLine)
	If document.all("PriceByMeasurementQuantity" & nLine).value <> "" Then
		Set oMeasurementType = Lookups.XMLDocument.selectSingleNode("/lookups/measurementtypes/measurementtype[@id='" & document.all("PriceByMeasurementTypeID" & nLine).value & "']")
		If Not oMeasurementType Is Nothing Then
				cMeasurementType = oMeasurementType.attributes.getNamedItem("code").text
		End If

		cPriceAdjustor = document.all("PriceByMeasurementPriceAdjustor" & nLine).value
		cDiscountDollars = document.all("PriceByMeasurementCustomerDiscountDollars" & nLine).value
		cDiscountPercent = document.all("PriceByMeasurementCustomerDiscountPercent" & nLine).value
		cDiscountExpirationDate = document.all("PriceByMeasurementDiscountExpirationDate" & nLine).value

		If Em(cDiscountExpirationDate) Then
			cDiscountExpirationDate = "(None)"
		Else
			cDiscountExpirationDate = FormatDate(CDate(cDiscountExpirationDate))
		End If
		If Em(cPriceAdjustor) Then
			cPriceAdjustor = "0"
		End If

		cPriceAdjustor = FormatNumber(cPriceAdjustor,2,,False,False) & "%"

		cDiscount = "0"
		cDiscountType = "$"

		If Em(cDiscountDollars) Or cDiscountDollars = "0" Then
				If Not Em(cDiscountPercent) And cDiscountPercent <> "0" Then
					cDiscountType = "%"
					cDiscount = cDiscountPercent
				End If
		Else
			cDiscount = cDiscountDollars
		End If

		If cDiscountType = "%" Then
			cDiscount = FormatNumber(cDiscount,2,,False,False) & "%"
		Else
			cDiscount = FormatCurrency(cDiscount)
		End If

		cMsg = cMsg & "<table cellpadding='0' cellspacing='0' bgcolor='#181818' width='225'>"
		cMsg = cMsg & "<tr><td class='hoverPopupStyled_Header' colspan='2' align='center'>Measurement Detail</td></tr>"
		cMsg = cMsg & "<tr><td class='hoverPopupStyled_Font'>Measurement:</td><td class='hoverPopupStyled_Font'>" & FormatNumber(document.all("PriceByMeasurementQuantity" & nLine).value,2) & " " & cMeasurementType & "</td></tr>"
		cMsg = cMsg & "<tr><td class='hoverPopupStyled_Font'>Measurement Type:</td><td class='hoverPopupStyled_Font'>" & document.all("PriceByMeasurementLocation" & nLine).value & "</td></tr>"
		cMsg = cMsg & "<tr><td class='hoverPopupStyled_Font'>Base Price:</td><td class='hoverPopupStyled_Font'>" & FormatCurrency(document.all("PriceByMeasurementBasePrice" & nLine).value) & "</td></tr>"
		cMsg = cMsg & "<tr><td class='hoverPopupStyled_Font'>Unit Price:</td><td class='hoverPopupStyled_Font'>$" & FormatNumber(document.all("PriceByMeasurementUnitPrice" & nLine).value,4) & "</td></tr>"
		cMsg = cMsg & "<tr><td class='hoverPopupStyled_Font'>Min Price:</td><td class='hoverPopupStyled_Font'>" & FormatCurrency(document.all("PriceByMeasurementMinPrice" & nLine).value) & "</td></tr>"
		cMsg = cMsg & "<tr><td class='hoverPopupStyled_Font'>Price Adjustor:</td><td class='hoverPopupStyled_Font'>" & cPriceAdjustor & "</td></tr>"
		cMsg = cMsg & "<tr><td class='hoverPopupStyled_Font'>Discount:</td><td class='hoverPopupStyled_Font'>" & cDiscount & "</td></tr>"
		cMsg = cMsg & "<tr><td class='hoverPopupStyled_Font'>Exp Date:</td><td class='hoverPopupStyled_Font'>" & cDiscountExpirationDate & "</td></tr>"
		cMsg = cMsg & "</table>"

		Call ShowPopupStyled(cMsg)
	End If
End Sub

Sub ShowPopupStyled(cMsg)
	If Not Em(cMsg) Then
		x = window.event.Clientx + document.body.scrollLeft
		y = window.event.Clienty + document.body.scrollTop

		cPopHTML = "<div class='hoverPopupStyled'>" & cMsg & "</div>"
		Popup.innerHTML = cPopHTML

		cClientWidth = Popup.ClientWidth

		cBodyWidth = document.body.ClientWidth
		cBodyScroll = document.body.ScrollLeft

		If x + cClientWidth >= cBodyWidth + cBodyScroll Then
			If x - cClientWidth - 10 >= 0 Then
				x = x - cClientWidth - 10
				Popup.style.left = x
			Else
				Popup.style.left = x + 10
			End If
		Else
			Popup.style.left = x + 10
		End If

		cClientHeight = Popup.ClientHeight

		cBodyHeight = document.body.ClientHeight
		cBodyScroll = document.body.Scrolltop

		If y + cClientHeight >= cBodyHeight + cBodyScroll Then
			If y - cClientHeight - 10 >= 0 Then
				y = y - cClientHeight - 10
				Popup.style.top = y
			Else
				Popup.style.top = y + 10
			End If
		Else
			Popup.style.top = y + 10
		End If

		Popup.style.visibility = "visible"
	End If
End Sub

Sub StopPreserveSession()
	'reloading the preserveSession.inc iframe while form is being submitted can cause IE to lock up
	If Not document.frames("PreserveSessionFrame") Is Nothing Then
		document.frames("PreserveSessionFrame").location = "/blank.asp"
	End If
End Sub

Sub UpdateLog(cActivityCode, cActivityString, cBranchID)
	Set oXMLHTTP = CreateObject("Microsoft.XMLHTTP")
	oXMLHTTP.open "POST", "/xml/UpdateLog.asp?ActivityCode=" & cActivityCode & "&ActivityString=" & cActivityString & "&BranchID=" & cBranchID, False
	oXMLHTTP.send
End Sub

Function VClass(cClass, cParams)
	If Not Em(cParams) Then
		aParams = Split(cParams, "|")
	End If

	cClass = LCase(cClass)

	Select Case cClass
		Case "date"
			VClass = "onblur='javascript: vDateBlur(this)' onkeypress='javascript: vDateKey(this)' onkeydown='javascript: vDateKeyDown(this)' oncontextmenu='javascript: return vDateContextMenu(this)' class='input-date'"
		Case "ucase"
			VClass = "onkeypress = 'javascript: vUCaseKey(this)'"
		Case "icap"
			VClass = "onblur='javascript: vICapBlur(this)' onkeypress='javascript: vICapKey(this)'"
		Case "commrate"
			VClass = "onblur='javascript: vCommrateBlur(this, " & aParams(0) & "," & aParams(1) & ")' onkeypress='javascript: vCommrateKey(this)'"
		Case "dur"
			VClass = "onblur='javascript: vDurBlur(this)' onkeypress='javascript: vDurKey(this)'"
		Case "ipaddress"
			VClass = "onblur='javascript: vIPAddressBlur(this)' onkeypress='javascript: vIPAddressKey(this)'"
		Case "num"
			' aParams(0) - Precision
			' aParams(1) - Decimal
			' aParams(2) - Leading Zero
			' aParams(3) - Allow Negative Numbers
			' aParams(4) - Allow Blank
			' aParams(5) - Blank Zero

			VClass = "onblur='javascript: vNumBlur(this, " & aParams(0) & "," & aParams(1) & "," & aParams(2) & "," & aParams(3) & "," & aParams(4) & "," & aParams(5) & ")' onkeypress='javascript: vNumKey(this,"& aParams(3) & ")'"
		Case "smsnum"
			VClass = "onblur='javascript: vSMSNumBlur(this, " & aParams(0) & "," & aParams(1) & "," & aParams(2) & "," & aParams(3) & "," & aParams(4) & "," & aParams(5) & ")' onkeypress='javascript: vNumKey(this,"& aParams(3) & ")'"
		Case "percentage"
			VClass = "onblur='javascript: vPercentageBlur(this, " & aParams(0) & ")' onkeypress='javascript: vPercentageKey(this)'"
		Case "phone"
			VClass = "onblur='javascript: vPhoneBlur(this, """ & cParams & """)' onkeypress='javascript: vPhoneKey(this)' onfocus='javascript: vPhoneFocus(this, """ & cParams & """)'"
		Case "time"
			VClass = "onblur='javascript: vTimeBlur(this, """ & aParams(0) & """)' onkeypress='javascript: vTimeKey(this, """ & aParams(0) & """)' onkeydown='javascript: vTimeKeyDown(this, """ & aParams(0) & """)'"
		Case "timesheet"
			VClass = "onblur='javascript: vTimesheetBlur(this, " & aParams(0) & "," & aParams(1) & ")' onkeypress='javascript: vTimesheetKey(this)'"
		Case "year"
			VClass = "onblur='javascript: vYearBlur(this)' onkeypress='javascript: vYearKey(this)'"
		Case "limited"
			VClass = "onblur='javascript: vTextareaBlur(this, " & aParams(0) & "," & aParams(1) & ")' onkeypress='javascript: vTextareaKey(this, " & aParams(0) &")' onkeydown='javascript: vTextareaKeyDown(this, " & aParams(0) & "," & aParams(1) & ")'"
		Case "ordernumlist"
			VClass = "onkeypress='javascript: vOrderNumListKey(this)'"
		Case "taxid"
			VClass = "onblur='javascript: vTaxIDBlur(this)' onkeypress='javascript: vTaxIDKey(this)'"
		Case "1099"
			VClass = "onkeypress='javascript: v1099TypeKey(this)'"
		Case "yesno"
			VClass = "onkeypress='javascript: vYesNoKey(this)'"
		Case "sharepercentage"
			VClass = "onblur='javascript: vSharePercentageBlur(this, " & aParams(0) & ")' onkeypress='javascript: vPercentageKey(this)'"
		Case "carrierroute"
			VClass = "onblur='javascript: vCarrierRouteBlur(this)' onkeypress='javascript: vCarrierRouteKey(this)'"
		Case "dayofyear"
			VClass = "onblur='javascript: vDayOfYearBlur(this)' onkeypress='javascript: vDayOfYearKey(this)'"
		Case "lookup"
			' aParams(0) - OnKeyDown function call
			' aParams(1) - Use Caps

			If Right(aParams(0),1) <> ")" Then
				aParams(0) = aParams(0) & "()"
			End If

			If aParams(1) = "1" Then
				cKeyPress = "onkeypress='javascript: vUCaseKey(this)' "
			ElseIf aParams(1) = "2" Then
				cKeyPress = "onkeypress='javascript: vICapKey(this)' "
			Else
				cKeyPress = ""
			End If

			If Em(aParams(0)) Then
				VClass = cKeyPress & "class='input-lookup'"
			Else
				VClass = cKeyPress & "class='input-lookup' oncontextmenu='javascript: window.event.keyCode = 34; " & aParams(0) & "; return false;'"
			End If
		Case "autocomplete"
			'aParams(0) = Descriptive form field
			'aParams(1) = ID form field
			'aParams(2) = Page that retrieves data
			nPerPage = 20
			VClass = "onkeyup='loadAutoComplete(this, event, " & nPerPage & ", """ & aParams(0) & """, """ & aParams(1) & """, """ & aParams(2) & """);' onblur='selectAutoComplete(this, this, document.getElementById(""" & aParams(1) & """));'"
	End Select
End Function

' Dynamically appends branch specific XML for dropdowns to the Lookups data island.
' Currently supports cCache = "ServiceBranch" or "TechnicianBranch" -cdk 12/12/07
Function LoadBranchXML(cCache, cBranchID)
	If Not Em(cCache) And Not Em(cBranchID) Then
		Set oXMLHTTP = CreateObject("Microsoft.XMLHTTP")
		oXMLHTTP.open "GET", "/xml/get" & cCache & "XML.asp?BranchID=" & cBranchID, False
		oXMLHTTP.send
		If oXMLHTTP.statusText = "OK" Then
			Set myXML = oXMLHTTP.responseXML.documentElement
			For nI = 0 To myXML.childNodes.length - 1
				If Lookups.selectSingleNode("lookups/" & myXML.childNodes(0).nodeName) Is Nothing Then
					Lookups.selectSingleNode("lookups").appendChild(myXML.childNodes(0))
				End If
			Next
		End If
	End If
End Function

Sub DescriptionBuilder(nLine, lEdit)
	If Not lEdit Then
		Exit Sub
	End If

	cDescription = URLEncode(document.all("HiddenDetailedDescription" & nLine).value)

	cResult = window.showModalDialog("/dialog/DescriptionBuilder.asp?Description=" & cDescription,,"dialogHeight:200px;dialogWidth:650px")

	If Left(cResult, 2) = "OK" Then
		cDescription = Right(cResult, Len(cResult) - 3)

		If Not document.all("Description" & nLine) Is Nothing Then
			document.all("Description" & nLine).value = cDescription
		End If

		If Not document.all("HiddenDetailedDescription" & nLine) Is Nothing Then
			document.all("HiddenDetailedDescription" & nLine).value = cDescription
		End If

		If Not document.all("DetailedDescription" & nLine) Is Nothing Then
			document.all("DetailedDescription" & nLine).value = cDescription
		End If
	End If
End Sub

Sub CancelKeyPress()
	'Cancels a window.event.keypress event
	window.event.cancelbubble = True
	window.event.returnvalue = False
End Sub

Sub AlternateTableRowColor(cTableID, cColor1, cColor2)
	Set oTable = document.all(cTableID)
	If Not (oTable Is Nothing) Then
		If Left(cColor1, 1) <> "#" Then cColor1 = "#" & cColor1
		If Left(cColor2, 1) <> "#" Then cColor2 = "#" & cColor2

		For nI = 0 To oTable.Rows.Length - 1
			If nI Mod 2 = 0 Then
				oTable.Rows(nI).style.backgroundcolor = cColor1
			Else
				oTable.Rows(nI).style.backgroundcolor = cColor2
			End If
		Next
	End If
End Sub

Function CheckAccessRight(cFeatureCode, cOperationCode, cBranchID, cActivityString)
	xmlParams = "<params>"
	xmlParams = xmlParams & "<featurecode>" & cFeatureCode & "</featurecode>"
	xmlParams = xmlParams & "<operationcode>" & cOperationCode & "</operationcode>"
	xmlParams = xmlParams & "<branchid>" & cBranchID & "</branchid>"
	xmlParams = xmlParams & "<accessfunction>CheckAccessRight</accessfunction>"
	xmlParams = xmlParams & "</params>"

	Set oResponse = GetXMLHTTP(xmlParams, "/xml/checkAccess.asp", False)
	lAccess = (oResponse.selectSingleNode("status").text = "OK")

	If Not Em(cActivityString) And lAccess Then
		Call UpdateLog(cFeatureCode, cActivityString, cBranchID)
	End If
	Set oResponse = Nothing
	CheckAccessRight = lAccess
End Function

Function GetXMLHTTP(cXMLToPost, cPostingURL, lShowAlerts)
	Set oXMLHTTP = CreateObject("Microsoft.XMLHTTP")
	oXMLHTTP.open "POST", cPostingURL, False
	oXMLHTTP.send cXMLToPost
	If oXMLHTTP.statusText = "OK" Then
		Set oResponse = oXMLHTTP.responseXML.documentElement
		If oResponse.selectSingleNode("status").text <> "OK" Then
			If lShowAlerts Then
				If Not oResponse.selectSingleNode("msg") Is Nothing Then
					MsgBox("System Error: " & oResponse.selectSingleNode("msg").text)
				Else
					MsgBox("System Error: Unknown Origin")
				End If
			End If
		End If
	Else
		If lShowAlerts Then
			MsgBox("Server Error: " & oXMLHTTP.statusText)
		End If
		Set oTemp = CreateObject("Microsoft.XMLDOM")
		oTemp.async = False
		oTemp.LoadXML("<?xml version='1.0'?><response><status></status><msg>" & oXMLHTTP.statusText & "</msg></response>")
		Set oResponse = oTemp.documentElement
	End If
	Set oXMLHTTP = Nothing
	Set GetXMLHTTP = oResponse
End Function

Function GetChemicalBaseUOM(cChemicalID)
	xmlData = "<params>"
	xmlData = xmlData & "<chemicalid>" & cChemicalID & "</chemicalid>"
	xmlData = xmlData & "</params>"

	Set oResponse = GetXMLHTTP(xmlData, "/inventory/xml/getChemicalBaseUOM.asp", True)
	If oResponse.selectSingleNode("status").text = "OK" Then
		GetChemicalBaseUOM = oResponse.selectSingleNode("baseuomid").text
	Else
		GetChemicalBaseUOM = ""
	End If
End Function

Sub Sleep(nSeconds)
	nSeconds = Trim(nSeconds)
	If Not Em(nSeconds) Then
		If IsNumeric(nSeconds) Then
			xmlData = "<params>"
			xmlData = xmlData & "<secondstosleep>" & nSeconds & "</secondstosleep>"
			xmlData = xmlData & "</params>"
			Set oResponse = GetXMLHTTP(xmlData, "/xml/sleep.asp", True)
		End If
	End If
End Sub

Sub StartPageRedirect(cStartPage)
	Select Case cStartPage
		Case "L":  window.location = "/location/"
		Case "V":  window.location = "/visual.asp"
		Case Else: window.location = "/my.asp"
	End Select
End Sub

Sub GetCompanyEmail(cFieldName)
	Set oField = document.all(cFieldName)
	If Not (oField Is Nothing) Then
		If (Not oField.readonly) And (Not oField.disabled) Then
			cEmails = window.showModalDialog("/dialog/ChooseEmployeeEmail.asp?EmailList=" & oField.value,,"dialogHeight:450px;dialogWidth:600px")
			If Not Em(cEmails) Then
				If cEmails = "None" Then
					cEmails = ""
				End If
				oField.value = cEmails
			End If
		End If
	End If
End Sub

Function CheckPeriod(cBranchID, dCheckDate, cMsg)
	If Not Em(dCheckDate) Then
		xmlData = "<params><branchid>" & cBranchID & "</branchid></params>"

		Set oXMLHTTP = CreateObject("Microsoft.XMLHTTP")
		oXMLHTTP.open "POST", "/xml/getPeriod.asp", False
		oXMLHTTP.send xmlData

		If oXMLHTTP.statusText = "OK" Then
			Set oResponse = oXMLHTTP.responseXML.documentElement
			dLastPeriodDate = CDate(Coalesce(oResponse.selectSingleNode("cutoffdate").text, "1/1/1901"))
			dCheckDate = CDate(dCheckDate)

			If dCheckDate <= dLastPeriodDate Then
				alert(cMsg & vbcrlf & vbcrlf & "Period Cutoff Date: " & FormatDateShort(dLastPeriodDate))
				CheckPeriod = "Exit"
			End If
		Else
			alert("Error: CheckPeriod()")
			CheckPeriod = "Exit"
		End If
	End If
End Function

Function CheckPeriodBatch(cCheckType, cBatchID, cMsg)
	xmlData = "<params>"
	xmlData = xmlData & "<checktype>" & cCheckType & "</checktype>"
	xmlData = xmlData & "<batchid>" & cBatchID & "</batchid>"
	xmlData = xmlData & "</params>"

	Set oXMLHTTP = CreateObject("Microsoft.XMLHTTP")
	oXMLHTTP.open "POST", "/xml/ClosedPeriodBatchCheck.asp", False
	oXMLHTTP.send xmlData

	If oXMLHTTP.statusText = "OK" Then
		Set oResponse = oXMLHTTP.responseXML.documentElement
		cInvalidItem = oResponse.selectSingleNode("invaliditem").text

		If cInvalidItem = "1" Then
			alert(cMsg)
			CheckPeriodBatch = "Exit"
		End If
	Else
		alert("Error: CheckPeriodBatch()")
		CheckPeriodBatch = "Exit"
	End If
End Function