/*
HomerJax
Copyright 2009 by Jamal Mazrui
GNU Lesser General Public License (LGPL)
*/

/*
import Accessibility
import Microsoft.VisualBasic
import System
import System.ComponentModel
import System.Diagnostics
import System.Drawing
import System.IO
import System.Net
import System.Reflection
import System.Runtime.InteropServices
import System.Windows.Forms
import System.Xml
*/


// class HomerJax {
// Constants

var ioForReading = 1
var ioForWriting = 2
var ioForAppending = 8

var formatTristateUseDefault = -2 // Open as System default
var formatTristateTrue = -1 // Open as Unicode
var formatTriStateFalse = 0 // Open as ASCII

var vbBlack = 0x00 // Black
var vbRed = 0xFF // Red
var vbGreen = 0xFF00 // Green
var vbYellow = 0xFFFF // Yellow
var vbBlue = 0xFF0000 // Blue
var vbMagenta = 0xFF00FF// Magenta
var vbCyan = 0xFFFF00// Cyan
var vbWhite = 0xFFFFFF // White

var vbBinaryCompare = 0 // Perform a binary comparison
var vbTextCompare = 1 // Perform a textual comparison

var vbSunday = 1 // Sunday
var vbMonday = 2 // Monday
var vbTuesday = 3 // Tuesday
var vbWednesday = 4 // Wednesday
var vbThursday = 5 // Thursday
var vbFriday = 6 // Friday
var vbSaturday = 7 // Saturday
var vbUseSystemDayOfWeek = 0 // Use the day of the week specified in your system settings
var vbFirstJan = 11 // Use the week in which January = 1 // occurs (default)
var vbFirstFourDays = 2 // Use the first week that has at least four days in the new
var vbFirstFullWeek = 3 // Use the first full week of the year
var vbGeneralDate = 0 // Display a date and/or time. For real numbers, display a date and
var vbLongDate = 1 // Display a date using the long date format specified in your
var vbShortDate = 2 // Display a date using the short date format specified in your
var vbLongTime = 3 // Display a time using the long time format specified in your
var vbShortTime = 4 // Display a time using the short time format specified in your
var vbObjectError = -2147221504 // User-defined error numbers should be greater than this

var vbOKOnly = 0 // Display OK button only
var vbOKCancel = 1 // Display OK and Cancel buttons
var vbAbortRetryIgnore = 2 // Display Abort, Retry, and Ignore buttons
var vbYesNoCancel = 3 // Display Yes, No, and Cancel buttons
var vbYesNo = 4 // Display Yes and No buttons
var vbRetryCancel = 5 // Display Retry and Cancel buttons
var vbCritical = 16 // Display Critical Message icon
var vbQuestion = 32 // Display Warning Query icon
var vbExclamation = 48 // Display Warning Message icon
var vbInformation= 64 // Display Information Message icon
var vbDefaultButton1 = 0 // First button is the default
var vbDefaultButton2 = 256 // Second button is the default
var vbDefaultButton3 = 512 // Third button is the default
var vbDefaultButton4 = 768 // Fourth button is the default
var vbApplicationModal = 0 // Application modal. The user must respond to the message box
var vbSystemModal = 4096 // System modal
var vbOK = 1 // OK button was clicked
var vbCancel = 2 // Cancel button was clicked
var vbAbort = 3 // Abort button was clicked
var vbRetry = 4 // Retry button was clicked
var vbIgnore = 5 // Ignore button was clicked
var vbYes = 6 // Yes button was clicked
var vbNo = 7 // No button was clicked
var vbCr = '\r' // carriage return
var vbFormFeed = '\f' // form feed
var vbLf = '\n' // line feed
var vbNewLine = '\r\n' // platform-specific new line
var vbNullChar = 0x000 // null character
var vbNullString = '\0x0000'
var vbTab = '\t' // tab
var vbVerticalTab = '\v' // vertical tab
var vbUseDefault = -2 // Use default from computer's regional settings
var vbtrue = -1 // true
var vbfalse = 0 // false
var vbEmpty = 0 // Uninitialized (default)
var vbNull = 1 // Contains no valid data
var vbInteger = 2 // Integer subtype
var vbLong = 3 // Long subtype
var vbSingle = 4 // Single subtype
var vbDouble = 5 // Double subtype
var vbCurrency = 6 // Currency subtype
var vbDate = 7 // Date subtype
var vbString = 8 // String subtype
var vbObject = 9 // Object
var vbError = 10 // Error subtype
var vbBoolean = 11 // Boolean subtype
var vbVt = 12 // Vt (used only for arrays of Vts)
var vbDataObject = 13 // Data access object
var vbDecimal = 14 // Decimal subtype
var vbByte = 17 // Byte subtype
var vbArray = 8192 // Array

var vbUseSystem = 0 // Use National Language Support (NLS) API setting
var vbDefaultButton = 1 // = 0 // First button is default
var vbCrLf = '\r\n'
var xMaxPath = 260
var xSpace = ' '
var xMute = ''
var xComma = ','
var xCommaSpace = ', '
var xBar = '|'
var xQuote = '"'
var xApostrophe = "'"
var xSlash = '/'
var xBackslash = '\\'
var xEquals = '='
var xColon = ':'
var xSemicolon = ';'
var xLessThan = '<'
var xGreaterThan = '>'
var xLeftBrace = '{'
var xRightBrace = '}'
var xUTF = 8 // 'EFBBBF'
var xSectionBreak = vbCrLf + '----------' + vbCrLf + vbFormFeed + vbCrLf
var xEndOfDocument = vbCrLf + '----------' + vbCrLf + 'End of Document' + vbCrLf

var adVarWChar = 202

var adAffectCurrent = 1 //

var adSaveCreateNotExist = 1 // Default, create if absent
var adSaveCreateOverWrite = 2 // create even if present
var adTypeBinary = 1 // Binary
var adTypeText = 2 // default, text

var adAffectGroup = 2 //
var adAffectAll = 3 //
var adFilterNone = 0 //
var adFilterPendingRecords = 1 //
var adFilterAffectedRecords = 2 //
var adFilterFetchedRecords = 3 //
var adFilterConflictingRecords = 5 //
var adClipString = 2 //
var adUseServer = 2 //
var adUseClient = 3 //
var adOpenForwardOnly = 0 //
var adOpenKeySet = 1 //
var adOpenDynamic = 2 //
var adOpenStatic = 3 //
var adLockReadOnly = 1 //
var adLockOptimistic = 3 //
var adBatchOptimistic = 4 //
var adCmdText = 1 //
var adCmdTableDirect = 512 //
var adExecuteNoRecords = 128 //
var adSearchBackward = -1 //
var adSearchForward	= 1 //
var adBookmarkCurrent = 0 //
var adBookmarkFirst = 1 //
var adBookmarkLast = 2 //
var adPosBOF = -2 //
var adPosEOF = -3 //
var adPosUnknown = -1 //

// Functions

function DialogConfirm(sTitle, sMessage, sDefault) {
// Get choice from a standard Yes, No, or Cancel message box

var sDefault = sDefault.toUpperCase()
var sReturn = xMute
var iFlags = vbYesNoCancel
iFlags = iFlags | vbQuestion	// 32 query icon
iFlags = iFlags | vbSystemModal // 4096	System modal
if (sTitle == xMute) var sTitle = 'Confirm'
if (sDefault == 'N') iFlags = iFlags | vbDefaultButton2
var d = {'Message' : sMessage, 'Flags' : iFlags, 'Title' : sTitle}
var dParams = JsDictionaryToVt(d)
var sCode = 'MsgBox(d("Message"), d("Flags"), d("Title"))'
var iChoice = VtEvalVbs(sCode, dParams)
dParams = null
if (iChoice == vbCancel) return xMute
else if (iChoice == vbYes) return 'Y'
else return 'N'
} // DialogConfirm method

function DialogInput(sTitle, sField, sValue) {
// Get input from a single edit box

if (sField != xMute && sField.slice(-1) != ':') sField += ':'
if (sTitle == xMute) sTitle = 'Input'
var d = {'Field' : sField, 'Title' : sTitle, 'Value' : sValue}
var dParams = JsDictionaryToVt(d)
var sCode = 'InputBox(d("Field"), d("Title"), d("Value"))'
var sReturn = VtEvalVbs(sCode, dParams)
dParams = null
return sReturn
} // DialogInput method

function DialogShow(oTitle, oMessage) {
// Show string version of two parameters in the title && prompt of a message box

var sTitle = JsString(oTitle)
var sMessage = JsString(oMessage)
var iFlags
if (sTitle == 'Alert' || sTitle == 'Error') iFlags = vbExclamation // 48	warning icon
else iFlags = vbInformation // 64 information icon
iFlags |= vbSystemModal // 4096	System modal

var d = {'Message' : sMessage, 'Flags' : iFlags, 'Title' : sTitle}
var dParams = JsDictionaryToVt(d)
var sCode = 'MsgBox(d("Message"), d("Flags"), d("Title"))'
VtEvalVbs(sCode, dParams)
dParams = null
} // DialogShow method

function FileCopy(sSource, sTarget) {
// Copy source to destination file, replacing if it exists

if (!FileDelete(sTarget)) return false

var oSystem =VtCreateFileSystemObject()
try {
oSystem.CopyFile(sSource, sTarget)
}
catch (e) { }
oSystem = null
return FileExists(sTarget)
} // FileCopy method

function FileDelete(sFile) {
// Delete a file if it exists, && test whether it is subsequently absent
// either because it was successfully deleted || because it was!present in the first place

if (!FileExists(sFile)) return true
var oSystem =VtCreateFileSystemObject()
try {
oSystem.DeleteFile(sFile, true)
}
catch (e) {}

oSystem = null
return !FileExists(sFile)
} // FileDelete method

function FileExists(sFile) {
// Test whether File exists

var oSystem =VtCreateFileSystemObject()
var bReturn = !oSystem.FolderExists(sFile) && oSystem.FileExists(sFile)

oSystem =null
return bReturn
} // FileExists method

function FileGetDate(sFile) {
// Get date of a file

if (!FileExists(sFile)) return null

var oSystem =VtCreateFileSystemObject()
var oFile =oSystem.GetFile(sFile)
var dtReturn =oFile.DateLastModified

oFile = null
oSystem = null
return dtReturn
} // FileGetDate method

function FileGetSize(sFile) {
// Get size of a file

if (!FileExists(sFile)) return 0

var oSystem =VtCreateFileSystemObject()
var oFile =oSystem.GetFile(sFile)
var iReturn =oFile.size

oFile = null
oSystem = null
return iReturn
} // FileGetSize method

function FileGetType(sFile) {
// Get file type

if (!FileExists(sFile)) return null

var oSystem =VtCreateFileSystemObject()
var oFile =oSystem.GetFile(sFile)
var sReturn =oFile.Type

oFile = null
oSystem = null
return sReturn
} // FileGetType method

function FileMove(sSource, sTarget) {
// Move source to destination file, replacing if it exists

if (!FileDelete(sTarget)) return false

var oSystem =VtCreateFileSystemObject()
try {
oSystem.MoveFile(sSource, sTarget)
}
catch (e) {}

oSystem = null
return FileExists(sTarget)
} // FileMove method

function FileToString(sFile) {
// Get content of text file

if (FileGetSize(sFile) == 0) return xMute

var oSystem =VtCreateFileSystemObject()
var bCreate = false
var oFile = oSystem.OpenTextFile(sFile, ioForReading, bCreate, formatTriStateFalse)
var sReturn =oFile.ReadAll()
oFile.Close()

oFile = null
oSystem = null
return sReturn
} // FileToString method

function FolderCopy(sSource, sTarget) {
// Copy source to destination Folder, replacing if it exists

if (!FolderExists(sTarget)) return false

var oSystem =VtCreateFileSystemObject()
try {
oSystem.CopyFolder(sSource, sTarget)
}
catch (e) {}

oSystem = null
return FolderExists(sTarget)
} // FolderCopy method

function FolderCreate(sFolder) {
// Create folder

if (FolderExists(sFolder)) return true

var oSystem =VtCreateFileSystemObject()
try {
oSystem.CreateFolder(sFolder)
}
catch (e) {}

oSystem = null
return FolderExists(sFolder)
} // FolderCreate method

function FolderDelete(sFolder) {
// Delete a Folder if it exists, && test whether it is subsequently absent
// either because it was successfully deleted || because it was!present in the first place

if (!FolderExists(sFolder)) return true

var oSystem =VtCreateFileSystemObject()
try {
oSystem.DeleteFolder(sFolder, true)
}
catch (e) {}

oSystem = null
return !FolderExists(sFolder)
} // FolderDelete method

function FolderExists(sFolder) {
// Test whether folder exists

var oSystem =VtCreateFileSystemObject()
var bReturn =oSystem.FolderExists(sFolder)

oSystem =null
return bReturn
} // Folder exists method

