// BEGIN SECTION String_Reader

function default_cmp(p_x1, p_x2) 
/* Note that a==b?0 does not work for NAN */
{ return p_x1 == p_x2? 0: 
p_x1 < p_x2? -01: p_x2 < p_x1? +01: p_x1 == p_x1? -01: p_x2 == p_x2? +01: 0 
}

function StringReader(p_text) { this. m_text = p_text
this. m_pos = 0 }

function StringReader. prototype. read_token (p_sep) 
{ 
var 
a_text = this. m_text, a_pos = this. m_pos, 
a_next = a_text. indexOf(p_sep, this. m_pos)
if(a_next >= 0) { this. m_pos = a_next + 01
return a_text. substring(a_pos, a_next) }}

function StringReader. prototype. read_line () 
{ return this. read_token("\r") }

function StringReader. prototype. atEnd () 
{ return this. m_pos >= this. m_text. length }

function StringReader. prototype. read_word () 
{ while(!(this. atEnd())) { var a_word = this. read_token (" ")
if(a_word) return a_word }}

function StringReader. prototype. read_rest () 
{ var a_text = this. m_text, a_pos = this. m_pos
this. m_pos = a_text. length
return a_text. substring(a_pos)
}

// END SECTION String_Reader
// BEGIN SECTION HTML_Writer

function encodeNCR (p_text) 
{ var a_res = new Array(), a_len = p_text. length, an_ix = +0
for(; +an_ix < +a_len; ++an_ix) 
a_res[an_ix] = "&#" + p_text. charCodeAt(an_ix) + ";"
return a_res }

function open_tag(p_doc, p_tag) { p_doc. write("<")
p_doc. writeln(p_tag)
p_doc. writeln(">") }

function close_tag(p_doc, p_tag) { p_doc. write("<")
p_doc. write("/")
p_doc. writeln(p_tag)
p_doc. write(">") }

function HT_OL_Writer(p_doc) { this. m_doc = p_doc
this. m_pos = 0 }


function HT_OL_Writer. prototype. append (p_text) { 
var a_pos = this. m_pos, a_doc = this. m_doc
if(!a_pos) open_tag(a_doc, "OL")
open_tag(a_doc, "LI")
if(p_text) a_doc. writeln(p_text) 
this. m_pos = a_pos + 01 }

function HT_OL_Writer. prototype. close() 
{ if(this. m_pos) { close_tag(this. m_doc, "OL")
this. m_pos = 0 } }

function HT_Table_Writer (p_doc, p_col_names) { this. m_doc = p_doc
this. m_rows = 0
this. m_col_names = p_col_names }


function HT_Table_Writer. prototype. appendRow (p_text) { 
var a_rows = this. m_rows, a_doc = this. m_doc, 
l_col_names = this. m_col_names
if (!a_rows) { var an_ix
open_tag(a_doc, "TABLE")
if(l_col_names. length) { open_tag(a_doc, "THEAD")
open_tag(a_doc, "TR")
for(an_ix in l_col_names) { open_tag(a_doc, "TH")
a_doc. writeln(l_col_names[an_ix]) }} a_rows = +01 }
if(a_rows == +01 && p_text. length) open_tag(a_doc, "TBODY")
if(p_text. length) { open_tag(a_doc, "TR") 
++a_rows 
for(an_ix in p_text) { 
open_tag(a_doc, "TD", {title: l_col_names[an_ix]}) 
a_doc. writeln(p_text[an_ix]) }}
this. m_rows = a_rows }

function HT_Table_Writer. prototype. close () 
{ if(this. m_rows) { close_tag(this. m_doc, "TABLE")
this. m_rows = 0 } }


// END SECTION HTML_Writer
// BEGIN SECTION DOM_Utilities

function set_val_size (p_c, p_t) { var a_l = (p_t = p_t. toString()). length
if(a_l) p_c. size = a_l
p_c. value = p_t }

function set_val_size_nz (p_c, p_t) 
{ if (p_t) return set_val_size (p_c, p_t) }

function select_append(p_select, p_value, p_text) 
{ 
var an_ix = +p_select. selectedIndex, 
 l_opts = p_select. options
// alert(an_ix)
if(+an_ix != -01 && +an_ix < +l_opts. length) 
{ var an_opt = l_opts. item(+an_ix)
an_opt. value = p_value
an_opt. text = p_text } else { var an_opt = new Option()
an_opt. value = p_value
an_opt. text = p_text
p_select. add(an_opt) } 
if(an_ix != -01) p_select. selectedIndex = +an_ix + 01 
else p_select. selectedIndex = -01 }