function FolderGetDate(sFolder) {
// Get date of a Folder

if (!FolderExists(sFolder)) return null

var oSystem =VtCreateFileSystemObject()
var oFolder =oSystem.GetFolder(sFolder)
var dtReturn =oFolder.DateLastModified

oFolder = null
oSystem = null
return dtReturn
} // FolderGetDate method

function FolderGetSize(sFolder) {
// Get size of folder, summing the sizes of files && subfolders it contains

if (!FolderExists(sFolder)) return 0

var oSystem =VtCreateFileSystemObject()
var oFolder =oSystem.GetFolder(sFolder)
var iReturn =oFolder.size

oFolder = null
oSystem = null
return iReturn
} // FolderGetSize method

function FolderMove(sSource, sTarget) {
// Move source to destination Folder, replacing if it exists

if (!FolderExists(sSource)) return false

var oSystem =VtCreateFileSystemObject()
try {
oSystem.MoveFolder(sSource, sTarget)
}
catch (e) {}

oSystem = null
return FolderExists(sTarget)
} // FolderMove method

function HtmlEncodeString(sText) {
// Encode a string for HTML or XML

var sReturn = sText.replace('<', '&lt;')
sReturn = sReturn.replace('>', '&gt;')
sReturn = sReturn.replace('&', '&amp;')
sReturn = sReturn.replace(';', '&sc;')
return sReturn
} // HtmlEncodeString method

function HtmlGetLinks(sUrl) {
// Get a list of two-item lists containing the URL and text of a link

var lLinks = VtCreateList()
var dUrls = VtCreateDictionary()
var oDoc = VtCreateHtmlFile()
var sBody = WebUrlToString(sUrl)
oDoc.write(sBody)
var oLinks = oDoc.links
// var oLinks = oDoc.all.tags('a')
// These do not work
// JsPrint('domain=' + oDoc.domain)
// JsPrint('hostname=' + oDoc.hostname)
for (var i = 0; i < oLinks.length; i++) {
var oLink = oLinks.item(i)
var sUrl = oLink.href
var sText = oLink.innerText
if (dUrls.Exists(sUrl)) continue
dUrls.Add(sUrl, '')
// if (sUrl.indexOf('://') == -1) continue

var lLink = VtCreateList()
lLink.Add(sUrl)
lLink.Add(sText)
lLinks.Add(lLink)
}

oDoc.close()

lLink = null
dUrls = null
oDoc = null
return lLinks
} // HtmlGetLinks method

function HtmlGetUrls(sUrl) {
// Get a list of URLs linked to a web page

var lReturn = VtCreateList()
var lLinks = HtmlGetLinks(sUrl)
for (var i = 0; i < lLinks.Count; i++) {
var lLink = lLinks.Item(i)
var sLinkUrl = lLink.Item(0)
sLinkUrl = UrlNormalize(sLinkUrl, sUrl)
if (!lReturn.Contains(sLinkUrl)) lReturn.Add(sLinkUrl)
}

lLink = null
lLinks = null
return lReturn
} // HtmlGetUrls method

function HtmlGetText(sUrl) {
// Get the text of an HTML page

var HKCU = 0x80000001 // HKEY_CURRENT_USER
var sRegPath = 'HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Main\\Disable Script Debugger\\'
// neither technique works with JScript
// var sOldRegValue = RegistryRead(sRegPath)
// var sOldRegValue = RegistryGetString(HKCU, 'Software\\Microsoft\\Internet Explorer\\Main', 'Disable Script Debugger')
// if (!StringEquiv(sOldRegValue, 'yes')) RegistrySetString(HKCU, 'Software\\Microsoft\\Internet Explorer\\Main', 'Disable Script Debugger', 'yes')
var oDoc = VtCreateHtmlFile()
var sBody = WebUrlToString(sUrl)
oDoc.write(sBody)
// Does not work
// oDoc.open(sUrl)
var sText = oDoc.body.innerText
oDoc.close()
// if (!StringEquiv(sOldRegValue, 'yes')) RegistrySetString(HKCU, 'Software\\Microsoft\\Internet Explorer\\Main', 'Disable Script Debugger', sOldRegValue)

oDoc = null
return sText
} // HtmlGetText method

function HtmlGetTableText(sUrl, iTable) {
// Get the text of an HTML table specified by number, or null for all of them

var HKCU = 0x80000001 // HKEY_CURRENT_USER
var sRegPath = 'HKEY_CURRENT_USER\\Software\\Microsoft\\Internet Explorer\\Main\\Disable Script Debugger\\'
// neither technique works with JScript
// var sOldRegValue = RegistryRead(sRegPath)
// var sOldRegValue = RegistryGetString(HKCU, 'Software\\Microsoft\\Internet Explorer\\Main', 'Disable Script Debugger')
// if (!StringEquiv(sOldRegValue, 'yes')) RegistrySetString(HKCU, 'Software\\Microsoft\\Internet Explorer\\Main', 'Disable Script Debugger', 'yes')
var oDoc = VtCreateHtmlFile()
var sBody = WebUrlToString(sUrl)
oDoc.write(sBody)
var oTables = oDoc.all.tags('table')

var sText = xMute
if (JsIsNull(iTable)) {
for (var i = 0; i < oTables.length; i ++ ) {
var oTable = oTables.item(i)
sText += oTable.innerText + vbCrLf + vbCrLf
}
}
else {
var oTable = oTables.item(iTable)
sText = oTable.innerText + vbCrLf + vbCrLf
}
oDoc.close()
// if (!StringEquiv(sOldRegValue, 'yes')) RegistrySetString(HKCU, 'Software\\Microsoft\\Internet Explorer\\Main', 'Disable Script Debugger', sOldRegValue)

oTable = null
oTables = null
oDoc = null
return sText
} // HtmlGetTableText method

function JsDictionaryToEncodedString(d) {
// Convert dictionary to string with http encoding
var sReturn = ''
for (var sKey in d) {
var sValue = d[sKey]
var sComponent = encodeURIComponent(sKey) + '=' + encodeURIComponent(sValue)
if (sReturn.length > 0) sReturn += '&'
sReturn += sComponent
}
return sReturn
} // JsDictionaryToEncodedString method

function JsDictionaryToVt(d) {
// Convert JScript dictionary to variant

var dReturn = VtCreateDictionary()
for (var sKey in d) dReturn.Add(sKey, d[sKey])
return dReturn
} // JsDictionaryToVt method

function JsEval(sCode, o1, o2, o3, o4) {
// Evaluate sCode, optionally referencing up to 4 parameters of any type, and return the result

return eval(sCode, "unsafe")
} // JsEval method

function JsInspectObject(sName, oValue) {
// Report on type of object and its subobjects

var sReturn = ''
var sType = typeof(oValue)
if (sType != 'object' || oValue == null) sReturn += sType + ', ' + sName + ', ' + oValue + '\n'
else if (typeof(oValue.length) == 'number') {
sReturn += 'array, ' + sName + '\n'
for (var i = 0; i < oValue.length; i++) {
// sReturn += 'index ' + i + '\n'
var oItem = oValue[i]
sReturn += JsInspectObject(sName + '.' + i, oItem)
}
}
else {
sReturn += 'object, ' + sName+ '\n'
for (var sAttribute in oValue) {
// sReturn += 'attribute ' + sAttribute + '\n'
var oItem = oValue[sAttribute]
sReturn += JsInspectObject(sName + '.' + sAttribute, oItem)
}
}
return sReturn
} // JsInspectObject method

function JsIsBlank(sText) {
// Test if string is empty or white space

var s = JsString(sText)
if (s.length) s = s.replace(xSpace, xMute)
if (s.length) s = s.replace(vbTab, xMute)
if (s.length) s = s.replace(vbCr, xMute)
if (s.length) s = s.replace(vbLf, xMute)
if (s.length) s = s.replace(vbFormFeed, xMute)
if (s.length) s = s.replace(vbVerticalTab, xMute)

if (!s.length) return true
else return false
} // JsIsBlank method

function JsIsMute(o) {
// test for empty string

if (typeof(o) != 'string') return false
if (o == vbFormFeed) return true
else return false
} // JsIsMute method

function JsIsNull(o) {
// Test for null

return o == null
} // JsIsNull method

function JsIsObject(o) {
// Test for object

return ((typeof(o) == 'object') && (o != null))
} // JsIsObject method

function JsIsUndefined(o) {
// Test whether object is undefined

return (typeof(o) == 'undefined')
} // JsIsUndefined method

function JSNumber(o) {
// Convert to JScript number

var nReturn = 0
try {
nReturn = 0 + o
}
catch (e) {}
return nReturn
} // JSNumber method

function JsObjectToVt(oValue) {
// Convert JScript object to variant

var sType = typeof(oValue)
if (sType != 'object' || oValue == null) return oValue
else if (typeof(oValue.length) == 'number') {
var a = VtCreateList()
for (var i = 0; i < oValue.length; i++) {
var oItem = oValue[i]
a.Add(JsObjectToVt(oItem))
}
return a
}
else {
var d = VtCreateDictionary()
for (var sAttribute in oValue) {
oItem = oValue[sAttribute]
d.Add(sAttribute, JsObjectToVt(oItem))
}
return d
}
} // JsObjectToVt method

function JsPrint(o) {
// Print to screen using console mode of Windows Script Host

return WScript.Echo(o)
// return System.Console.WriteLine(o)
} // JsPrint method

function JsPrintObject(sName, oValue) {
// Print type of object and its subobjects

var sType = typeof(oValue)
if (sType != 'object' || oValue == null) JsPrint(sType + ', ' + sName + ', ' + oValue)
else if (typeof(oValue.length) == 'number') {
JsPrint('array, ' + sName)
for (var i = 0; i < oValue.length; i++) {
var oItem = oValue[i]
JsPrintObject(sName + '.' + i, oItem)
}
}
else {
JsPrint('object, ' + sName)
for (var sAttribute in oValue) {
var oItem = oValue[sAttribute]
JsPrintObject(sName + '.' + sAttribute, oItem)
}
}
} // JsPrintObject method

function JsSplit(sText, sDelimiter) {
// Split but ensure an empty array for empty text

if (!sText) return []
return sText.split(sDelimiter)
} // JsSplit method

function JsSplitLines(sText) {
// JsSplit by line feeds after chomping

var sText = StringConvertToUnixLineBreak(sText)
sText = StringChomp(sText)
return JsSplit(sText, '\n')
} // JsSplitLines method

function JsString(o) {
// Convert to a JScript string

var sReturn = xMute
try {
sReturn = xMute + o
}
catch (e) {}
return sReturn
} // JsString method

function JsToVt(sJs) {
// Convert string in JavaScript Object Notation to COM exchange format

var sJs = '(' + sJs + ')'
var oValue = eval(sJs)
return JsObjectToVt(oValue)
} // JsToVt method

function PathCombine(sFolder, sName) {
// Combine folder and name to form a valid path

var sReturn = sFolder + '\\' + sName
sReturn = sReturn.replace('\\\\', '\\')
return sReturn
} // PathCombine method

function PathCreateTempFolder() {
// Create temporary folder && return its full path

var sFolder = PathCombine(PathGetTempFolder(), PathGetTempName())
return FolderCreate(sFolder)
} // PathCreateTempFolder method

function PathExists(sPath) {
// Test whether path exists

var oSystem =VtCreateFileSystemObject()
var bReturn =oSystem.FolderExists(sPath) || oSystem.FileExists(sPath)

oSystem =null
return bReturn
} // PathExists method

function PathGetBase(sPath) {
// Get base/root name of a file or folder

var oSystem =VtCreateFileSystemObject()
var sReturn =oSystem.GetBaseName(sPath)

oSystem = null
return sReturn
} // PathGetBase method

function PathGetCurrentDirectory() {
// Get current directory of active process

var oShell =VtCreateWScriptShell()
var sReturn =oShell.CurrentDirectory

oShell = null
return sReturn
} // PathGetCurrentDirectory method

function PathGetExtension(sPath) {
// Get extention of file || folder

var oSystem =VtCreateFileSystemObject()
var sReturn =oSystem.GetExtensionName(sPath)

oSystem = null
return sReturn
} // PathGetExtension method

function PathGetFolder(sPath) {
// Get the parent folder of a file or folder

var oSystem =VtCreateFileSystemObject()
var sReturn =oSystem.GetParentFolderName(sPath)

oSystem = null
return sReturn
} // PathGetFolder method

function PathGetInternetCacheFolder() {
// Get Windows folder for temporary Internet files

var iTemporaryInternetFiles = 32
var oShell = VtCreateShellApplication()
var oFolder = oShell.Namespace(iTemporaryInternetFiles)
var oItem = oFolder.Self
var sReturn = oItem.Path

oItem = null
oFolder = null
oShell = null
return sReturn
} // GetInternetCacheFolder method

function PathGetLong(sPath) {
// Get long name of file or folder

var oShell = VtCreateWScriptShell()
var oShortcut = oShell.CreateShortcut('temp.lnk')
oShortcut.TargetPath = sPath
var sReturn = oShortcut.TargetPath

oShortcut = null
oShell = null
return sReturn
} // PathGetLong method

function PathGetName(sPath) {
// Get the file or folder name at the end of a path

var oSystem =VtCreateFileSystemObject()
var sReturn =oSystem.GetFileName(sPath)

oSystem = null
return sReturn
} // PathGetName method

function PathGetShort(sPath) {
// Get short path (8.3 style) of a file or folder

var oSystem =VtCreateFileSystemObject()
if (FolderExists(sPath)) {
var oFolder =oSystem.GetFolder(sPath)
var sReturn =oFolder.ShortPath
}
else {
var oFile =oSystem.GetFile(sPath)
var sReturn =oFile.ShortPath
}

oFile = null
oFolder = null
oSystem = null
return sReturn
} // PathGetShort method

function PathGetSpec(sDir, sWildcards, sFlags) {
// Get a list of paths, specifying folder, wild card pattern, && sort order

var lReturn = VtCreateList()
var iWindowStyle = 0 // hidden
var bWait = true
var sCommand = '%COMSPEC% /c dir /b ' + sFlags + ' ' + '"' + sDir + '\\' + sWildcards + '"'
var sTempFile = PathGetTempFile()
var sCommand = sCommand + ' >' + sTempFile
ShellRun(sCommand, iWindowStyle, bWait)
var sReturn = StringTrim(FileToString(sTempFile))
FileDelete(sTempFile)
var aReturn = sReturn.split(vbCrLf)
for (var i = 0; i < aReturn.length; i++) {
var s = aReturn[i]
if (!StringContains(s, ':', false)) s = PathCombine(sDir, s)
lReturn.Add(s)
}
return lReturn
} // PathGetSpec method

function PathGetTempFile() {
// Get full path of a temporary file

return PathGetTempFolder() + '\\' + PathGetTempName()
} // PathGetTempFile method

function PathGetTempFolder() {
// Get Windows folder for temporary files

var iTempFolder = 2
var oSystem =VtCreateFileSystemObject()
var sReturn =oSystem.GetSpecialFolder(iTempFolder).path

oSystem = null
return sReturn
} // PathGetTempFolder method

function PathGetTempName() {
// Get Name for temporary file || folder

var oSystem =VtCreateFileSystemObject()
var sReturn = oSystem.GetTempName()

oSystem = null
return sReturn
} // PathGetTempName method

function PathGetValid(sDir, sBase, sExt, bUnique) {
var sIllegal = "&=@%*+\\|':'<>/?" + xQuote
var sViewable = "!#$%&'()*+,-./0123456789:'<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
var sPrintable = xSpace + sViewable

var sSourceDir = sDir
var sSourceBase = sBase
var sSourceExt = sExt
if (StringLength(sSourceExt) && !StringStartsWith(sSourceExt, '.', false)) sSourceExt = '.' + sSourceExt
// var sLine = sSourceBase
var sLine = sBase
var iCount = StringLength(sIllegal)
for (var i = 0; i < iCount; i++) {
var s = sIllegal.charAt(i)
// if (StringContains(sLine, s, false)) sLine = sLine.replace(s, xSpace)
if (StringContains(sLine, s, false)) sLine = StringReplace(sLine, s, xSpace, false)
}

// sLine = StringReplaceAll(sLine, '  ', xSpace)
// sLine = StringReplaceAll(sLine, '  ', '_')
sLine = VtTrim(sLine)
sLine = RegExpReplace(sLine, ' +', '_', false)

var sTargetBase = sLine
var sTargetFile = sSourceDir + '\\' + sTargetBase + sSourceExt
if (bUnique && FileExists(sTargetFile)) {
var s = '_01'
var sTargetFile = sSourceDir + '\\' + sTargetBase + s + sSourceExt
var i = 1
while (FileExists(sTargetFile) && i <= 99 ) {
if (i < 10) s = '_0' + i
else s = '_' + i

sTargetFile = sSourceDir + '\\' + sTargetBase + s + sSourceExt
i++
}
}
return sTargetFile
} // PathGetValid method

function PathSetCurrentDirectory(sDir) {
// Set current directory of active process, and return previously current directory

var oShell =VtCreateWScriptShell()
var sReturn = oShell.CurrentDirectory
oShell.CurrentDirectory = sDir

oShell = null
return sReturn
} // PathSetCurrentDirectory method

function RegExpContains(sText, sMatch, bIgnoreCase) {
/*
Get Array containing the starting index and text of the first match of a regular expression
where sText is the string to search
sMatch is the regular expression to match
bIgnoreCase indicates whether capitalization matters
*/

var lReturn = VtCreateList()
var oExp = VtCreateRegExp()
oExp.Pattern = sMatch
oExp.Ignorecase = bIgnoreCase
oExp.Multiline = false
oExp.Global = false

var oMatches = oExp.Execute(sText)
var iCount = oMatches.Count
if (iCount) {
var oMatch = oMatches.Item(0)
var iIndex = oMatch.FirstIndex
var sValue = oMatch.Value
lReturn.Add(iIndex)
lReturn.Add(sValue)
}

oMatch = null
oMatches = null
oExp = null
return lReturn
} // RegExpContains method

function RegExpContainsLast(sText, sMatch, bIgnoreCase) {
/*
Get list containing the starting index and text of the last match of a regular expression
where sText is the string to search
sMatch is the regular expression to match
bIgnoreCase indicates whether capitalization matters
*/

var lReturn = VtCreateList()
var oExp = VtCreateRegExp()
oExp.Pattern = sMatch
oExp.Ignorecase = bIgnoreCase
oExp.Multiline = false
oExp.Global = true

var oMatches = oExp.Execute(sText)
var iCount = oMatches.Count
if (iCount) {
var oMatch = oMatches.Item(iCount - 1)
var iIndex = oMatch.FirstIndex
var sValue = oMatch.Value
lReturn.Add(iIndex, sValue)
}

oMatch = null
oMatches = null
oExp = null
return lReturn
} // RegExpContainsLast method

function RegExpCount(sText, sMatch, bIgnoreCase) {
/*
Count matches of a regular expression
where sText is the string to search
sMatch is the regular expression to match
bIgnoreCase indicates whether capitalization matters
*/

var oExp = VtCreateRegExp()
oExp.Pattern = sMatch
oExp.Ignorecase = bIgnoreCase
oExp.Multiline = false
oExp.Global = true

var oMatches = oExp.Execute(sText)
var iReturn = oMatches.Count

oMatches = null
oExp = null
return iReturn
} // RegExpCount method

function RegExpExtract(sText, sMatch, bIgnoreCase) {
/*
Get list containing matches of a regular expression
where sText is the string to search
sMatch is the regular expression to match
bIgnoreCase indicates whether capitalization matters
*/

var lReturn = VtCreateList()
var oExp = VtCreateRegExp()
oExp.Pattern = sMatch
oExp.Ignorecase = bIgnoreCase
oExp.Multiline = false
oExp.Global = true

var oMatches = oExp.Execute(sText)
var iCount = oMatches.Count
for (var i = 0; i < iCount; i++) {
var oMatch = oMatches.Item(i)
lReturn.Add(oMatch.Value)
}

oMatch = null
oMatches = null
oExp = null
return lReturn
} // RegExpExtract method

function RegExpReplace(sText, sMatch, sReplace, bIgnoreCase) {
/*
Replace text matching a regular expression
where sText is the string to search
sMatch is the regular expression to match
sReplace is the replacement text
bIgnoreCase indicates whether capitalization matters
*/

var oExp = VtCreateRegExp()
oExp.Pattern = sMatch
oExp.Ignorecase = bIgnoreCase
oExp.Multiline = false
oExp.Global = true

var sReturn = oExp.replace(sText, sReplace)

oExp = null
return sReturn
} // RegExpReplace method

function RegExpTest(sText, sMatch, bIgnoreCase) {
/*
Test match of a regular expression
where sText is the string to search
sMatch is the regular expression to match
bIgnoreCase indicates whether capitalization matters
*/

var oExp = VtCreateRegExp()
oExp.Pattern = sMatch
oExp.Ignorecase = bIgnoreCase
oExp.Multiline = false
oExp.Global = true

var bReturn = oExp.Test(sText)

oExp = null
return bReturn
} // RegExpTest method

function RegistryGetString(iRootKey, sSubKey, sValueName) {
// Get a string from registry

var oRegistry
var sValueData = xMute

var oRegistry = null
try {
oRegistry = VtGetWMIObject()
}
catch (e) { }
if (JsIsNull(oRegistry)) return xMute

oRegistry.GetStringValue(iRootKey, sSubKey, sValueName, sValueData)

oRegistry = null
return sValueData
} // RegistryGetString method

function RegistryRead(sKey) {
// Get a string from the registry

var sReturn = xMute
var oShell =VtCreateWScriptShell()
try {
var sReturn =oShell.RegRead(sKey)
}
catch (e) {}

oShell = null
return sReturn
} // RegistryRead method

function RegistrySetString(iRootKey, sSubKey, sValueName, sValueData) {
// Set a registry string

var oRegistry = null
try {
oRegistry = VtGetWMIObject()
}
catch (e) { }
if (JsIsNull(oRegistry)) return false

var bReturn = oRegistry.SetStringValue(iRootKey, sSubKey, sValueName, sValueData)

oRegistry = null
return bReturn
} // RegistrySetString method

function RegistryWrite(sKey, sValue) {
// Write a string to the registry

var oShell =VtCreateWScriptShell()
var bReturn = false
try {
bReturn =oShell.RegWrite(sKey, sValue, 'REG_SZ')
}
catch (e) { }

oShell = null
return bReturn
} // RegistryWrite method

function ShellCreateShortcut(sFile, sTargetPath, sWorkingDirectory, iWindowStyle, sHotkey) {
// Create a .lnk or .url file

if (!FileDelete(sFile)) return false

var oShell = VtCreateWScriptShell()
var oShortcut = oShell.CreateShortcut(sFile)
oShortcut.TargetPath = sTargetPath
oShortcut.WorkingDirectory = sWorkingDirectory
oShortcut.WindowStyle = iWindowStyle
oShortcut.Hotkey = sHotkey
oShortcut.Save()

oShortcut = null
oShell = null
return FileExists(sFile)
} // ShellCreateShortcut method

function ShellExec(sCommand) {
// Run a console mode command && return its standard output

var oShell =VtCreateWScriptShell()
var oExec =oShell.Exec(sCommand)
while ( oExec.Status ==0) {
VtSleep(10)
}

var oOutput =oExec.StdOut
var sReturn =oOutput.ReadAll()
oExec.Terminate()

oOutput = null
oExec = null
oShell = null
return sReturn
} // ShellExec method

function ShellExecute(sFile, sParams, sFolder, sVerb, iWindowStyle) {
// Execute a command with a verb like RunAs

var bReturn = false
var oShell = VtCreateShellApplication()
try {
oShell.ShellExecute(sFile, sParams, sFolder, sVerb, iWindowStyle)
bReturn = true
}
catch (e) { }
return bReturn
} // ShellExecute method

function ShellExpandEnvironmentVariables(sText) {
// Replace environment variables with their values

var oShell =VtCreateWScriptShell()
var sReturn =oShell.ExpandEnvironmentStrings(sText)

oShell = null
return sReturn
} // ShellExpandEnvironmentVariables method

function ShellGetEnvironmentVariable(sVariable) {
// Get the value of an environment variable

var oShell =VtCreateWScriptShell()
var oEnv =oShell.Environment
var sReturn =oEnv.Item(sVariable)

oEnv = null
oShell = null
return sReturn
} // ShellGetEnvironmentVariable method

function ShellGetShortcutTargetPath(sFile) {
// Get the target path of a shortcut file

var oShell = VtCreateWScriptShell()
var oShortcut = oShell.CreateShortcut(sFile)
var sReturn = oShortcut.TargetPath
oShortcut = null
oShell = null
return sReturn
} // ShellGetShortcutTargetPath method

function ShellGetSpecialFolder(vFolder) {
// Get a special Windows folder

var oShell = VtCreateShellApplication()
var oNamespace = oShell.Namespace(vFolder)
var oFolder = oNamespace.Self
var sReturn = oFolder.Path
oFolder = null
oNamespace = null
oShell = null
return sReturn
} // ShellGetSpecialFolder method

function ShellInvokeVerb(sPath, sVerb) {
// Invoke a verb on a file or folder

var sFolder = PathGetFolder(sPath)
var sName = PathGetName(sPath)
var oShell = VtCreateShellApplication()
var oFolder = oShell.Namespace(sFolder)
var oName = oFolder.ParseName(sName)
var bReturn = oName.InvokeVerb(sVerb)

oName = null
oFolder = null
oShell = null
return bReturn
} // ShellInvokeVerb method

function ShellOpen(sPath) {
// Open a file or folder with the default program associated with its type

return ShellRun(StringQuote(sPath), 1, false)
} // ShellOpen method