function select_truncate (p_select) 
{ var an_ix = +p_select. selectedIndex
for(; +an_ix != -01; an_ix = +(p_select. selectedIndex = +an_ix)) 
p_select. remove (+an_ix)
}

// END SECTION DOM_Utilities
// BEGIN SECTION WMI_utilities

function locateWMI()
/* Fills the SELECT control with OPTIONS from WMI query. */ 
{ var a_cmd = document. activeElement. name 
if("LOCATE" == a_cmd) /* ?WMILOCATE Y */ {
var l_elts = this. elements, l_res = new Enumerator( 
 GetObject(l_elts. namedItem("MONIKER"). value). 
 ExecQuery(l_elts. namedItem("QUERY"). value)), 
 a_sel = l_elts. namedItem("RESULT")
if(l_res. atEnd()) /* ?NORESULTS Y */
l_elts. 
namedItem("RESULT"). value = "N/A"
else /* ?NORESULTS N */ { a_sel. selectedIndex = 0
for(; !l_res. atEnd(); l_res. moveNext()) /* @RESULTS */
{ var an_item = l_res. item() 
select_append(a_sel, an_item. Path_, an_item. ProgId) } /* @RESULTS X */ } 
/* ?NORESULTS */
l_elts. namedItem("SHOW"). disabled = false }
else /* ?WMILOCATE N */ { 
var l_elts = this. elements, a_sel = l_elts. namedItem("RESULT"),
 an_obj = GetObject(l_elts. namedItem("MONIKER"). value). 
 Get(
 l_elts. 
 namedItem("WMI-PATH"). 
 value = a_sel. options. item(a_sel. selectedIndex). value)
l_elts. namedItem("SERVER-PROGID"). value = an_obj. ProgId
l_elts. namedItem("SERVER-CLASSID"). value = an_obj. ComponentId } 
/* ?WMILOCATE */
return false
} /* !locateWMI X */

function findProgId() 
/* Finds a progId given a classId using WMI. */
{ var a_cmd = document. activeElement. name, l_elts = this. elements
if("ENTER-CLASSID" == a_cmd) /* ?ENTERCLASSID Y */
{ var an_obj = (
l_elts. namedItem("WMI-LOCATOR"). object. ConnectServer(). Get(
l_elts. 
namedItem("WMI-PATH"). 
value. replace("?", l_elts. namedItem("SERVER-CLASSID"). value)))
l_elts. namedItem("SERVER-CLASSID"). value = an_obj. ComponentId
l_elts. namedItem("SERVER-PROGID"). value = an_obj. ProgId } 
else /* ?ENTERCLASSID N */ if("ENTER-PROGID" == a_cmd) /* ?ENTERPROGID Y */
{ 
var l_serv = new Enumerator(
l_elts. 
namedItem("WMI-LOCATOR"). 
object. 
ConnectServer(). 
ExecQuery(
l_elts. 
namedItem("QUERY"). 
value. replace("?", l_elts. namedItem("SERVER-PROGID"). value)))
if(!l_serv. atEnd()) /* ?GOT_RESULTS Y */ {
for(; !l_serv. atEnd(); l_serv. moveNext()) /* @RESULTS */ 
{ var an_obj = l_serv. item()
select_append(l_elts. namedItem("SERVERS"), an_obj. Path_, an_obj. ProgId) } 
/* @RESULTS X */ 
l_elts. namedItem("READ-SERVER"). disabled = false } /* ?GOT_RESULTS */ } 
else /* ?ENTERPROGID N */ if("READ-SERVER" == a_cmd) /* ?READ_SERVER Y */
{ 
var an_obj = (
l_elts. 
namedItem("WMI-LOCATOR"). 
object. ConnectServer(). Get(l_elts. namedItem("SERVERS"). value))
l_elts. namedItem("SERVER-CLASSID"). value = an_obj. ComponentId
l_elts. namedItem("SERVER-PROGID"). value = an_obj. ProgId } 
/* ?READ_SERVER */ /* ?ENTERPROGID */ /* ?ENTERCLASSID */
return false } /* !findProgId X */