function ShellOpenWith(sExe, sParam) {
// Open a program with a file

return ShellRun(StringQuote(sExe) + ' ' + StringQuote(sParam), 1, false)
} // ShellRunWith method

function ShellRun(sFile, iStyle, bWait) {
/*
Launch a program or file, indicating its window style && whether to wait before returning
window styles:
0 Hides the window && activates another window
1 Activates && displays a window. If the window is minimized || maximized, the
system restores it to its original size && position. This flag should be used
when specifying an application for the first time
2 Activates the window && displays it minimized
3 Activates the window && displays it maximized
4 Displays a window in its most recent size && position. The active window
remains active
5 Activates the window && displays it in its current size && position
6 Minimizes the specified window && activates the next top-level window in the Z
order
7 Displays the window as a minimized window. The active window remains active
8 Displays the window in its current state. The active window remains active
9 Activates && displays the window. If it is minimized || maximized, the system
restores it to its original size && position. An application should specify
this flag when restoring a minimized window
10 Sets the show state based on the state of the program that started the
application
*/

var oShell =VtCreateWScriptShell()
var iReturn = -2
try {
iReturn =oShell.Run(sFile, iStyle, bWait)
}
catch (e) { }

oShell = null
return iReturn
} // ShellRun method

function ShellRunCommandPrompt(sDir) {
// Open a command prompt in the directory specified

return ShellRun('%COMSPEC% /k cd ' + StringQuote(sDir), 1, false)
} // ShellRunCommandPrompt method

function ShellRunExplorerWindow(sDir) {
// Open Windows Explorer in the directory specified

return ShellOpen(sDir)
} // ShellRunExplorerWindow method

function ShellWait(sPath) {
// Run a program and wait for it to return

return ShellRun(StringQuote(sPath), 0, true)
} // ShellWait method

function StringAppendToFile(sText, sFile, sDivider) {
// Append string to File, omitting divider if the first one

if (FileExists(sFile)) sText = FileToString(sFile) + sDivider + sText
StringToFile(sText, sFile)
return FileExists(sFile)
} // StringAppendToFile method

function StringChomp(sText) {
// Chop \n for both ends of a string

var sReturn = sText
while (sReturn.length) {
if (!StringStartsWith(sReturn, '\n', false)) break
sReturn = StringChopLeft(sReturn, 1)
}
while (sReturn.length) {
if (!StringEndsWith(sReturn, '\n', false)) break
sReturn = StringChopRight(sReturn, 1)
}
return sReturn
} // StringChomp method

function StringChopLeft(sText, iCount) {
// Remove iCount characters from left of sText

var iIndex = Math.min(iCount, sText.length)
return sText.slice(iIndex)
} // StringChopLeft method

function StringChopRight(sText, iCount) {
// Remove iCount characters from Right of sText

var iIndex = Math.min(iCount, sText.length) * -1
return sText.slice(0, iIndex)
} // StringChopRight method

function StringContains(sText, sMatch, bIgnoreCase) {
// Test if a string is contained in another

if (bIgnoreCase) {
var sText = sText.toLowerCase()
var sMatch = sMatch.toLowerCase()
}

return sText.indexOf(sMatch) >= 0
} // StringContains method

function StringConvertToMacLineBreak(sText) {
// Convert to Macintosh line break, \r

var sReturn = sText.replace(vbCrLf, vbCr)
sReturn = sReturn.replace(vbLf, vbCr)
return sReturn
}

function StringConvertToUnixLineBreak(sText) {
// Convert to Unix line break, \n

var sReturn = sText.replace(vbCrLf, vbLf)
sReturn = sReturn.replace(vbCr, vbLf)
return sReturn
}

function StringConvertToWinLineBreak(sText) {
// Convert to standard Windows line break, \r\n

var sReturn = sText.replace(vbCrLf, vbLf)
sReturn = sReturn.replace(vbCr, vbLf)
sReturn = sReturn.replace(vbLf, vbCrLf)
return sReturn
}

function StringCount(sText, sMatch) {
// Count occurrences of a string within another string

var iLength = sText.length
var s = sText.replace(sMatch, xMute)
var iDelta = iLength - s.length
var iReturn = iDelta / sMatch.length
return iReturn
} // StringCount method

function StringEndsWith(sText, sSuffix, bIgnoreCase) {
// Test whether first string ends with second one

if (bIgnoreCase) {
var sText = sText.toLowerCase()
var sSuffix = sSuffix.toLowerCase()
}

var iText = sText.length
var iSuffix = sSuffix.length
if (iSuffix > iText) return false
return sText.slice(-iSuffix) == sSuffix
} // StringEndsWith method

function StringEqual(s1, s2) {
// Test if two strings are exactly equal

return s1 == s2
} // StringEqual method

function StringEquiv(s1, s2) {
// Test whether two strings are the same except for capitalization

return s1.toLowerCase() == s2.toLowerCase()
} // StringEquiv method

function StringGetASCII(sText) {
// Get space delimited ASCII codes for characters in string

var sReturn = xMute
var iCount = sText.length
for (var i = 0; i < iCount; i++ ) {
var s = sText.charAt(i)
if (sReturn.length) sReturn += xSpace
sReturn += s.charCode(0)
}
return sReturn
} // StringGetASCII method

function StringLeft(sText, iCount) {
// Return leftmost characters of a string

return sText.slice(0, iCount)
} // StringLeft method

function StringLength(sText) {
// Return length of a string

return sText.length
} // StringLength method

function StringLower(sText) {
// Convert string to lower case

return sText.toLowerCase()
} // StringLower method

function StringPlural(sItem, iCount) {
// Return singular || plural form of a string, depending on whether count equals one

var sReturn = JsString(iCount) + ' ' + sItem
if (iCount != 1) sReturn += 's'
return sReturn
} // StringCount method

function StringQuote(sText) {
// Quote a string

return '"' + sText + '"'
} // StringQuote method

function StringReplaceAll(sText, sMatch, sReplace, bIgnoreCase) {
// Replace all occurrences of a string within another

if (StringContains(sReplace, sMatch, bIgnoreCase)) return StringReplace(sText, sMatch, sReplace, bIgnoreCase)

var sReturn = sText
while ( StringContains(sReturn, sMatch, bIgnoreCase)) {
sReturn = StringReplace(sReturn, sMatch, sReplace, bIgnoreCase)
}
return sReturn
} // StringReplaceAll method

function StringRight(sText, iCount) {
// Return rightmost characters of a string

var iLength = sText.length
var iPosition = iLength - iCount
return sText.slice(iPosition)
} // StringRight method

function StringSlice(sText, iStart, iEnd) {
return sText.slice(iStart, iEnd)
} // StringSlice method

function StringStartsWith(sText, sPrefix, bIgnoreCase) {
// Test whether first string starts with second one

if (bIgnoreCase) {
var sText = sText.toLowerCase()
var sPrefix = sPrefix.toLowerCase()
}

var iText = sText.length
var iPrefix = sPrefix.length
if (iPrefix > iText) return false

return sText.slice(0, iPrefix) == sPrefix
} // StringStartsWith method

function StringToFile(sText, sFile) {
// Saves string to text file, replacing if it exists

if (!FileDelete(sFile)) return false

var bReplace = true
var bUnicode = false
var oSystem =VtCreateFileSystemObject()
var oFile =oSystem.CreateTextFile(sFile, bReplace, bUnicode)
try {
oFile.Write(sText)
oFile.Close()
}
catch (e) { }

oFile = null
oSystem = null
return FileExists(sFile)
} // StringToFile method

function StringToList(sText, sDelimiter) {
// Convert string with specified delimiter to list

var lReturn = VtCreateList()
var aParts = sText.split(sDelimiter)
for (var i = 0; i < aParts.length; i++) {
var sPart = a[i]
lReturn.Add(sPart)
}
return lReturn
} // StringToList method

function StringTrim(sText) {
// Trim white space from both ends of a string

// return sText.replace(/(^\s*)|(\s*$)/g/, '')
return RegExpReplace(sText, '(^\s*)|(\s*$)', '', false)
} // StringTrim method

function StringTrimLeft(sText) {
// Trim white space from left end of a string

return RegExpReplace(sText, '^\s*', '', false)
} // StringTrimLeft method

function StringTrimRight(sText) {
// Trim white space from right end of a string

return RegExpReplace(sText, '\s*$', '', false)
} // StringTrimRight method

function StringUnquote(sText) {
// Unquote a string

var sReturn = sText
while ( StringLeft(sReturn, 1) == '"') {
sReturn = StringChopLeft(sReturn, 1)
}

while (StringRight(sReturn, 1) == '"') {
sReturn = StringChopRight(sReturn, 1)
}
return sReturn
} // StringUnquote method

function StringUpper(sText) {
// Convert string to upper case

return sText.toUpperCase()
} // StringUpper method

function StringWrap(sText, iMaxLine) {
var aLines, aWords
var i, j
var sReturn, sLines, sLine, sWords, sWord

aLines = sText.split(vbCrLf)
sReturn = xMute
var iCount = aLines.length
for (var i = 0; i < iCount; i++) {
sLine = aLines[i]
if (sLine.length > iMaxLine) {
aWords = sLine.split(' ')
sLine = xMute
for (var j = 0; j < aWords.length; j++) {
sWord = aWords(j)
if (sLine.length + sWord.length > iMaxLine) {
sReturn += StringTrim(sLine) + vbCrLf
sLine = sWord + ' '
}
else {
sLine = sLine + sWord + ' '
}
}
}
else {
sReturn += StringTrimRight(sLine) + vbCrLf
}
}
return sReturn
} // StringWrap method

function UrlCreate(sProtocol, sHost, sPath, sQuery) {
// Create a URL from components

var sReturn = xMute
if (!sProtocol) sProtocol = 'http'
sReturn += sProtocol + '://'
if (sHost) sReturn += sHost
if (sPath) sReturn += '/' + sPath
if (sQuery) sReturn += '?' + sQuery
return sReturn
} // UrlCreate method

function WebUrlDownloadPath(sUrl, sFolder, bUnique) {
// /Get file from URL, trying various techniques

var sUrl = UrlNormalize(sUrl, null)
var sFile = WebUrlFileName(sUrl)
if (sFile) return PathCombine(sFolder, sFile)

var sQuery = UrlGetQuery(sUrl)
var sFile = UrlGetFile(sUrl)
if (!sQuery && sFile) return PathCombine(sFolder, sFile)

var sBase = UrlGetPathPlus(sUrl)
var sExtension = 'bin'
if (WebUrlIsHtml(sUrl)) {
sExtension = 'htm'
if (!sBase) sBase = 'page'
}
else {
var sType = WebUrlContentType(sUrl)
var aParts = sType.split('/')
var iLength = aParts.length
if (iLength && aParts[0]) sExtension = aParts[iLength - 1]
if (!sBase) sBase = 'file'
}
var sReturn = PathGetValid(sFolder, sBase, sExtension, bUnique)
return sReturn
} // WebUrlDownloadPath method

function UrlGetBaseDomain(sUrl) {
// Get base domain of a URL

var sReturn = xMute
var s = UrlGetHost(sUrl)
var a = s.split('.')
var iLength = a.length
if (iLength >= 2) s = a[iLength -2] + '.' + a[iLength - 1]
if (s.indexOf('.') >= 0) sReturn = s
return sReturn
} // UrlGetBaseDomain method

function UrlGetHost(sUrl) {
// Get subdomain and domain of a URL

var sReturn = sUrl
var i = sReturn.indexOf('://')
if (i >= 0) sReturn = sReturn.slice(i + 3)
// if (StringStartsWith(sReturn, 'www.', true)) sReturn = StringChopLeft(sReturn, 4)
i = sReturn.indexOf('/')
if (i >= 0) sReturn = sReturn.slice(0, i)
if (sReturn.indexOf('.') == -1) sReturn = xMute
return sReturn
} // UrlGetHost method

function UrlGetExtension(sUrl) {
// Get extension of a URL

var sReturn = UrlGetFile(sUrl)
if (sReturn) sReturn = PathGetExtension(sReturn)
return sReturn
} // UrlGetExtension method

function UrlGetFile(sUrl) {
// Get file of a URL

var sReturn = UrlGetPath(sUrl)
if (sReturn) sReturn = PathGetName(sReturn)
return sReturn
} // UrlGetFile method

function UrlGetFolder(sUrl) {
// Get folder of a URL

var sReturn = UrlGetPath(sUrl)
if (sReturn) sReturn = PathGetFolder(sReturn)
return sReturn
} // UrlGetFolder method

function UrlGetFragment(sUrl) {
// Get fragment of a URL

var sReturn = xMute
var i = sUrl.indexOf('#')
if (i >= 0) sReturn = sUrl.slice(i + 1)
return sReturn
} // UrlGetFragment method