// END SECTION WMI_utilities

// BEGIN SECTION Shell_utilities

function get_path(p_s) /* Returns the location of the object. */ 
{ var a_n
if(a_n = p_s. Document) p_s = a_n
if(a_n = p_s. Folder) p_s = a_n
if(a_n = p_s. Items()) p_s = a_n. Item(). Path + "\\"
return p_s } /* !get_path X */

function unprefix (p_s, p_pf) 
/* Removes the prefix from the path, converting it to a relative path */
{ var a_l = (p_pf = get_path(p_pf)). length
if(p_s. substr(0, a_l) == p_pf) return p_s. substr(a_l). replace(/\\/g, "/") 
else alert(p_pf) } /* !unprefix X */

function showFolder() /* Dual folder view event handler. */ 
/* TODO: rename this */
{ var l_elts = this. elements, a_cmd = document. activeElement. name
if("GET-PATH" == a_cmd) /* *COMMAND=GET_PATH */
/* shows the current location path in the address control */
l_elts. 
 namedItem("PATH"). 
 value = (
 l_elts. 
 namedItem("BROWSER"). object. LocationURL)
else if("NEXT" == a_cmd) /* *COMMAND=NEXT */
for(;;) /* @LOCATIONS */ 
{ var a_pos = ++ l_elts. namedItem ("CUR"). value, an_ex 
try /* &NAVIGATE */ { l_elts. namedItem("BROWSER"). object. Navigate2 (a_pos)
break /* @LOCATIONS X */ } 
catch(an_ex) /* &NAVIGATE F */ {} /* &NAVIGATE X */ } 
/* @LOCATIONS X */
else if("UPLOAD" == a_cmd) /* *COMMAND=UPLOAD */
/* Uploads the local file to the remote server. */
{ var a_path = l_elts. namedItem("LOCAL-FILE"). value
l_elts. namedItem("REMOTE"). Document. Folder. ParseName( 
 unprefix(a_path, 
 l_elts. namedItem("LOCAL"). object)). Parent. CopyHere(a_path) } 
else if("SHOW" == a_cmd) /* *COMMAND=SHOW */ 
/* Retrieves the selected file in the remote location. */
location = l_elts. namedItem("REMOTE"). Document. Folder. ParseName( 
 unprefix(l_elts. namedItem("LOCAL-FILE"). value, 
 l_elts. namedItem("LOCAL"). object)). Path
return false } /* !showFolder X */

// END SECTION Shell_utilities

// BEGIN SECTION Sniffer

function handle_request(a_frm, a_req)
/* Handles notifications returned by the XML HTTP Request object. */
{ var a_state = +a_req. readyState
a_frm. namedItem("STATE"). value = +a_state
if (+a_state == +04) /* ?IS_COMPLETE Y */ {
a_frm. namedItem("HEADERS"). value = a_req. getAllResponseHeaders()
a_frm. namedItem("STATUS"). value = a_req. status } /* ?IS_COMPLETE */ } 
/* !handle_request X */

function getHeaders() 
/* Prepares and sends the XML HTTP request. */
{ var l_elts = this. elements
var a_req = l_elts. namedItem("REQUEST"). object, a_frm = this
a_req. onreadystatechange = function handler() 
{ handle_request(l_elts, a_req) } /* !getHeaders.handler X */
a_req. open("HEAD", l_elts. namedItem("URL"). value)
a_req. send()
return false } /* !getHeaders X */

function sniff_setup (p_frm) 
/* Prepares the sniffer form for using */
{ var l_elts = p_frm. elements
p_frm. onsubmit = getHeaders
if(l_elts. namedItem("REQUEST"). object) 
l_elts. namedItem("GET"). disabled = false } /* !sniff_setup */

// END SECTION Sniffer

function processText() { var a_text_ctl = this. elements. namedItem("TEXT") 
a_text_ctl. value = encodeNCR(a_text_ctl. value)
return false } /* !processText X */

// BEGIN SECTION Transformer