function UrlGetPath(sUrl) {
// Get path of a URL

var sReturn = UrlGetPathPlus(sUrl)
var sFragment = UrlGetFragment(sReturn)
if (sFragment) sReturn = StringChopRight(sReturn, sFragment.length + 1)
var sQuery = UrlGetQuery(sReturn)
if (sQuery) sReturn = StringChopRight(sReturn, sQuery.length + 1)
return sReturn
} // UrlGetPath method

function UrlGetPathPlus(sUrl) {
// Get path and fragment or query of a URL

var sReturn = xMute
var s = sUrl
var sProtocol = UrlGetProtocol(s)
if (sProtocol) s = StringChopLeft(s, sProtocol.length + 3)
var sHost = UrlGetHost(s)
if (sHost) s = StringChopLeft(s, sHost.length + 1)
sReturn = s
return sReturn
} // UrlGetPathPlus method

function UrlGetPrePath(sUrl) {
// Get part of URL before path

var sReturn = xMute
var sPathPlus = UrlGetPathPlus(sUrl)
if (sPathPlus) sReturn = StringChopRight(sReturn, sPathPlus.length)
} // UrlGetPrePath method

function UrlGetQuery(sUrl) {
// Get query of URL

var sReturn = xMute
var i = sUrl.indexOf('?')
if (i >= 0) sReturn = sUrl.slice(i + 1)
return sReturn
} // UrlGetQuery method

function UrlGetProtocol(sUrl) {
// Get protocol of URL

var sReturn = xMute
var i = sUrl.indexOf('://')
if (i >= 0) sReturn = sUrl.slice(0, i)
return sReturn
} // UrlGetProtocol method

function UrlGetSubdomain(sUrl) {
// Get subdomain of a URL

var sReturn = xMute
var s = UrlGetHost(sUrl)
var a = s.split('.')
for (var i = 0; i < a.length - 2; i++) {
if (i) sReturn += '.'
sReturn += a[i]
}
return sReturn
} // UrlGetSubdomain method

function UrlNormalize(sUrl, sBase) {
// Normalize a URL for comparison

var sReturn = sUrl
var sProtocol = UrlGetProtocol(sReturn)
if (!sProtocol && sBase) {
var iIndex = sUrl.indexOf(':/')
if (iIndex >= 0) sReturn = StringChopLeft(sReturn, iIndex + 2)
if (!StringEndsWith(sBase, '/', false) && !StringStartsWith(sReturn, '/', false)) sReturn = sBase + '/' + sReturn
else sReturn = sBase + sReturn
}

sProtocol = UrlGetProtocol(sReturn)
if (!sProtocol) sUrl = 'http://' + sReturn

var sPrePath = UrlGetPrePath(sReturn)
if (sReturn == sPrePath && !StringEndsWith(sPrePath, '/', false)) sReturn += '/'

var sFragment = UrlGetFragment(sReturn)
if (sFragment) sReturn = StringChopRight(sReturn, sFragment.length + 1)
return sReturn
} // UrlNormalize method

function VtArrayToJs(a) {
// Convert variant array to JScript

return (new VBArray(a)).toArray()
} // VtArrayToJs method

function VtArrayToList(a) {
// Convert variant array to list

var aJs = VtArrayToJs(a)
var lReturn = VtCreateList()
for (var i = 0; i < aJs.length; i++) lReturn.Add(aJs[i])
return lReturn
} // VtArrayToList method

function VtCopyDictionary(dItems) {
// Copy a dictionary

var dReturn = VtCreateDictionary()
var aKeys = VtDictionaryKeysToJs(dItems)
for (var i = 0; i < aKeys.length; i++) {
var sKey = aKeys[i]
dReturn(sKey) = dItems(sKey)
}
return dReturn
} // VtCopyDictionary method

function VtCopyList(lItems) {
// Copy a list

var lReturn = VtCreateList()
for (var i = 0; i < lItems.Count; i++) {
var sItem = lItems(i)
lReturn.Add(sItem)
}
return lReturn
} // VtCopyList method

function VtCreateDictionary() {
// Return a variant dictionary

return new ActiveXObject('Scripting.Dictionary')
} // VtCreateDictionary method

function VtCreateFileSystemObject() {
// Return a file system object

return new ActiveXObject('Scripting.FileSystemObject')
} // VtCreateFileSystemObject

function VtCreateHtmlFile() {
// Create a variant HTMLFile object

return new ActiveXObject('HTMLFile')
} // CreateHtmlFile method

function VtCreateInternetExplorerApplication() {
// Return an Internet Explorer object

return new ActiveXObject('InternetExplorer.Application')
} // VtCreateInternetExplorerApplication method

function VtCreateList() {
// Create a variant list object

return new ActiveXObject('System.Collections.ArrayList')
} // VtCreateList method

function VtCreateRecordSet() {
var oRs = new ActiveXObject('ADODB.RecordSet')
oRs.CursorLocation = adUseClient
return oRs
} // VtCreateRecordSet method

function VtCreateRegExp() {
// Return a scripting RegExp object

return new ActiveXObject('VBScript.RegExp')
} // VtCreateRegExp method

function VtCreateShellApplication() {
// Return a Shell.Application object

return new ActiveXObject('Shell.Application')
} // VtCreateShellApplication method

function VtCreateStream() {
// Return an ADODB.Stream object

var oStream = new ActiveXObject('ADODB.Stream')
oStream.Type = adTypeBinary
oStream.Open()
return oStream
} // VtCreateStream method

function VtCreateVBScriptControl() {
// Return MSScriptControl.ScriptControl object

var oScript = new ActiveXObject('MSScriptControl.ScriptControl')
oScript.Language = 'VBScript'
return oScript
} // VtCreateVBScriptControl method

function VtCreateWebRequest() {
// Create web request object

// Does not work reliably with GET request
// return new ActiveXObject('MSXML2.XMLHTTP')

return new ActiveXObject('MSXML2.ServerXMLHTTP')

// Does not work reliably with POST request
var oRequest = new ActiveXObject('WinHttp.WinHttpRequest.5.1')
var WinHttpRequestOption_SslErrorIgnoreFlags  = 4
oRequest.Option(WinHttpRequestOption_SslErrorIgnoreFlags) = 0x3300 // ignore all server certificate errors
var WinHttpRequestOption_EnableHttpsToHttpRedirects = 12
oRequest.Option(WinHttpRequestOption_EnableHttpsToHttpRedirects  ) = true
return oRequest
} // VtCreateWebRequest method

function VtCreateWScriptShell() {
// Return WScript.Shell object

return new ActiveXObject('Wscript.Shell')
} // VtCreateWScriptShell method

function VtCreateXmlDocument() {
// Return an XML document

var oDoc = new ActiveXObject('MSXML2.DOMDocument')
oDoc.async = false
oDoc.setProperty('SelectionLanguage', 'XPath')
// Not necessary, since the following line is the default
// Set oNode = oDoc.createProcessingInstruction ('xml', 'version=''1.0'' encoding=''UTF-8''')
// o Doc.appendChild(oNode)
return oDoc
} // VtCreateXmlDocument method

function VtDateToJs(dt) {
// Convert a variant date to JScript

return Date.parse(dt)
} // VtDateToJs method

function VtDictionaryToJs(d) {
// Convert a variant dictionary to JScript

var aKeys = d.Keys()
var a = VtArrayToJs(aKeys)
var dReturn = {}
for (var i = 0; i < a.length; i++) {
var sKey = a[i]
dReturn[sKey] = d.Item(sKey)
}
return dReturn
} // VtDictionaryToJs method

function VtDictionaryKeysToJs(d) {
// Convert variant array of dictionary keys to JScript array

var a = VtArrayToJs(d.Keys())
return a
} // VtDictionaryKeysToJs method

function VtDictionaryKeysToList(d) {
// Convert variant array of dictionary keys to list

var l = VtArrayToList(d.Keys())
return l
} // VtDictionaryKeysToList method

function VtDictionaryToXml(dItems, sFile) {
// Save dictionary to XML file

var d = VtDictionaryToJs(dItems)
for (var sKey in d) {
var sValue = d[sKey]
XmlSetValue(sFile, sKey, sValue)
}
} // VtDictionaryToXml method

function VtEvalVbs(sCode, dParams) {
// Evaluate VBScript code and return the result

var oScript = VtCreateVBScriptControl()
oScript.AddObject('d', dParams)
var vReturn = oScript.Eval(sCode)
oScript = null
return vReturn
} // VtEvalVbs method

function VtEvalVbsParam(sCode, vParam) {
// Evaluate VBScript code and return result, passing single argument

var dParams = VtInitDictionary(vParam)
var vReturn = VtEvalVbs(sCode, dParams)
dParams = null
return vReturn
} // VtEvalVbsParam method

function VtGetWMIObject() {
// Get WMI object

return GetObject('winmgmts:{impersonationLevel=impersonate}!\\\\.\\root\\default:StdRegProv')
} // VtGetWMIObject method

function VtInitDictionary(vValue) {
// Create a variant dictionary and initialize it with a single key/value pair

var dReturn = VtCreateDictionary()
dReturn.Add('v', vValue)
return dReturn
} // VtInitDictionary method

function VtInitXmlDocument(sXml) {
// Create and initialize an Xml document with a string of XML

var oDoc = VtCreateXmlDocument()
oDoc.loadXML(sXml)
return oDoc
} // VtInitXmlDocument method

function VtListFilterByExtension(lPaths, lExtensions) {
// Get a subset from a list of paths that match an extension

var lReturn = VtCreateList()
for (var i = 0; i < lPaths.Count; i++) {
var sPath = lPaths(i)
var sExtension = PathGetExtension(sPath)
if (StringStartsWith(sPath, '.', false)) sExtension = StringChopLeft(sExtension, 1)
sExtension = sExtension.toLowerCase()
if (lExtensions.Contains(sExtension)) lReturn.Add(sPath)
}
return lReturn
} // VtFilterByExtension method

function VtListFilterByRegExp(lItems, sMatch, bIgnoreCase) {
// Return list of matches of a regular expression

var lReturn = VtCreateList()
for (var i = 0; i < lItems.Count; i++) {
var sItem = lItems(i)
if (RegExpTest(sItem, sMatch, bIgnoreCase)) lReturn.Add(sItem)
}
return lReturn
} // VtListFilterByRegExp method

function VtListFilterByWildcard(lItems, sMatch) {
// Return list of matches of a wildcard filter expression

var lReturn = VtCreateList()
if (!lItems) return lReturn

var oRs = VtCreateRecordSet()
var oFields = oRs.Fields
oFields.Append('Item', adVarWChar, xMaxPath)
oRs.Open()

for (var i = 0; i < lItems.Count; i++) {
var sItem = lItems(i)
oRs.AddNew('Item', sItem)
}
oRs.Update()

oRs.Filter = "Item Like '" + sMatch + "'"
var oField = oFields('Item')
if (!oRs.BOF) oRs.MoveFirst()
while (!oRs.EOF) {
var sValue = oField.Value
lReturn.Add(sValue)

oRs.MoveNext()
}
oRs.Close()

oField = null
oFields = null
oRs = null
return lReturn
} // VtListFilterByWildcard method


function VtListGetExtensions(lPaths) {
// Get a list of extensions from a list of paths, converting to lower case, removing duplicates, and sorting

var lReturn = VtCreateList()
for (var i = 0; i < lPaths.Count; i++) {
var sPath = lPaths(i)
var sExtension = PathGetExtension(sPath)
if (StringStartsWith(sPath, '.', false)) sExtension = StringChopLeft(sExtension, 1)
if (!sExtension) continue
sExtension = sExtension.toLowerCase()
if (lReturn.Contains(sExtension)) continue
lReturn.Add(sExtension)
}
lReturn.Sort()
return lReturn
} // VtListGetExtensions method

function VtListToJs(l) {
// Convert variant list to JScript array

var aReturn = []
for (var i = 0; i < l.Count; i++) aReturn[i] = l.Item(i)
return aReturn
} // VtListToJs method

function VtListToString(lItems, sDelimiter) {
// Convert a list to a string with a specified delimiter

var sReturn = xMute
for (var i = 0; i < lItems.Count; i++) {
var oItem = lItems(i)
var sItem = JsString(oItem)
if (i > 0) sReturn += sDelimiter
sReturn += sItem
}
return sReturn
} // VtListToStringMethod

function StringReplace(sText, sMatch, sReplace, bIgnoreCase) {
// Replace text

var iCompare
if (bIgnoreCase) iCompare = vbTextCompare
else iCompare = vbBinaryCompare
var sCode = 'Replace(d("Text"), d("Match"), d("Replace"), 1, -1, d("Compare"))'
var dParams = VtCreateDictionary()
dParams.Add('Text', sText)
dParams.Add('Match', sMatch)
dParams.Add('Replace', sReplace)
dParams.Add('Compare', iCompare)
return VtEvalVbs(sCode, dParams)
} // StringReplace method

function VtSleep(iMilliseconds) {
var sCode = 'Sleep(d("v"))'
return VtEvalVbsParam(sCode, iMilliseconds)
} // VtSleep method