function processXML (p_elts) 
/* Transforms the referenced XML document using the referenced stylesheet. */
{ 
var 
l_elts = p_elts? p_elts: this. elements, 
an_xml_h = (
l_elts. 
namedItem ("A-DOC-WIN"). object. getElementById ("MSXML2.DOMDocument")), 
an_xml = an_xml_h. object, 
a_tr = (
l_elts. namedItem ("A-XFRM-WIN"). 
object. getElementById ("MSXML2.DOMDocument")),
a_state = an_xml. readyState, a_doc = an_xml. documentElement, a_doc_type, 
a_tr_doc = a_tr. documentElement,
an_err = an_xml. parseError, a_display = l_elts. namedItem ("TRANSFORMED"), 
a_uri_doc_ctl = l_elts. namedItem("URI-DOC"), 
a_uri_xfrm_ctl = l_elts. namedItem ("URI-XFRM"),
a_doc_uri = a_uri_doc_ctl. value, an_xfrm_uri = a_uri_xfrm_ctl. value
if(!+an_err) an_err = a_tr. parseError
l_elts. namedItem("STATE"). selectedIndex = a_state
if(a_doc_type = an_xml. doctype) 
l_elts. namedItem("DOC"). value = a_doc_type. name
l_elts. namedItem("ERROR"). value = an_err
l_elts. namedItem("REASON"). value = an_err. reason
set_val_size(l_elts. namedItem("ERROR-TEXT"), an_err. srcText)
l_elts. namedItem("ERROR-LINE"). value = an_err. line 
/* TO DO: DETECT CHANGE IN VALUE AND ACT ACCORDINGLY */
/* if (an_xml. url != a_doc_uri) 
window. alert ("URI changed from " + an_xml. url + ", refresh!") */
/* The problem with this approach 
is that a relative URI transforms to absolute */
if(a_doc && a_tr_doc) {
a_display. write (an_xml. transformNode(a_tr))
a_display. close () }
if(!p_elts || an_xml. readyState == 04 && !a_doc 
&& !+an_err && an_xml. async && a_tr. readyState == 04 && !a_tr_doc 
&& a_tr. async) 
{ 
var a_prop = [ 
"ProhibitDTD", false, "ResolveExternals", true, 
"AllowDocumentFunction", true ], 
an_ix = 0, a_l = a_prop. length, l_docs = [an_xml, a_tr], a_doc
for(; an_ix < a_l; an_ix += 02) 
for (a_doc in l_docs)
l_docs [a_doc]. setProperty(a_prop[an_ix], a_prop[an_ix + 01]) 

for (a_doc in l_docs) 
l_docs [a_doc]. onreadystatechange = function xml_onload() { 
 processXML(l_elts) }
a_tr. load (an_xfrm_uri) 
window. set_val_size_nz (a_uri_xfrm_ctl, a_tr. url)
an_xml. load (a_doc_uri) 
window. set_val_size_nz (a_uri_doc_ctl, a_doc_uri)
 }
return false } /* !processXML X */

function XML_setup (p_frm) /* Prepares the XML form for using */
{ 
p_frm. onsubmit = processXML 
p_frm. elements. namedItem("SUBMIT"). disabled = false
 } /* !XML_setup X */

// END SECTION Transformer

// BEGIN SECTION LS_DU
/* 
Analysis.  
Each directory listed, except for the first, has a directory header.  
The directory appears after it has been listed.  
The parent directory listing contains an inode 
which is a unique number attributed to this directory.  
By convention, the root directory has inode 0.
We need to identify each subdirectory by inode.  
Since the subdirectories are enumerated after they are recorded, 
this is possible by scanning the listing forward.
We define a relation DIRECTORY(PARENT: INODE, NAME: TEXT, INDEX: INODE)
where INDEX is unique for (PARENT, NAME)
and (PARENT, NAME) is unique for INDEX.
We can use true recordsets or JavaScript dictionaries for the purpose.
Since JavaScript does not support two-key dictionaries, we need a relation
inode[parent][name] = number
and entry[inode] = [parent, name, ...]
These are going to be global objects for now.

TODO: Use the fact that the file names are sorted by name.
Store all DIRECTORY records in an array.
Reference the array by index and not by inode (eliminate lookup).
Perform binary search on entry from parent_begin till parent_end.

Thus we get 
entry [entry_index [inode]]. inode == inode
!IF entry [entry [index]. begin] <= pendent < entry [entry. end] 
!THEN entry [pendent]. parent == INDEX

The operation { pendent => entry [pendent]. name } 
is increasing in this range.

Anyway, the first step is to switch rendering off.

*/

function create_hash() 
{ var a_res = {}, an_ix = 0, a_len = +arguments. length, a_prop
for (; +an_ix < +a_len; ++an_ix) 
if (+an_ix & 01) a_res [a_prop] = arguments [+an_ix] 
else a_prop = arguments [+an_ix]
return a_res }

while (create_hash (0, 01) [0] != 01) debugger

function directoryTree () 
/* A tree contains a root node 0 with a traceback */
{ this [0] = { "/.": { node: 0 }}}

function directoryTree. prototype. key (p_name) 
/* Encodes a file name so that it does not clash with a built-in property */
{ return "/" + p_name }

function directoryTree. prototype. get_entry (p_node) 
/* Returns the entry for the node */
{ return this. locate (+p_node, ".") }

function directoryTree. prototype. locate (p_node, p_name) 
/* Returns the entry by name within the node */
{ var a_node = this [+p_node]
if (a_node) return a_node [this. key (p_name)] }

function directoryTree. prototype. add_entry (p_entry) 
/* Adds an entry and a traceback */
{ 
var call_cre = function create_entry (p_name, p_node) {
var a_list = this [+p_node]
if (a_list) a_list [p_name] = p_entry
else 
(this [+p_node] = 
create_hash (p_name, p_entry)) }
call_cre. call (this, this. key (p_entry. name), +p_entry. parent)
call_cre. call (this, "/.", +p_entry. node)
}

function directoryTree. prototype. find_path (p_path) 
{ var an_ix, a_dir = 0
p_path = p_path. split ("/")
for (an_ix in p_path) 
if ((a_dir = this. locate (a_dir, p_path [+an_ix])) == null) return 
else a_dir = a_dir. node
return a_dir }

function directoryTree. prototype. get_path (p_node) 
{ return this. get_entry (+p_node). name }

function directoryTree. prototype. calc_sizes()
/* 
Returns the function total_size as an array
where total_size is calculated according to the formula
total_size ($node) 
:= $node.size + sum (apply total_size to nodes where .parent == $node)
Implementation notes
The total size is 
*/
{ var l_sizes = [], a_node
for (a_node in this) 
if (+a_node == a_node) /* ?ISNODE Y */ 
{ var a_dir = this [+a_node], an_entry
for (an_entry in a_dir) 
if (an_entry. charAt && an_entry. charAt (0) == "/" && an_entry != "/.") 
/* ?ISENTRY Y */
{ var a_rec = a_dir [an_entry], a_size = +a_rec. size
if (a_size) /* ?HASSIZE Y */ { var a_node = +a_rec. node
for 
(l_sizes [+a_node] = +a_size; +a_node; 
a_rec = this. get_entry (+a_node)) 
l_sizes [+(a_node = +a_rec. parent)] += +a_size } /* ?HASSIZE */ } 
/* ?ISENTRY */ } /* ?ISNODE */ return l_sizes } /* !calc_sizes X */

function ls_tracer () { 
var a_doc = this. m_doc = (this. m_win = open ("", "ls")). document. open
open_tag (a_doc, "title")
a_doc. writeln("Directory of")
close_tag (a_doc, "title")
}

function ls_tracer_quiet () {}

function ls_tracer. prototype. append_path (p_path) { 
var a_doc = this. m_doc
open_tag (a_doc, "h2")
a_doc. write (p_path)
close_tag (a_doc, "h2")
}

function ls_tracer_quiet. prototype. append_path () {}

function ls_tracer. prototype. append_subtotal (p_val) { 
var a_doc = this. m_doc
open_tag (a_doc, "p")
a_doc. write (p_val)
close_tag (a_doc, "p")
}

function ls_tracer_quiet. prototype. append_subtotal () {}

function ls_tracer. prototype. append_table (p_head) { 
this. m_tbl = new HT_Table_Writer (this. m_doc, p_head)
}

function ls_tracer_quiet. prototype. append_table () {}

function ls_tracer. prototype. append_row (p_fields) 
{ 
return this. m_tbl. appendRow (p_fields)
}

function ls_tracer_quiet. prototype. append_row () {}

function ls_tracer_quiet. prototype. close_table () {}