function VtStreamToFile(aBytes, sFile) {
// Save a variant byte array to a binary file

try {
var oStream = VtCreateStream()
oStream.Write(aBytes)
oStream.SaveToFile(sFile, adSaveCreateOverWrite)
oStream.Close()
}
catch (e) {
DialogShow('Error', e.description)
}
oStream = null
return FileExists(sFile)
} // VtStreamToFile method

function VtTrim(sText) {
// Trim space from both ends of a string

var sCode = 'Trim(d("v"))'
return VtEvalVbsParam(sCode, sText)
} // VtTrim method

function VtTypeName(vVariant) {
// Get variant subtype

var sCode = 'TypeName(d("v"))'
return VtEvalVbsParam(sCode, vVariant)
} // VtTypeName method

function WebListDownload(lUrls, sFolder, bUnique) {
// Download a list of URLs, specifying folder and whether to ensure unique file names

for (var i = 0; i < lUrls.Count; i++) {
var sUrl = lUrls(i)
var sFile = WebUrlDownloadPath(sUrl, sFolder, bUnique)
JsPrint(sFile)
WebUrlToFile(sUrl, sFile)
}
} // WebListDonload method

function WebFetch(dParams) {
// Fetch files from web according to specifications in dictionary of parameters

/*
SearchScope values:
Path, with same directory and subdomain
Subdomain, with any directory
Domain, with any directory or subdomain
Other, restricted by filters or additional limits
*/

if (!dParams.Exists('LinkSegment')) dParams('LinkSegment') = 1
if (!dParams.Exists('TimeLimit')) dParams('TimeLimit') = 0
if (!dParams.Exists('TimeStart')) dParams('TimeStart') = (new Date()).getTime()
if (!dParams.Exists('MaximumSize')) dParams('MaximumSize') = 0
if (!dParams.Exists('TotalSize')) dParams('TotalSize') = 0
if (!dParams.Exists('EventLog')) dParams('EventLog') = xMute
if (!dParams.Exists('CrawlUrls')) dParams('CrawlUrls') = VtCreateList()
if (!dParams.Exists('FetchUrls')) dParams('FetchUrls') = VtCreateList()

var iNow = (new Date()).getTime()
var iDelta = iNow - dParams('TimeStart')

if ((dParams('TimeLimit') > 0) && (iDelta > dParams('TimeLimit'))) {
sReturn += 'Time limit of ' + StringCount('minute', iDelta / Math.pow(60, 2)) + ' exceeded' + '\n'
return dParams
}

if ((dParams('MaximumSize') > 0) && (dParams('TotalSize') > dParams('MaximumSize'))) {
sReturn += 'Maximum size of ' + StringCount('megabyte', d('MaximumSize') / Math.pow(1024, 2)) + ' exceeded' + '\n'
return dParams
}

var sReturn = 'Parameters:' + '\n'
var d = VtDictionaryToJs(dParams)
for (var sKey in d)  sReturn += sKey +'=' + d[sKey] + '\n'
sReturn += '\n'

var sProjectFolder = d['ProjectFolder']
var bIncludeSubfolders = d['IncludeSubfolders']
var bUniquePath = true
if (bIncludeSubfolders) bUniquePath = false
var sSearchScope = d['SearchScope']
var bQueryOnly = d['QueryOnly']

var aBodyFilters = JsSplitLines(d['BodyFilters'])
var aIncludeBodyFilters = []
var aExcludeBodyFilters = []
for (var iBodyFilter = 0; iBodyFilter < aBodyFilters.length; iBodyFilter++) {
var sBodyFilter = aBodyFilters[iBodyFilter]
if (!sBodyFilter) continue
if (StringStartsWith(sBodyFilter, '-', false)) {
sBodyFilter = StringChopLeft(sBodyFilter, 1)
aExcludeBodyFilters.push(sBodyFilter)
}
else {
if (StringStartsWith(sBodyFilter, '+', false)) sBodyFilter = StringChopLeft(sBodyFilter, 1)
aIncludeBodyFilters.push(sBodyFilter)
}
} // create BodyFilter arrays

var aUrlFilters = JsSplitLines(d['UrlFilters'])
var aIncludeUrlFilters = []
var aExcludeUrlFilters = []
for (var iUrlFilter = 0; iUrlFilter < aUrlFilters.length; iUrlFilter++) {
var sUrlFilter = aUrlFilters[iUrlFilter]
if (!sUrlFilter) continue
if (StringStartsWith(sUrlFilter, '-', false)) {
sUrlFilter = StringChopLeft(sUrlFilter, 1)
aExcludeUrlFilters.push(sUrlFilter)
}
else {
if (StringStartsWith(sUrlFilter, '+', false)) sUrlFilter = StringChopLeft(sUrlFilter, 1)
aIncludeUrlFilters.push(sUrlFilter)
}
} // create URL filter arrays

var aWebSource = JsSplitLines(d['WebSource'])
sReturn += 'Fetching' +'\n'
for (var iWebSource = 0; iWebSource < aWebSource.length; iWebSource++) {
var sWebSource = aWebSource[iWebSource]
if (!sWebSource) continue
if (dParams('FetchUrls').Contains(sWebSource)) continue
sReturn += 'Web source ' + sWebSource + '\n'
var bIncludeWebSource = true
for (var iExcludeUrlFilter = 0; iExcludeUrlFilter < aExcludeUrlFilters.length; iExcludeUrlFilter++) {
var sExcludeUrlFilter = aExcludeUrlFilters[iExcludeUrlFilter]
if (!sExcludeUrlFilter) continue
if (RegExpTest(sWebSource, sExcludeUrlFilter, true)) {
bIncludeWebSource = false
sReturn += 'No fetch from exclude URL filter ' + sExcludeUrlFilter + '\n'
break
}
} // Test exclude URL filters
if (!bIncludeWebSource) continue

if (aIncludeUrlFilters.length) bIncludeWebSource = false
for (var iIncludeUrlFilter = 0; iIncludeUrlFilter < aIncludeUrlFilters.length; iIncludeUrlFilter++) {
var sIncludeUrlFilter = aIncludeUrlFilters[iIncludeUrlFilter]
if (!sIncludeUrlFilter) continue
if (RegExpTest(sWebSource, sIncludeUrlFilter, true)) {
bIncludeWebSource = true
sReturn += 'Fetch from include URL filter ' + sIncludeUrlFilter + '\n'
break
}
} // Test include URL filters
if (!bIncludeWebSource) continue

var sFolder = UrlGetFolder(sWebSource)
if (bIncludeSubfolders && sFolder) sFolder = PathCombine(sProjectFolder, sFolder)
var sFile = WebUrlDownloadPath(sWebSource, sFolder, bUniquePath)
dParams('FetchUrls').Add(sWebSource)
if (bQueryOnly) continue
else if (WebUrlToFile(sWebSource, sFile)) {
sReturn += 'Download ' + sFile + '\n'
var iSize = FileGetSize(sFile)
d('TotalSize') += iSize
}
else sReturn += 'Cannot download ' + sFile + '\n'
} // Fetch web sources
if (d['LinkSegment'] >= d['LinkDistance']) return sReturn

sReturn += 'Crawling' + '\n'
for (var iWebSource = 0; iWebSource < aWebSource.length; iWebSource++) {
var sWebSource = aWebSource[iWebSource]
if (!sWebSource) continue
if (dParams('CrawlUrls').Contains(sWebSource)) continue
if (!WebUrlIsHtml(sWebSource)) continue
dParams('CrawlUrls').Add(sWebSource)
sReturn += 'HTML ' + sWebSource + '\n'
var sBody = HtmlGetText(sWebSource)

var bIncludeWebSource = true
for (var iExcludeBodyFilter = 0; iExcludeBodyFilter < aExcludeBodyFilters.length; iExcludeBodyFilter++) {
var sExcludeBodyFilter = aExcludeBodyFilters[iExcludeBodyFilter]
if (!sExcludeBodyFilter) continue
if (RegExpTest(sBody, sExcludeBodyFilter, true)) {
bIncludeWebSource = false
sReturn += 'No crawl from exclude body filter ' + sExcludeBodyFilter + '\n'
break
}
} // Test exclude body filters
if (!bIncludeWebSource) continue

if (aIncludeBodyFilters.length) bIncludeWebSource = false
for (var iIncludeBodyFilter = 0; iIncludeBodyFilter < aIncludeBodyFilters.length; iIncludeBodyFilter++) {
var sIncludeBodyFilter = aIncludeBodyFilters[iIncludeBodyFilter]
if (!sIncludeBodyFilter) continue
if (RegExpTest(sBody, sIncludeBodyFilter, true)) {
bIncludeWebSource = true
sReturn += 'Crawl from include body filter ' + sIncludeBodyFilter + '\n'
break
}
} // Test include body filters
if (!bIncludeWebSource) continue

var lLinkUrls = HtmlGetUrls(sWebSource)
for (var iLinkUrl = 0; iLinkUrl < lLinkUrls.Count; iLinkUrl++) {
var sLinkUrl = lLinkUrls(iLinkUrl)
sReturn += 'Link URL ' + sLinkUrl + '\n'
if (StringEquiv(sSearchScope, 'Path') && !(StringEquiv(UrlGetHost(sWebSource), UrlGetHost(sLinkUrl)) && StringEquiv(UrlGetFolder(sWebSource), UrlGetFolder(sLinkUrl)))) {
sReturn += 'No crawl from search scope ' + sSearchScope + '\n'
continue
}
else if (StringEquiv(sSearchScope, 'Subdomain') && !StringEquiv(UrlGetHost(sWebSource), UrlGetHost(sLinkUrl))) {
sReturn += 'No crawl from search scope ' + sSearchScope + '\n'
continue
}
else if (StringEquiv(sSearchScope, 'Domain') && !StringEquiv(UrlGetBaseDomain(sWebSource) , UrlGetBaseDomain(sLinkUrl))) {
sReturn += 'No crawl from search scope ' + sSearchScope + '\n'
continue
}

var dCopy = VtCopyDictionary(dParams)
dCopy('WebSource') = sLinkUrl
dCopy('LinkSegment')++
var dReturn = WebFetch(dCopy)
if (JsIsObject(dReturn)) {
sReturn += dReturn('EventLog') + '\n'
dParams('TotalSize') = dReturn('TotalSize')
dParams('CrawlUrls') = dReturn('CrawlUrls')
dParams('FetchUrls') = dReturn('FetchUrls')
sReturn += '\n'
}
} // Iterate LinkURLs
} // Iterate web sources
dParams('EventLog') = sReturn
return dParams
} // WebFetch method

function WebRequest(sType, sUrl, dData, dHeaders, sUser, sPassword) {
// Send a web request and return the response

var sType = sType.toUpperCase()
var sData = null
if (JsIsObject(dData)) {
var d = VtDictionaryToJs(dData)
sData = JsDictionaryToEncodedString(d)
}

if (sType == 'GET' && sData) sUrl += '?' + sData
var oRequest = VtCreateWebRequest()
try {
oRequest.open(sType, sUrl, false, sUser, sPassword)
}
catch (e) {
return null
}
oRequest.setRequestHeader('User-Agent', 'HomerJax')
if (sType == 'POST') oRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')

if (JsIsObject(dHeaders)) {
var d = VtDictionaryToJs(dHeaders)
for (var sKey in d) {
var sValue = d[sKey]
oRequest.setRequestHeader(sKey, sValue)
}
}

try {
if (sType == 'POST') {
oRequest.send(sData)
}
else oRequest.send()
}
catch (e) {
// DialogShow('Error', e.description)
}
return oRequest
} // WebRequest method

function WebRequestGet(sUrl, dData, dHeaders, sUser, sPassword) {
// Send a get request

return WebRequest('GET', sUrl, dData, dHeaders, sUser, sPassword)
} // WebRequestGet method

function WebRequestGetToFile(sUrl, dData, dHeaders, sUser, sPassword, sFile) {
// Send a get request and save response to file

return WebRequestToFile('GET', sUrl, dData, dHeaders, sUser, sPassword, sFile)
} // WebRequestGetToFile method

function WebRequestGetToString(sUrl, dData, dHeaders, sUser, sPassword) {
// Send a get request and return response as string

return WebRequestToString('GET', sUrl, dData, dHeaders, sUser, sPassword)
} // WebRequestGetToString method

function WebRequestHead(sUrl, dData, dHeaders, sUser, sPassword) {
// Send a head request

return WebRequest('HEAD', sUrl, dData, dHeaders, sUser, sPassword)
} // WebRequestHead method

function WebRequestHeader(sUrl, sHeader) {
// Get response header

var dData = null
var dHeaders = null
var sUser = null
var sPassword = null

var oRequest = WebRequestHead(sUrl, dData, dHeaders, sUser, sPassword)
var sReturn = xMute
try {sReturn = oRequest.getResponseHeader(sHeader)}
catch (e) {}

oRequest = null
return sReturn
} // WebRequestHeader method