function ls_tracer. prototype. close_table (p_total) {
var a_doc = this. m_doc
this. m_tbl. close()
this. m_tbl = null
open_tag (a_doc, "p")
a_doc. writeln ("Total:")
a_doc. writeln (p_total)
}

function ls_tracer. prototype. close () { this. m_doc. close ()
this. m_doc = null }

function ls_tracer_quiet. prototype. close () {}

function show_listing() 
/* FTP DIR parser command handler. */
{ 
var l_elts = this. elements, a_cmd = document. activeElement. name
if (a_cmd. valueOf() == "C-LIST") /* *CMD=C-LIST */ {
var a_src = l_elts, a_next, a_rdr, a_tab_no = +0, an_ix, 
a_tree = new directoryTree(), a_node
/* Extract the text of the listing; we could use innerText as well. */
if (a_src) a_next = a_src. namedItem("T-LS")
if (a_next) a_src = a_next
else throw "No elements"
if (a_next = a_src. object) a_src = a_next
else throw "No object"
if (a_next = a_src. getElementsByTagName ("PRE") [0]) a_src = a_next
else throw "No PRE"
if (a_next = a_src. firstChild) a_src = a_next
else throw "No text"
if (a_next = a_src. data) a_src = a_next
else throw "No data"
var a_trc = new ls_tracer_quiet(), a_line
a_rdr = new StringReader(a_src)
do /* @TABLES */ {
for(an_ix = +0; +an_ix < +02; ++an_ix) /* @HEADING */ 
{ if(+an_ix) a_trc. append_subtotal (a_line = a_rdr. read_line())
else { var a_last
a_trc. append_path (a_node = +a_tab_no? a_rdr. read_line(): ".")
if (a_node. charAt (+(a_last = +a_node. length - 01)) == ":") 
a_node = a_node. substr (0, +a_last)
// window. alert (a_node)
if ((+(a_node = a_tree. find_path (a_node))). toString () == "NaN") debugger
 } /* ?SUBTOTAL */ } /* @HEADING X */
if(a_line) /* ?LINE Y */ {
var a_head = ["parent", "node", "rights", "links", "user", "group", "size", 
"month", "day", "time", "name"], a_total = 0
a_trc. append_table (a_head)
while(a_line = a_rdr. read_line()) /* @RECORDS */
{ var a_frdr = new StringReader(a_line), l_fields = new Array(013), an_ix, 
an_entry = {}
l_fields [0] = +(an_entry. parent = +a_node)
for(an_ix = +01; +an_ix < +012; ++an_ix) 
l_fields[an_ix] = an_entry [a_head [an_ix]] = a_frdr. read_word() 
l_fields[an_ix] = an_entry. name = a_frdr. read_rest()
a_total += +l_fields [+06]
a_trc. append_row (l_fields)
a_tree. add_entry (an_entry)
 } /* @RECORDS X */
/*
28874912 -rw-------  1 ne01026  2000  181365 Sep  7 05:01 .mail
00000001 0000000002  3 0000004  0005  000006 007  8 00009 &rest;
*/
a_trc. close_table (a_total)
++a_tab_no
a_line = a_line != null } /* ?LINE */ } 
while (a_line /* && +a_tab_no < 02 */) /* @TABLES X */
// debugger
/* Create and calculate */
if (true) { var l_sizes = a_tree. calc_sizes(), l_sndx = []
for (a_node in l_sizes) l_sndx. push (+a_node)
l_sndx. sort (function cmp_sizes (p_x1, p_x2) 
{ return -default_cmp (+l_sizes [+p_x1], +l_sizes [+p_x2]) })
if (false) /* ?DUMP2 Y */ { a_tbl = false
for (a_node in l_sndx) /* @NODE */
{ if (!a_tbl) /* ?THEAD Y */ { var a_head = ["node", "size"], an_ix
open_tag(a_doc, "TABLE")
open_tag(a_doc, "THEAD")
open_tag (a_doc, "TR")
for (an_ix in a_head) /* @HEADERS */ { open_tag (a_doc, "TH")
a_doc. write (a_head [+an_ix]) } /* @HEADERS X */
open_tag (a_doc, "TBODY") 
a_tbl = true
} /* ?THEAD */
open_tag (a_doc, "TR")
open_tag (a_doc, "TD")
a_doc. write (a_node = +l_sndx [+a_node])
open_tag (a_doc, "TD")
a_doc. write (l_sizes [+a_node]) } /* @NODE X */
if (a_tbl) close_tag (a_doc, "TABLE")
} /* ?DUMP2 */
if (true) 
/* Fills the node list ordered by size. */
{ var a_sel = l_elts. namedItem ("S-NODES")
a_sel. selectedIndex = 0
for (a_node in l_sndx) 
{ var an_entry = a_tree. get_entry (+(a_node = +l_sndx [+a_node])) 
select_append (a_sel, +an_entry. node, +l_sizes [+a_node]) }
select_truncate (a_sel)
l_elts. namedItem ("C-SHOW"). disabled = false
window. g_tree = a_tree
window. g_sizes = l_sizes
window. g_sndx = l_sndx
}}
/* Dump the tree as a table for debugging */
if (false) { var a_node
a_tbl = false
for (a_node in a_tree) 
if (a_node == +a_node) /* ?DIR Y */ { var an_entry, a_dir = a_tree [+a_node]
for (an_entry in a_dir) /* @ENTRIES */ {
if (an_entry. charAt && an_entry. charAt (0) == "/") /* ?ENTRY Y */ 
{ var a_col, a_rec
if (!a_tbl) /* ?OTBL Y */ {
open_tag (a_doc, "TABLE")
open_tag (a_doc, "THEAD")
open_tag (a_doc, "TR")
for (a_col in a_dir [an_entry]) /* @HEADERS */ { open_tag (a_doc, "TH")
a_doc. writeln (a_col) } /* @HEADERS X */ open_tag (a_doc, "TBODY") 
a_tbl = true } /* ?OTBL */
open_tag (a_doc, "TR") 
a_rec = a_dir [an_entry]
for (a_col in a_rec) /* @ENTRY */ { open_tag (a_doc, "TD", "title", a_col)
a_doc. write (a_rec [a_col]) } /* @ENTRY X */ } /* ?ENTRY */ } 
/* @ENTRIES X */ } /* ?DIR */
if (a_tbl) close_tag (a_doc, "TABLE")
}
a_trc. close() } 
else if (a_cmd. valueOf() == "C-SHOW") 
set_val_size 
(l_elts. namedItem ("T-PATH"), 
window. g_tree. get_path (l_elts. namedItem ("S-NODES"). value)) 
return false }

// END SECTION LS_DU

function DOM_to_XML(p_doc, p_node) 
{ return (p_node. tagName? 
p_doc. createElement (p_node. tagName. toLowerCase()): 
p_doc. createTextNode(p_node. nodeValue)) }

function XHTML_setup(p_frm) 
{ var l_elts = p_frm. elements, an_in = l_elts. namedItem( "T-HTML" ), 
an_out, l_attrs, an_ix, a_len, a_next
p_frm. onsubmit = function transform_HTML() 
{ var a_doc = l_elts. namedItem( "A-DOC" ), 
a_src = document. createElement( "INS" )
for
(a_src. innerHTML = l_elts. namedItem( "T-HTML" ). value; 
a_src; ) /* @nodes */ {
(an_out = 
an_out? 
an_out. appendChild (DOM_to_XML (a_doc, a_src)): 
a_doc. documentElement = a_doc. createElement (a_src. tagName. toLowerCase()))
if (l_attrs = a_src. attributes) /* ?attrs Y */ { a_len = +l_attrs. length
for( an_ix = 0; +an_ix < +a_len; ++an_ix ) /* @attrs */
{ var an_attr = l_attrs. item( +an_ix )
if( an_attr. specified )
an_out. 
setAttribute( an_attr. name. toLowerCase(), an_attr. value. toString())} 
/* @attrs X */ } /* ?attrs */ 
if (!(a_next = a_src. firstChild)) {
while (a_src && !(a_next = a_src. nextSibling)) { a_src = a_src. parentNode
if(an_out) an_out = an_out. parentNode } 
if(an_out) an_out = an_out. parentNode } 
a_src = an_out? a_next: null } /* @nodes X */
l_elts. namedItem( "T-XHTML" ). value = a_doc. xml
return false }
an_in. value = an_in. outerHTML
l_elts. namedItem( "C-TRANSFORM" ). disabled = false
}

if (this. WScript) 
WScript. Echo 
("JavaScript Tools library\n © Christopher Yeleighton, 2009\n Handle with care.")