function WebRequestPost(sUrl, dData, dHeaders, sUser, sPassword) {
// Send a post request

return WebRequest('POST', sUrl, dData, dHeaders, sUser, sPassword)
} // WebRequestPost method

function WebRequestPostToFile(sUrl, dData, dHeaders, sUser, sPassword, sFile) {
// Send a post request and save response to file

return WebRequestToFile('POST', sUrl, dData, dHeaders, sUser, sPassword, sFile)
} // WebRequestPostToFile method

function WebRequestPostToString(sUrl, dData, dHeaders, sUser, sPassword) {
// Send a post request and return response as string

return WebRequestToString('POST', sUrl, dData, dHeaders, sUser, sPassword)
} // WebRequestPostToString method

function WebRequestToFile(sType, sUrl, dData, dHeaders, sUser, sPassword, sFile) {
// Save web resource to file

var oRequest = WebRequest(sType, sUrl, dData, dHeaders, sUser, sPassword)
var aBytes = oRequest.responseBody
var bReturn = VtStreamToFile(aBytes, sFile)
oRequest = null
return bReturn
} // WebRequestToFile method

function WebRequestToString(sType, sUrl, dData, dHeaders, sUser, sPassword) {
// Return web resource as string

var oRequest = WebRequest(sType, sUrl, dData, dHeaders, sUser, sPassword)
var sReturn = oRequest.responseText
oRequest = null
return sReturn
} // WebRequestToString method

function WebUrlContentLength(sUrl){
// Get content length of a web resource

var sHeader = 'content-length'
var sReturn = WebRequestHeader(sUrl, sHeader)
return sReturn
} // WebUrlContentLength method

function WebUrlContentLocation(sUrl){
// Get redirected location of a web resource

var sHeader = 'Content-Location'
var sReturn = WebRequestHeader(sUrl, sHeader)
return sReturn
} // WebUrlContentLocation method

function WebUrlContentLanguage(sUrl){
// Get natural language code of a web resource

var sHeader = 'Content-Language'
var sReturn = WebRequestHeader(sUrl, sHeader)
return sReturn
} // WebUrlContentLanguage method

function WebUrlContentEncoding(sUrl){
// Get encoding of a web resource

var sHeader = 'Content-Encoding'
var sReturn = WebRequestHeader(sUrl, sHeader)
return sReturn
} // WebUrlContentEncoding method

function WebUrlLastModified(sUrl){
// Get last modification time stamp of a web resource

var sHeader = 'LastModified'
var sReturn = WebRequestHeader(sUrl, sHeader)
return sReturn
} // WebUrlLastModified method

function WebUrlServer(sUrl){
// Get server name and version

var sHeader = 'Server'
var sReturn = WebRequestHeader(sUrl, sHeader)
return sReturn
} // WebUrlServer method

function WebUrlContentType(sUrl){
// Get content type of a web resource

var sHeader = 'content-type'
var sReturn = WebRequestHeader(sUrl, sHeader)
return sReturn
} // WebUrlContentType method

function WebUrlFileName(sUrl){
// Get suggested file name of a web resource

var sHeader = 'content-disposition'
var sReturn = WebRequestHeader(sUrl, sHeader)
var aParts = sReturn.split('=')
var iLength = aParts.length
sReturn = aParts[iLength - 1]
sReturn = VtTrim(sReturn)
return sReturn
} // WebUrlFileName method

function WebUrlIsHtml(sUrl) {
// Test whether content type is text/html

var sType = WebUrlContentType(sUrl)
return StringStartsWith(sType, 'text/html', true)
} // WebUrlIsHtml method

function WebUrlToFile(sUrl, sFile) {
// Save web resource to file

var dData = null
var dHeaders = null
var sUser = null
var sPassword = null

return WebRequestGetToFile(sUrl, dData, dHeaders, sUser, sPassword, sFile)
} // WebUrlToFile method

function WebUrlToString(sUrl) {
// Return web resource as string

var dData = null
var dHeaders = null
var sUser = null
var sPassword = null

return WebRequestGetToString(sUrl, dData, dHeaders, sUser, sPassword)
} // WebUrlToString method

function WebUrlToXml(sUrl) {
// Return web resource as XML document

var dData = null
var dHeaders = null
var sUser = null
var sPassword = null

var sText = WebUrlToString(sUrl)
var oDoc = VtCreateXmlDocument()
oDoc.loadXML(sText)
return oDoc
} // WebUrlToXml method

function XmlAppendElement(oParent, sName, sValue) {
// Append element to a node

var oChild = XmlCreateElement(oParent, sName, sValue)
oParent.appendChild(oChild)
return oChild
} // XmlAppendElement method

function XmlCreateElement(oNode, sName, sValue) {
// Create an XML element

var oChild = null
if (JsIsUndefined(sValue)) sValue = null
if (JsIsObject(oNode)) {
var oDoc
if (VtTypeName(oNode) == 'DOMDocument') oDoc = oNode
else oDoc = oNode.ownerDocument

var oChild = oDoc.createElement(sName)
if (!JsIsNull(sValue)) {
var oData = oDoc.createCDATASection(sValue)
oChild.appendChild(oData)
}
}

oDoc = null
return oChild
} // XmlCreateElement method

function XmlCreateFile(sFile) {
// Create a root XML file

var oDoc = VtCreateXmlDocument()
XmlAppendElement(oDoc, 'Root', null)
FileDelete(sFile)
oDoc.save(sFile)
return oDoc
} // XmlCreateFile method

function XmlEnsureGetNode(sFile, sPath) {
// Return a node, creating preceding elements if necessary

var oNode = null
var oDoc
if (JsIsObject(sFile)) oDoc = sFile
else oDoc = XmlEnsureOpenFile(sFile)

if (JsIsObject(oDoc)) {
var oParent
if (VtTypeName(oDoc) == 'DOMDocument') oParent = oDoc.documentElement
else oParent = oDoc

var oNode
if (!sPath.length) oNode = oParent
else {
oNode = XmlGetNode(oParent, sPath)
if (JsIsNull(oNode)) {
var aNames = sPath.split('/')
var sName = aNames.pop()
var sPath = aNames.join('/')
oParent = XmlEnsureGetNode(oDoc, sPath)
oNode = XmlAppendElement(oParent, sName, null)
}
}
}

oParent = null
oDoc = null
return oNode
} // XmlEnsureGetNode method

function XmlEnsureOpenFile(sFile) {
// Open an XML file, creating it if necessary

var oDoc = XmlOpenFile(sFile)
if (JsIsNull(oDoc)) oDoc = XmlCreateFile(sFile)
return oDoc
} // XmlEnsureOpenFile method

function XmlGetAttribute(sFile, sPath, sAttribute, sDefault) {
// Get an attribute of a node

var sReturn = sDefault
if (JsIsUndefined(sReturn)) sReturn = null
var oDoc
if (JsIsObject(sFile)) oDoc = sFile
else oDoc = XmlOpenFile(sFile)

if (JsIsObject(oDoc)) {
var oParent
if (VtTypeName(oDoc) == 'DOMDocument') oParent = oDoc.documentElement
else oParent = oDoc

var oNode = oParent.selectSingleNode(sPath)
if (JsIsObject(oNode)) {
var sText = oNode.getAttribute(sAttribute)
if (sText != null) sReturn = sText
}
}

oNode = null
oParent = null
oDoc = null
return sReturn
} // XmlGetAttribute method

function XmlGetNode(sFile, sPath) {
// Get a node

var oNode = null
var oDoc
if (JsIsObject(sFile)) oDoc = sFile
else oDoc = XmlOpenFile(sFile)

if (JsIsObject(oDoc)) {
var oParent
if (VtTypeName(oDoc) == 'DOMDocument') oParent = oDoc.documentElement
else oParent = oDoc

var oNode = oParent.selectSingleNode(sPath)
}

oParent = null
oDoc = null
return oNode
} // XmlGetNode method

function XmlGetNodeNames(sFile, sPath) {
// Get node names

var lReturn = VtCreateList()
var oDoc
if (JsIsObject(sFile)) oDoc = sFile
else oDoc = XmlOpenFile(sFile)

if (JsIsObject(oDoc)) {
var oParent
if (VtTypeName(oDoc) == 'DOMDocument') oParent = oDoc.documentElement
else oParent = oDoc

var oNodes = oParent.selectNodes(sPath)
for (var i = 0; i < oNodes.length; i++) {
var oNode = oNodes.item(i)
lReturn.Add(oNode.nodeName)
}
}

oNode = null
oNodes = null
oParent = null
oDoc = null
return lReturn
} // XmlGetNodeNames method

function XmlGetNodes(sFile, sPath) {
// Get a node list

var lReturn = VtCreateList()
var oDoc
if (JsIsObject(sFile)) oDoc = sFile
else oDoc = XmlOpenFile(sFile)

if (JsIsObject(oDoc)) {
var oParent
if (VtTypeName(oDoc) == 'DOMDocument') oParent = oDoc.documentElement
else oParent = oDoc

var oNodes = oParent.selectNodes(sPath)
for (var i = 0; i < oNodes.length; i++) {
var oNode = oNodes.item(i)
lReturn.Add(oNode)
}
}

oNode = null
oNodes = null
oParent = null
oDoc = null
return lReturn
} // XmlGetNodes method

function XmlGetValue(sFile, sPath, sDefault) {
// Get the value of a node

var sReturn = sDefault
if (JsIsUndefined(sReturn)) sReturn = null
var oDoc
if (JsIsObject(sFile)) oDoc = sFile
else oDoc = XmlOpenFile(sFile)

if (JsIsObject(oDoc)) {
var oParent
if (VtTypeName(oDoc) == 'DOMDocument') oParent = oDoc.documentElement
else oParent = oDoc

var oNode = oParent.selectSingleNode(sPath)
if (JsIsObject(oNode)) {
var sValue = oNode.nodeValue
if (sValue != null) sReturn = sValue
}
}

oNode = null
oParent = null
oDoc = null
return sReturn
} // XmlGetValue method

function XmlGetText(sFile, sPath, sDefault) {
// Get the text of a node

var sReturn = sDefault
if (JsIsUndefined(sReturn)) sReturn = null
var oDoc
if (JsIsObject(sFile)) oDoc = sFile
else oDoc = XmlOpenFile(sFile)

if (JsIsObject(oDoc)) {
var oParent
if (VtTypeName(oDoc) == 'DOMDocument') oParent = oDoc.documentElement
else oParent = oDoc

var oNode = oParent.selectSingleNode(sPath)
if (JsIsObject(oNode)) {
var sText = oNode.text
if (sText != null) sReturn = sText
}
}

oNode = null
oParent = null
oDoc = null
return sReturn
} // XmlGetText method

function XmlOpenFile(sFile) {
// Open an XML file

if (!FileExists(sFile)) return null

var oDoc = VtCreateXmlDocument()
try {
oDoc.load(sFile)
}
catch (e) {
oDoc = null
}
return oDoc
} // XmlOpenFile method

function XmlRemoveAttribute(sFile, sPath, sAttribute) {
// Remove an attribute

var oDoc
if (JsIsObject(sFile)) oDoc = sFile
else oDoc = XmlOpenFile(sFile)

if (JsIsObject(oDoc)) {
var oParent
if (VtTypeName(oDoc) == 'DOMDocument') oParent = oDoc.documentElement
else oParent = oDoc

var oNode = oParent.selectSingleNode(sPath)
if (JsIsObject(oNode)) {
oNode.removeAttribute(sAttribute)
oDoc.save(sFile)
}
}

oNode = null
oParent = null
oDoc = null
} // XmlRemoveAttribute method

function XmlRemoveNode(sFile, sPath) {
// Remove a node

var oDoc
if (JsIsObject(sFile)) oDoc = sFile
else oDoc = XmlOpenFile(sFile)

if (JsIsObject(oDoc)) {
var oParent
if (VtTypeName(oDoc) == 'DOMDocument') oParent = oDoc.documentElement
else oParent = oDoc

var oNode = oParent.selectSingleNode(sPath)
if (JsIsObject(oNode)) {
oParent = oNode.parentNode
oParent.removeChild(oNode)
oDoc.save(sFile)
}
}

oNode = null
oParent = null
oDoc = null
} // XmlRemoveNode method

function XmlRemoveNodes(sFile, sPath) {
// Remove a node collection

var oDoc
if (JsIsObject(sFile)) oDoc = sFile
else oDoc = XmlOpenFile(sFile)

if (JsIsObject(oDoc)) {
var oParent
if (VtTypeName(oDoc) == 'DOMDocument') oParent = oDoc.documentElement
else oParent = oDoc

var oNodes = oParent.selectNodes(sPath)
if (oNodes.length) {
var oParent = oNodes.firstChild.parentNode
for (var i = oNodes.length - 1; i >= 0; i--) {
var oNode = oNodes.item(i)
oParent.removeChild(oNode)
}
oDoc.save(sFile)
}
}

oNode = null
oNodes = null
oParent = null
oDoc = null
} // XmlRemoveNodes method

function XmlSetAttribute(sFile, sPath, sAttribute, sText) {
// Set an attribute

var oNode = XmlEnsureGetNode(sFile, sPath)
if (JsIsObject(oNode)) {
oNode.setAttribute(sAttribute, sText)
var oDoc
if (VtTypeName(oNode) == 'DOMDocument') oDoc = oNode
else oDoc = oNode.ownerDocument
if (!JsIsObject(sFile)) oDoc.save(sFile)
}

oNode = null
oDoc = null
return (XmlGetAttribute(sFile, sPath, sAttribute, null) == sText)
} // XmlSetAttribute method

function XmlSetText(sFile, sPath, sText) {
// Set text of an element

return XmlSetText(sFile, sPath, sText) 
} // XmlSetText method

function XmlSetValue(sFile, sPath, sValue) {
// Set a value

var oNode = XmlEnsureGetNode(sFile, sPath)
if (JsIsObject(oNode)) {
var aNames = sPath.split('/')
var sName = aNames.pop()

var oDoc
if (VtTypeName(oNode) == 'DOMDocument') oDoc = oNode
else oDoc = oNode.ownerDocument
var oNew = XmlCreateElement(oDoc, sName, sValue)
var oAttributes = oNode.attributes
for (var i = 0; i < oAttributes.length; i++) {
var oAttribute = oAttributes.item(i)
var sAttribute = oAttribute.nodeName
var sText = oNode.getAttribute(sAttribute)
oNew.setAttribute(sAttribute, sText)
}
var oParent = oNode.parentNode
oParent.replaceChild(oNew, oNode)
if (!JsIsObject(sFile)) oDoc.save(sFile)
}

oNew = null
oNode = null
oDoc = null
return (XmlGetValue(sFile, sPath, null) == sValue)
} // XmlSetValue method

function XmlToVtDictionary(sFile) {
// Convert XML file to variant dictionary

var dReturn = VtCreateDictionary()
var oNodes = XmlGetNodes(sFile, '*')
for (var i = 0; i < oNodes.length; i++) {
var oNode = oNodes.item(i)
var sName = oNode.nodeName
var sValue = oNode.text
dReturn(sName) = sValue
}
return dReturn
} // XmlToVtDictionary method
// } // HomerJax class

function HomerJax() {
// Constructor for HomerJax object

this.DialogConfirm=DialogConfirm
this.DialogInput=DialogInput
this.DialogShow=DialogShow
this.FileCopy=FileCopy
this.FileDelete=FileDelete
this.FileExists=FileExists
this.FileGetDate=FileGetDate
this.FileGetSize=FileGetSize
this.FileGetType=FileGetType
this.FileMove=FileMove
this.FileToString=FileToString
this.FolderCopy=FolderCopy
this.FolderCreate=FolderCreate
this.FolderDelete=FolderDelete
this.FolderExists=FolderExists
this.FolderGetDate=FolderGetDate
this.FolderGetSize=FolderGetSize
this.FolderMove=FolderMove
this.HtmlEncodeString=HtmlEncodeString
this.HtmlGetLinks=HtmlGetLinks
this.HtmlGetUrls=HtmlGetUrls
this.HtmlGetText=HtmlGetText
this.HtmlGetTableText=HtmlGetTableText
this.JsDictionaryToEncodedString=JsDictionaryToEncodedString
this.JsDictionaryToVt=JsDictionaryToVt
this.JsEval=JsEval
this.JsInspectObject=JsInspectObject
this.JsIsBlank=JsIsBlank
this.JsIsMute=JsIsMute
this.JsIsNull=JsIsNull
this.JsIsObject=JsIsObject
this.JsIsUndefined=JsIsUndefined
this.JSNumber=JSNumber
this.JsObjectToVt=JsObjectToVt
this.JsPrint=JsPrint
this.JsPrintObject=JsPrintObject
this.JsSplit=JsSplit
this.JsSplitLines=JsSplitLines
this.JsString=JsString
this.JsToVt=JsToVt
this.PathCombine=PathCombine
this.PathCreateTempFolder=PathCreateTempFolder
this.PathExists=PathExists
this.PathGetBase=PathGetBase
this.PathGetCurrentDirectory=PathGetCurrentDirectory
this.PathGetExtension=PathGetExtension
this.PathGetFolder=PathGetFolder
this.PathGetInternetCacheFolder=PathGetInternetCacheFolder
this.PathGetLong=PathGetLong
this.PathGetName=PathGetName
this.PathGetShort=PathGetShort
this.PathGetSpec=PathGetSpec
this.PathGetTempFile=PathGetTempFile
this.PathGetTempFolder=PathGetTempFolder
this.PathGetTempName=PathGetTempName
this.PathGetValid=PathGetValid
this.PathSetCurrentDirectory=PathSetCurrentDirectory
this.RegExpContains=RegExpContains
this.RegExpContainsLast=RegExpContainsLast
this.RegExpCount=RegExpCount
this.RegExpExtract=RegExpExtract
this.RegExpReplace=RegExpReplace
this.RegExpTest=RegExpTest
this.RegistryGetString=RegistryGetString
this.RegistryRead=RegistryRead
this.RegistrySetString=RegistrySetString
this.RegistryWrite=RegistryWrite
this.ShellCreateShortcut=ShellCreateShortcut
this.ShellExec=ShellExec
this.ShellExecute=ShellExecute
this.ShellExpandEnvironmentVariables=ShellExpandEnvironmentVariables
this.ShellGetEnvironmentVariable=ShellGetEnvironmentVariable
this.ShellGetShortcutTargetPath=ShellGetShortcutTargetPath
this.ShellGetSpecialFolder=ShellGetSpecialFolder
this.ShellInvokeVerb=ShellInvokeVerb
this.ShellOpen=ShellOpen
this.ShellOpenWith=ShellOpenWith
this.ShellRun=ShellRun
this.ShellRunCommandPrompt=ShellRunCommandPrompt
this.ShellRunExplorerWindow=ShellRunExplorerWindow
this.ShellWait=ShellWait
this.StringAppendToFile=StringAppendToFile
this.StringChomp=StringChomp
this.StringChopLeft=StringChopLeft
this.StringChopRight=StringChopRight
this.StringContains=StringContains
this.StringConvertToMacLineBreak=StringConvertToMacLineBreak
this.StringConvertToUnixLineBreak=StringConvertToUnixLineBreak
this.StringConvertToWinLineBreak=StringConvertToWinLineBreak
this.StringCount=StringCount
this.StringEndsWith=StringEndsWith
this.StringEqual=StringEqual
this.StringEquiv=StringEquiv
this.StringGetASCII=StringGetASCII
this.StringLeft=StringLeft
this.StringLength=StringLength
this.StringLower=StringLower
this.StringPlural=StringPlural
this.StringQuote=StringQuote
this.StringReplaceAll=StringReplaceAll
this.StringRight=StringRight
this.StringSlice=StringSlice
this.StringStartsWith=StringStartsWith
this.StringToFile=StringToFile
this.StringToList=StringToList
this.StringTrim=StringTrim
this.StringTrimLeft=StringTrimLeft
this.StringTrimRight=StringTrimRight
this.StringUnquote=StringUnquote
this.StringUpper=StringUpper
this.StringWrap=StringWrap
this.UrlCreate=UrlCreate
this.WebUrlDownloadPath=WebUrlDownloadPath
this.UrlGetBaseDomain=UrlGetBaseDomain
this.UrlGetHost=UrlGetHost
this.UrlGetExtension=UrlGetExtension
this.UrlGetFile=UrlGetFile
this.UrlGetFolder=UrlGetFolder
this.UrlGetFragment=UrlGetFragment
this.UrlGetPath=UrlGetPath
this.UrlGetPathPlus=UrlGetPathPlus
this.UrlGetPrePath=UrlGetPrePath
this.UrlGetQuery=UrlGetQuery
this.UrlGetProtocol=UrlGetProtocol
this.UrlGetSubdomain=UrlGetSubdomain
this.UrlNormalize=UrlNormalize
this.VtArrayToJs=VtArrayToJs
this.VtArrayToList=VtArrayToList
this.VtCopyDictionary=VtCopyDictionary
this.VtCopyList=VtCopyList
this.VtCreateDictionary=VtCreateDictionary
this.VtCreateFileSystemObject=VtCreateFileSystemObject
this.VtCreateHtmlFile=VtCreateHtmlFile
this.VtCreateInternetExplorerApplication=VtCreateInternetExplorerApplication
this.VtCreateList=VtCreateList
this.VtCreateRecordSet=VtCreateRecordSet
this.VtCreateRegExp=VtCreateRegExp
this.VtCreateShellApplication=VtCreateShellApplication
this.VtCreateStream=VtCreateStream
this.VtCreateVBScriptControl=VtCreateVBScriptControl
this.VtCreateWebRequest=VtCreateWebRequest
this.VtCreateWScriptShell=VtCreateWScriptShell
this.VtCreateXmlDocument=VtCreateXmlDocument
this.VtDateToJs=VtDateToJs
this.VtDictionaryToJs=VtDictionaryToJs
this.VtDictionaryKeysToJs=VtDictionaryKeysToJs
this.VtDictionaryKeysToList=VtDictionaryKeysToList
this.VtDictionaryToXml=VtDictionaryToXml
this.VtEvalVbs=VtEvalVbs
this.VtEvalVbsParam=VtEvalVbsParam
this.VtGetWMIObject=VtGetWMIObject
this.VtInitDictionary=VtInitDictionary
this.VtInitXmlDocument=VtInitXmlDocument
this.VtListFilterByExtension=VtListFilterByExtension
this.VtListFilterByRegExp=VtListFilterByRegExp
this.VtListFilterByWildcard=VtListFilterByWildcard
this.VtListGetExtensions=VtListGetExtensions
this.VtListToJs=VtListToJs
this.VtListToString=VtListToString
this.StringReplace=StringReplace
this.VtSleep=VtSleep
this.VtStreamToFile=VtStreamToFile
this.VtTrim=VtTrim
this.VtTypeName=VtTypeName
this.WebListDownload=WebListDownload
this.WebFetch=WebFetch
this.WebRequest=WebRequest
this.WebRequestGet=WebRequestGet
this.WebRequestGetToFile=WebRequestGetToFile
this.WebRequestGetToString=WebRequestGetToString
this.WebRequestHead=WebRequestHead
this.WebRequestHeader=WebRequestHeader
this.WebRequestPost=WebRequestPost
this.WebRequestPostToFile=WebRequestPostToFile
this.WebRequestPostToString=WebRequestPostToString
this.WebRequestToFile=WebRequestToFile
this.WebRequestToString=WebRequestToString
this.WebUrlContentLength=WebUrlContentLength
this.WebUrlContentType=WebUrlContentType
this.WebUrlFileName=WebUrlFileName
this.WebUrlIsHtml=WebUrlIsHtml
this.WebUrlToFile=WebUrlToFile
this.WebUrlToString=WebUrlToString
this.XmlAppendElement=XmlAppendElement
this.XmlCreateElement=XmlCreateElement
this.XmlCreateFile=XmlCreateFile
this.XmlEnsureGetNode=XmlEnsureGetNode
this.XmlEnsureOpenFile=XmlEnsureOpenFile
this.XmlGetAttribute=XmlGetAttribute
this.XmlGetNode=XmlGetNode
this.XmlGetNodeNames=XmlGetNodeNames
this.XmlGetNodes=XmlGetNodes
this.XmlGetValue=XmlGetValue
this.XmlOpenFile=XmlOpenFile
this.XmlRemoveAttribute=XmlRemoveAttribute
this.XmlRemoveNode=XmlRemoveNode
this.XmlRemoveNodes=XmlRemoveNodes
this.XmlSetAttribute=XmlSetAttribute
this.XmlSetValue=XmlSetValue
this.XmlToVtDictionary=XmlToVtDictionary
} // HomerJax constructor


// Main routine
/*
try {
ClientInformation.ScriptName = "Homer JAX"
ClientInformation.ScriptVersion = "0.6"
ClientInformation.ScriptDescription = "Access Internet resources via JavaScript and XML"
// ClientInformation.ScriptHelp = "Homer JAX is a function library for getting, reading, and writing data from the Internet"
ClientInformation.ScriptHelp = function () {
var sChoice = DialogConfirm('Confirm', 'Run demo of HomerJax functionality?', 'N')
if (sChoice == 'Y') {
var sFile = PathCombine(ClientInformation.ScriptPath, 'HomerJaxDemo.vbs')
StartScript(sFile)
}
else {
var sFile = PathCombine(ClientInformation.ScriptPath, 'HomerJax.htm')
ShellOpen(sFile)
}
} // ScriptHelp anonymous function

SharedObjects.Register('org.NonvisualDevelopment.HomerJax', oJax)
}
catch (e) {}
*/

// var oJax = new HomerJax()
// oJax
