reference updates, including diagrams
[org.ibex.core.git] / doc / reference.xml
diff --git a/doc/reference.xml b/doc/reference.xml
deleted file mode 100644 (file)
index 15b8da4..0000000
+++ /dev/null
@@ -1,2418 +0,0 @@
-<ibex-doc title="The Ibex Reference" subtitle="Nitrogen Release" author="Adam Megacz" email="adam@ibex.org">
-
-<!-- ----------------------------------------------------------------------- -->
-<section title="Preface">
-    
-    <i>
-    If you are reading the html version of this document and are
-    thinking of printing it out, you might be interested in the nicely
-    typeset <link url="reference.pdf" text="pdf version"/> produced
-    with LaTeX.
-    </i>
-
-    This document is a <b>reference</b>. It is not a
-    <b>specification</b> or a
-    <b>tutorial</b>.
-    
-    This document does not guide the user gently through examples (as a
-    tutorial would), and it doesn't provide enough detail and formality
-    for a third party to construct a compatible re-implementation of the
-    Ibex Core (as a specification would).
-    
-    Rather, the goal of this document is to completely describe every
-    aspect of the environment that the Ibex Core provides to client
-    applications, from the bottom up. If you want to be an Ibex expert,
-    this is the right document to read. It is assumed that you are already
-    familiar with XML and with either JavaScript or ECMAscript. If
-    you are not familiar with ECMAscript, some reference materials are
-    provided in <link appendix="G"/>
-    
-    The <i>wildebeest sequence</i> (how the Ibex Core gets onto the
-    client's computer, and how it knows where to download the initial
-    <t>.ibex</t> from) is not described in this document, since it
-    will be different for every platform that Ibex is ported to.
-    
-    If you need to use or rely on some behavior you notice in the Ibex
-    Core, but which is not clearly defined here, please post to <link
-    url="http://lists.ibex.org/listinfo/users" text="the users mailing list"/>.
-    
-  <section title="Key Concepts">
-  
-    <definition term="The Core">
-         Ibex itself; the native code (or Java bytecode) that runs on
-         the client.  This term does not include the <i>wildebeest</i>
-         or the <i>UI</i></definition>
-  
-    <definition term="The UI / The Application">
-         a set of files (mostly XML, JavaScript, and PNG images)
-         bundled up in a zip archive, ending with the "..ibex"
-         extension.  Together, these files specify the appearance and
-         behavior of the application's user interface.  Sometimes
-         we'll refer to this as the ".ibex" to be clear that we're
-         talking about the actual zip archive, rather than its visual
-         appearance when rendered on the screen.</definition>
-  
-    <definition term="The Server">
-         We will use the term "the server" to refer to any other
-         computer which the client makes XML-RPC or SOAP calls
-         to. Note that it is possible for the client and server to be
-         the same machine.</definition>
-  
-    <definition term="The Wildebeest">
-         this is a very small piece of code that is downloaded the
-         first time a client uses Ibex. It downloads the Ibex core,
-         verifies its signature, and launches it with the appropriate
-         parameters indicating where to find the initial UI.  The
-         Wildebeest works differently on every platform, and is outside
-         the scope of this document.</definition>
-  
-    <definition term="put/write">
-         In ECMAscript, when you change the value of a property on an
-         object, you are <i>putting</i> to that property, or
-         <i>writing</i> to it. For example, the ECMAscript expression
-         "<t>foo.bar = 5</t>" <i>puts</i> the value 5 to the bar
-         property on object foo.</definition>
-  
-    <definition term="get/read">
-         In ECMAscript, when you access the value of a property on an
-         object, you are <i>getting</i> that property, or
-         <i>reading</i> from it. For example, the ECMAscript
-         expression "<t>return (3 + foo.bar)</t>" <i>gets</i> the
-         value of bar property on object foo and then adds 3 to it
-         before returning the result.</definition>
-  
-    <definition term="JavaScript">
-        We will use the terms JavaScript and ECMAScript
-        interchangeably in this document.  The Ibex interpreter is not
-        completely ECMA-compliant, however (see <link
-        appendix="C"/> for details).  </definition>
-  </section>
-</section>
-    
-<section title="Surfaces">
-
-  Each top-level window in an Ibex UI is called a
-  <i>surface</i>. There are two kinds of surfaces: <i>frames</i>,
-  which usually have a platform-specific titlebar and border, and
-  <i>windows</i>, which never have any additional platform-specific
-  decorations.
-    
-  Whenever we refer to the size or position of a surface, we are
-  referring to the size or position of the UI-accessible portion of the
-  surface; this does not include any platform-specific decorations. This
-  means that if you set the position of a frame to (0,0), the
-  platform-specific titlebar will actually be off the screen on most
-  platforms (it will be above and to the left of the top-left corner of
-  the screen).
-    
-  Surfaces are not actual JavaScript objects; you cannot obtain a
-  reference to a surface.  However, each surface is uniquely identified
-  by its <i>root box</i>, described in the next section.
-    
-</section>
-
-<section title="Boxes">
-
-  A <i>box</i> is the fundamental unit from which all Ibex user
-  interfaces are built.  Boxes can contain other boxes (known as
-  <i>children</i>).  Each Surface has a single box associated with it
-  called the <i>root box</i>; the root box and its children (and its
-  children's children, and so on) form the surface's <i>box tree</i>.
-    
-  There are three ways to think of a box: as a rendered visualization on
-  the screen (the "Visual Representation"), as a JavaScript object (the
-  "Object Representation"), and as an XML tag (the "XML
-  Representation").
-    
-  FIXME: diagram here
-    
-  All three representations are equally valid, and being able to figure
-  out what an action in one representation would mean in terms of the other
-  two representations is crucial to a solid understanding of Ibex.
-    
-  <section title="The Object Representation">
-
-    Each box is a full-fledged ECMAscript object, and can store key-value
-    pairs as properties.  Some of these keys have special meaning, which
-    will be explained later.  Each box's numeric properties hold its
-    <i>child boxes</i>. 
-    
-  </section>
-
-  <section title="The Visual Representation">
-
-    Each box occupies a rectangular region on the surface.  The visual
-    appearance of a surface is created by rendering each box in its tree.
-    Unless the <t>clip</t> attribute is <t>false</t>, each box will
-    clip its childrens' visual representations to its own, so that the
-    children appear "confined to" the parent.  Children are rendered after
-    their parents so they appear "on top of" their parents (they obscure
-    them).
-    
-    Each box has two major visual components, each with subcomponents:
-    
-    FIXME: diagram
-    
-    <list>
-        A <b>path</b>, which consists of zero or more lines and
-        curves.  The path may be filled with a color, gradient, or
-        texture, and may be stroked with a line of a given thickness
-        and color.  If the path is not specified, it defaults to the
-        perimiter of the box.
-
-        <list>
-            The path has an associated <b>strokecolor</b>, which is a
-            color
-
-            The path has an associated <b>strokewidth</b>, which is a
-            number specifying the width of the stroke.
-            
-            The path also has a <b>fill</b>, which is either a color, gradient, or
-            texture
-        
-            A single line of <b>text</b>, which can be rendered in
-            different fonts, colors, and sizes.
-        </list>
-
-        The text has an associated <b>font</b>, which currently can be
-        any font supported by the <link url="http://www.freetype.org"
-        text="FreeType2"/> library.
-            
-        The text also has an associated <b>fontsize</b>
-            
-        The text is drawn in an associated <b>textcolor</b>
-
-    </list>
-
-    These eight components plus the size of a box fully specify its
-    appearance.  Every single box you see in Ibex is drawn only on the
-    basis of these components and its size.
-    
-  </section>
-
-  <section title="The XML Representation">
-
-    A template (discussed in the next section) is an XML file which acts
-    as a blueprint for constructing a tree of boxes.  We call this
-    construction process <i>applying</i>, since unlike
-    <i>instantiation</i>, you always apply a template to a pre-existing
-    box, and you can apply multiple templates to the same box.  Each XML
-    tag corresponds to a single box, or to another template which will be
-    applied to that box.  For example, a <t>scrollbar</t> template, when
-    applied, will construct a tree of boxes which has the visual
-    appearance and behavior of a scrollbar.
-    
-    Although it is useful to think of the XML tags as being boxes, keep in
-    mind that the XML representation is only a blueprint for constructing
-    a tree of JavaScript objects.  Once the template has been
-    instantiated, the XML is effectively "thrown away", and JavaScript code is
-    free to alter the boxes.
-    
-  </section>
-</section>
-
-<section title="Templates">
-
-  Each template is an XML document whose root element
-  is <t>&lt;ibex></t>.  Any text content of the root element is
-  ignored, and may safely be used for comments.  The root element may
-  have any of the following elements as children, each of which may
-  appear no more than once, and which must appear in this order:
-    
-  Here is a sample Ibex file:
-    
-  <pre>
-  <ibex xmlns="ibex.widget" xmlns:lib="ibex.lib">
-      This is a sample Ibex file. Text up here is ignored.
-      Copyright (C) 2004 Mustapha Mond.
-      <static>
-          // code here will be executed only once
-      </static>
-      <template cols="5">
-          <box id="container"/>
-          <checkbox/>
-          <box>
-              /* This has to be commented out or else it
-                 will be treated as a script */
-              <lib:scrollbar/>
-          </box>
-      </template>
-  </ibex>
-  </pre>
-    
-  <heading title="Applying an XML Tag to a Box"/>
-
-    The following description of the box application is extremely detailed
-    and precise; it is intended for UI designers who need to know the
-    exact order in which each event happens.  FIXME:
-    easier description.  While this whole process sounds very
-    complex, it actually works pretty intuitively. The description below
-    is given in great detail since most applications will wind up being
-    unintentionally dependent on subtle features of this process.
-    However, most of the time you can just pretend that the XML tags and
-    the boxes are the same thing.
-    
-    To apply an XML tag <t><b>X</b></t> to a box <t><b>B</b></t>, perform the following
-    operations, in this order:
-    
-    <list type="ordered">
-
-        Allocate a fresh scope <t><b>s</b></t> whose parent scope is
-        <t><b>b</b></t>.
-        
-        Process each child element or text segment of <t><b>X</b></t> in the
-        order they appear in the document: For each <i>text
-        segment</i> <t><b>t</b></t>:
-
-        <list>
-            Treat <t><b>t</b></t> a JavaScript script, and execute it
-            with <t><b>s</b></t> as the root scope.
-        </list>
-
-        For each child element <t><b>x</b></t> of
-        <t><b>x</b></t>:
-
-        <list>
-            Create a new box <t><b>b</b></t>.
-            
-            If the name of tag <t><b>x</b></t> is not "<t>box</t>" (in the
-            default XML namespace), prepend the tag's namespace
-            identifier uri (if any) to the name of the tag, and use
-            the result as a key to retrieve a property from the root
-            stream (defined later).  Interpret the resulting stream as
-            a template and apply that template to <t><b>b</b></t>.
-            
-            (recursively) apply <t><b>x</b></t> to <t><b>b</b></t>.
-            
-            If <t><b>x</b></t> has an <t>id</t> attribute, declare a variable
-            in <t><b>s</b></t> whose name is the value of the <t>id</t>
-            attribute, prefixed with the <t>$</t> character, and whose
-            value is <t><b>b</b></t>
-            
-            Copy any <t>$</t>-variables created during the application
-            of <t><b>x</b></t> into scope <t><b>s</b></t>.
-            
-            Append <t><b>b</b></t> as the last child of <t><b>b</b></t>.
-        </list>
-        
-        Apply any attributes on <t><b>x</b></t> to <t><b>b</b></t>, except for
-        <t>id</t>.  Since XML specifies that the order of attributes
-        cannot be significant, Ibex processes attributes in
-        alphabetical order by attribute name.  For example, if
-        <t><b>x</b></t> has the attribute <t>foo="bar</t>", then the
-        equivalent of the statement <t>B.foo="bar";</t> will be
-        performed, with the following exceptions:
-
-        <list>
-            If the value portion of the attribute is the string
-            "<t>true</t>", put the boolean <t>true</t>. If the
-            value is "<t>false</t>", put the boolean <t>false</t>.
-        
-            If the value is a valid ECMAscript number, put it as a
-            number (instead of a string).
-                 
-            If the value begins with a dollar sign (<t>$</t>),
-            retrieve the value of the corresponding variable in
-            <t><b>s</b></t> and use that value instead.
-         
-            If the value begins with a dot (<t>.</t>), prepend the
-            attributes' namespace identifier uri (if any) and
-            interpret the remainder as a property to be retrieved from
-            the root stream (defined later).
-        </list>
-    </list>
-
-    The last two steps are referred to as the <i>initialization</i> of the
-    node.  There are two important aspects of this ordering to be aware of:
-             
-    <list type="unordered">
-
-        A given box will be fully initialized before its parent is
-        given a reference to that box.  This way, parents can be
-        certain that they will never wind up accessing a box when it
-        is in a partially-initialized state.
-        
-        Attributes are applied <i>after</i> scripts are run so that
-        the attributes will trigger any <i>traps</i> (defined later)
-        placed by the script.
-
-    </list>
-    
-</section>
-
-<section title="Life Cycle of an Ibex Application">
-
-  A user begins by specifying the URL of an Ibex application run.
-  Usually this is done by visiting a web page which uses the
-  <i>wildebeest</i> to install the core if it is not already on the user's
-  machine, but you can also supply the URL on the command line.
-    
-  The Ibex Core downloads the .ibex for the application, loads it, applies
-  the <t>main.ibex</t> template and renders it onto the screen, running
-  any associated ECMAscript code.
-    
-  The user interacts with the application by clicking and moving the
-  mouse, and by pressing keys on the keyboard.  These actions trigger
-  fragments of JavaScript code which are designated to handle events.
-  This JavaScript code can then relay important information back to the
-  server using XML-RPC or SOAP, or it can modify the structure and
-  properties of the user interface to change its appearance, thereby
-  giving feedback to the user.
-    
-    
-  DIAGRAM: graphic here showing the circular feedback cycle.
-    
-    
-  The Ibex core quits when the last remaining surface has been destroyed.
-    
-</section>
-
-<!-- ----------------------------------------------------------------------- -->
-<section title="Layout and Rendering">
-
-    The size and position of every other box is determined
-    by its properties, its childrens' sizes, and its parent's size and position.
-    Box layout and rendering happens in four phases: <i>packing</i>,
-    <i>constraining</i>, <i>placing</i>, and <i>rendering</i>.  The Core is careful to only
-    perform a phase on a box if the box has changed in a way that
-    invalidates the work done the last time that phase was performed.
-      The
-    packing and constraining phases are performed in a single traversal of
-    the tree (packing is preorder, constraining is postorder), and the
-    placing and rendering phases are performed in a second traversal of
-    the tree (first placing, then rendering, both preorder).
-    
-    For brevity, the rest of this chapter deals only with width and
-    columns.  Height and rows is treated identically and independently.
-    Also, it is important to note that the term <i>minimum width</i> is
-    not the same thing as the property <t>minwidth</t>, although they
-    are closely related.
-    
-  <section title="The size of the root box">
-
-    When the user resizes a window, Ibex changes the root box's
-    <t>maxwidth</t> and <t>maxheight</t> to match the size chosen by
-    the user and then determines the root box's size using the same sizing
-    rules it uses for other boxes.
-    
-    Ibex will always attempt to prevent the
-    user from making the surface smaller than the root box's
-    <t>minwidth</t> and <t>minheight</t>.  If the <t>hshrink</t> or
-    <t>vshrink</t> flag is set, Ibex will try to prevent the user from
-    resizing the surface at all.  However, not all platforms give Ibex
-    enough control to do this.
-    
-    </section>
-
-  <section title="The alignment point">
-
-    When talking about positioning, we will often refer to the
-    <i>alignment point</i>.
-    
-    <list type="unordered">
-
-        If the <t>align</t> property is "<t>center</t>", then the
-        alignment point is the center of the box.
-        
-        If the <t>align</t> property is "<t>topleft</t>",
-        "<t>bottomleft</t>", "<t>topright</t>", or
-        "<t>bottomright</t>", then the alignment point is
-        corresponding corner of the box.
-        
-        If the <t>align</t> property is "<t>top</t>",
-        "<t>bottom</t>", "<t>right</t>", or "<t>left</t>", then
-        the alignment point is middle of the corresponding edge of the
-        box.
-
-    </list>
-
-    FIXME: diagram
-    
-    When positioning a child box, the alignment point is determined by the
-    <i>parent's</i> <t>align</t> property.  When positioning a visual
-    element (a texture, path, or text string) within a box, the alignment
-    point is determined by the <i>box's own</i> <t>align</t> property.
-    
-    A simple way to think about this is that whenever there are two boxes
-    involved in the decision, you should use the parent's alignment point.
-    
-    </section>
-
-  <section title="Packing">
-
-    of <i>cells</i> is created within the parent.  If the parent's
-    <t>cols</t> property is set to 0, the cell grid has an infinite
-    number of columns.  Either <t>cols</t> or <t>rows</t> must be
-    zero, but not both.
-        
-    If a child's <t>visible</t> property is <t>false</t>, it does
-    not occupy any cells (and is not rendered).  Otherwise, each child
-    occupies a rectangular set of cells <t>child.colspan</t> cells
-    wide and <t>child.rowspan</t> cells high.
-        
-    The Core iterates over the cells in the grid in the following
-    order: if <t>rows</t> is 0, the Core iterates across each column
-    before proceeding to the next row; otherwise rows come before
-    columns.  At each cell, the Core attempts to place the <i>first
-    remaining unplaced child's</i> top-left corner in that cell (with
-    the child occupying some set of cells extending down and to the
-    right of that cell).  If the parent has a fixed number of columns
-    and the child's <t>colspan</t> exceeds that limit, the child is
-    placed in column zero regardless, but only occupies the available
-    set of cells (it does not "hang off the end" of the box).
-    
-    <image url="image/layout.png"/>
-    
-    <pre>
-    <box cols="3">
-        <box id="1" />
-        <box id="2" rowspan="2" />
-        <box id="3" colspan="2" />
-        <box id="4" />
-        <box id="5" colspan="2" />
-    </box>
-    </pre>
-    
-    Notes on the layout example:
-    
-    <list type="ordered">
-
-        Box '3' doesn't fit in the gap after '2', nor in the gaps either
-        side of '2' on the next row, hence it is pushed onto the 3rd row.
-
-        Box '4' would fit in the gaps around '2', but must be placed
-        <i>after</i> it's preceeding box, '3'.
-
-    </list>
-    
-    </section>
-
-  <section title="Constraining">
-
-    <list type="ordered">
-        
-        Each box's minimum width is computed recursively as the
-        maximum of:
-
-        <list>
-            Its <t>minwidth</t>
-             
-            The width of the box's <t>text</t> (after applying the
-            box's <t>transform</t>).
-             
-            The width of the box's path (after applying the box's
-            <t>transform</t>) <i>if the box is <t>packed</t></i>.
-             
-            The width of the bounding box enclosing the box's cells.
-        </list>
-        
-        The minimum width of each cell is computed as the minimum
-        width of the box occupying it divided by the box's
-        <t>colspan</t>.
-        
-        If a box's <t>hshrink</t> property is set to
-        <t>true</t>, the box's maximum width is the same as its
-        minimum width; otherwise it is the box's
-        <t>maxwidth</t>.
-        
-        The maximum width of each cell is the <t>maxwidth</t> of
-        the box occupying it divided by the box's
-        <t>colspan</t>.
-
-    </list>
-
-    </section>
-
-  <section title="Placing">
-
-    <list type="ordered">
-        
-        Each column's <i>actual width</i> is set to the maximum
-        <i>minimum width</i> of all the cells in that column.
-        <b>NOTE:</b> although a column or row can be sized smaller
-        than its "minimum width" or larger than its "maximum width", a
-        box will <i>never</i> be smaller than its <t>minwidth</t> or
-        larger than its <t>maxwidth</t>.
-        
-        Each column's maximum width is the largest maximum width of
-        the cells in that column, but no smaller than the column's
-        minimum width.
-        
-        The <i>slack</i> is the difference between the parent's width
-        and the sum of its columns' actual width.  The slack is
-        divided equally among the columns.  Any column which has
-        exceeded its maximum width is set to its maximum width, and
-        the difference is returned to the slack.  This process is
-        repeated until the slack is zero or all columns are at their
-        maximum width.
-        
-        Next, the rows and columns are positioned within the parent
-        box.  The rows and columns are transformed according to the
-        parent's <t>transform</t> property, and the bounding box of
-        the resulting cells are placed such that the cells' alignment
-        point coincides with the parent's alignment point (both
-        alignment points are determined by the parent's <t>align</t>
-        property).  FIXME: diagram
-    
-        <b>Packed boxes:</b> Each packed box's actual position
-        and size is then set to the aggregation of the actual sizes of
-        the cells it spans.  If this size exceeds the box's maximum
-        width, the box is sized to its maximum width and centered
-        horizontally within the space occupied by its cells.
-
-        <b>Non-packed boxes</b>: each non-packed box is transformed
-        according to the parent's <t>transform</t> property and then
-        positioned so that its alignment point is <t>(child.x,
-        child.y)</t> pixels from the parent's alignment point (both
-        alignment points are determined by the parent's <t>align</t>
-        property).
-        
-    </list>
-
-    </section>
-
-  <section title="Rendering">
-
-    Boxes are rendered in a depth-first, pre-order traversal.  Note that
-    this may cause a non-packed box to overlap its siblings.
-    
-    <list type="ordered">
-        
-        If the box's <t>transform</t> property is non-null, the
-        coordinate space is transformed accordingly for the rest of
-        this phase and for the rendering of all children.
-        
-        If the box is packed and has a non-<t>null</t> path, the
-        path is translated such that the alignment point of the path's
-        bounding box coincides with the box's alignment point (both
-        alignment points are determined by the box's <t>align</t>
-        property).
-        
-        If a box has a path, that path is filled with the color,
-        gradient, or image specified by the <t>fill</t> property and
-        stroked with the color and width specified by the
-        <t>strokecolor</t> and <t>strokewidth</t> properties.
-        
-        If the box has a non-null <t>text</t> attribute,
-        the text is rendered in <t>font</t> with size
-        <t>fontsize</t> and color <t>textcolor</t>.  The text is
-        then translated such that the alignment point of the text's
-        bounding box coincides with the box's alignment point (both
-        alignment points are determined by the box's <t>align</t>
-        property).
-        
-        The box's children are rendered (pre-prder traversal).
-
-    </list>
-    
-    </section>
-
-  </section>
-
-<!-- ----------------------------------------------------------------------- -->
-<section title="Box Properties">
-
-  <section title="Rendering Properties">
-
-    Every box has several special properties which control how it is
-    drawn. In general, if you put an
-    invalid value to a special property, no action will be taken -- the
-    put will be ignored.
-    
-    <property name="strokecolor" type="string" default="clear">
-             If the value is a 5-character hex string (<t>#RGB</t>),
-             7-character hex string (<t>#RRGGBB</t>), 9-character hex
-             string (<t>#AARRGGBB</t>), the box's stroke color will be set
-             to that color. 
-             If the value is one of the <link url="http://www.color.org/ICC-1A_1999-04.PDF" text="ICC"/> colors
-             (the same set of color names supported by SVG), the stroke
-             color be set to that color.
-             If the value is <t>null</t>, the stroke color will be set to
-             clear (<t>#00000000</t>).
-             </property>
-    
-    <property name="strokewidth" type="int" default="1">
-             The width (in pixels) to stroke the path with.
-             </property>
-    
-    <property name="fill">
-             This property can be set to any of the values specified for
-             <t>strokecolor</t>.  
-             Alternatively, if the value written is an object, its stream
-             will be read and interpreted as a PNG, GIF, or JPEG image,
-             which will become the texture for this box, and the box's
-             <t>minwidth</t> and <t>minheight</t> properties will be
-             automatically set to the dimensions of the image.
-             </property>
-    
-    <property name="path" type="string" default='""'>
-            The box's path.  The grammar and feature set supported are
-            identical to that specified in <link
-            url="http://www.w3.org/TR/SVG11/paths.html" text="SVG 1.1,
-            section 8"/>.
-            </property>
-    
-    <property name="text" type="string" default='""'>
-            The box's text; writing <t>null</t> to this property sets it
-            to "<t></t>".
-            </property>
-    
-    <property name="font" type="stream" default=".ibex.font.sansserif">
-            When an object is written to this property, its stream is read
-            using the <link url="http://www.freetype.org" text="freetype2
-            library"/>, and the resulting font is used to render the
-            box's <t>text</t>.
-            </property>
-            
-    <property name="fontsize" type="number" default="10">
-            The size (in points) to render the text.
-            </property>
-            
-    <property name="textcolor" type="number" default="black">
-            The color in which to render the font; accepts the same values as <t>strokecolor</t>.
-            </property>
-    
-    </section>
-
-  <section title="Layout Properties">
-    
-    <property name="shrink" type="boolean" default="false">
-        If set to <t>true</t>, this box will shrink
-        (horizontally/vertically/both) to the smallest size allowed by
-        its children and the bounding box of its path.
-        </property>
-    
-    <property name="x" type="integer" default="varies">
-        If the box is a root box, this is the (x/y)-coordinate of the
-        surface; otherwise it is the distance between the parent's
-        alignment point and this box's alignment point.
-        </property>
-    
-    <property name="globalx" type="integer" default="varies">
-        The distance between this box's (left/top) edge and the root
-        box's (left/top) edge. A put to this property has the same
-        effect as a put to the (<t>x</t>/<t>y</t>) property,
-        except that it is relative to the root box rather than to this
-        box's parent. FIXME is this fakeable?  How is
-        distance measured?
-        </property>
-    
-    <property name="minwidth" type="integer" default="0">
-        The desired minimum width and height.
-        </property>
-    
-    <property name="maxwidth" type="integer" default="ibex.maxint">
-        The desired maximum width and height.
-        </property>
-    
-    <property name="width" type="integer" default="varies">
-        When read, this is the (width/height) of this box.  Writing to
-        this property is equivalent to writing to <i>both</i> the
-        minimum and maximum (width/height).
-        </property>
-    
-    <property name="cols" type="integer" default="0">
-        The number of (columns/rows) in which to lay out the children of this
-        box.  If set to zero, the number of (columns/rows) is unconstrained.
-        Either <t>rows</t> or <t>cols</t> must be zero.  If
-        <t>0</t> is written to <t>cols</t> when <t>rows</t> is
-        <t>0</t>, the write is ignored.  If a nonzero value is
-        written to <t>cols</t> when <t>rows</t> is nonzero,
-        <t>rows</t> is set to <t>0</t>, and vice versa.
-        </property>
-    
-    <property name="colspan" type="integer" default="1">
-        The number of (columns/rows) that this box spans within its parent.
-        </property>
-    
-    <property name="align" type="string" default="center">
-        Determines the box's alignment point for positioning its text,
-        texture, path, and children.
-        </property>
-    
-    <property name="visible" type="boolean" default="true">
-        If set to false, this box will be rendered as if its width and
-        height were zero. If this is a root box, the associated surface
-        will be hidden.
-        When reading from this property, the value
-        <t>false</t> will be returned if this box <i>or any of its
-        ancestors</i> is not visible.  Thus it is possible to write
-        <t>true</t> to a box's <t>visible</t> property and then
-        read back <t>false</t>.
-        </property>
-    
-    <property name="packed" type="boolean" default="true">
-         The layout strategy for this box.
-        </property>
-    
-    </section>
-
-  <section title="Child Control Properties">
-    
-    During a box initialization, script-private references to a box's
-    descendants with <t>id</t> attributes are placed on the box. These
-    references allow scripts on that box to easily refer to descendant
-    nodes created by the template in which the script appears. For
-    example, these two blocks of code have exactly the same effect:
-    
-    <pre>
-    <box>                     <box>
-        <box id="foo"/>           <box/>
-        $foo.color = "red";       var $foo = this[0];
-                                  $foo.color = "red";
-    </box>                    </box>
-    </pre>
-    
-    The following special properties control how a box's children are laid
-    out.  If a box has a non-null redirect target, reads and writes to these
-    properties will be forwarded to the redirect target.
-    
-    The <t>redirect</t> attribute is very useful for hiding the
-    internal structure of a widget, and for allowing widgets to act as
-    "smart" containers for other widgets. For example, a menu widget might
-    have an invisible child as its redirect target; this way, when boxes
-    representing items on the menu are added as children of the menu
-    widget, they do not appear until the menu is pulled down.
-    
-    <property name="numeric properties" type="int" default="">
-        The <i>n</i>th child of box <t>b</t> can be accessed by reading from
-        <t>b[n]</t>. The <i>n</i>th child can be removed by writing
-        <t>null</t> to <t>b[n]</t> (the child will become parentless). A
-        new child can be inserted <i>before</i> the <i>n</i>th child by
-        writing it to <t>b[n]</t>; if the value written is already a child of
-        <t>b</t>, it will be removed from <t>b</t> first. It is important
-        to note that this behavior is different from ECMAscript arrays --
-        writing a non-<t>null</t> value to <t>b[n]</t> does not eliminate
-        the <i>n</i>th child; it merely shifts it over one position.  
-        <b>Note:</b> Unlike most JavaScript objects, enumerating a Box's
-        properties with the JavaScript <t>for..in</t> construct will
-        enumerate <i>only</i> the box's children and not any other properties.
-        </property>
-    
-    <property name="clip" type="boolean" default="true">
-        If <t>true</t>, the visual representation of this box's
-        children will be clipped to the boundaries of this box.
-        <b>Note:</b> setting this property to <t>false</t> imposes a
-        substantial performance penalty.
-        </property>
-    
-    <property name="numchildren" type="integer" default="0">
-        The number of children this box has.
-        </property>
-    
-    <property name="redirect" type="box" default="thisbox">
-        Writing to this property sets the box's redirect
-        target. This property cannot be read from, and can only be
-        written to once.
-        </property>
-    
-    <property name="surface" type="" default="null">
-        If this box has a parent, this property returns
-        <t><i>parent</i>.surface</t>; otherwise it returns null.
-        This property is a simple building block that the widget
-        library uses to implement more complex functionality such as
-        focus control and popups.
-        </property>
-    
-    </section>
-
-  <section title="Other Box Properties">
-    
-    <property name="cursor" type="string" default="null">
-        The shape that the cursor should take when inside this
-        box. Valid values are: "<t>default </t> " , "<t>wait</t>",
-        "<t>crosshair</t>", "<t>text</t>", "<t>hand</t>", and
-        "<t>move</t>", as well as resizing cursors"<t>east</t>",
-        "<t>west</t>", "<t>north</t>", "<t>south</t>",
-        "<t>northwest</t>", "<t>northeast</t>",
-        "<t>southwest</t>", and "<t>southeast</t>". Note that on
-        some platforms, resize cursors for opposite directions (such
-        as <t>northwest</t> and <t>southeast</t> are the
-        same).
-        If a box's cursor is <t>null</t>, its parent's cursor will
-        be used. If the root box's cursor is null, the
-        "<t>default</t>" cursor will be used.
-        </property>
-
-    <property name="mouse.x" type="integer" default="varies">
-         The (horizontal/vertical) distance between the mouse cursor and this
-         box's (left/top) edge. Puts to this property are ignored. This
-         value will not be updated if the mouse is outside the root
-         box of the surface and no button was pressed when it left.
-        </property>
-    
-    <property name="mouse.inside" type="boolean" default="false">
-        True if the mouse is inside the rendered region of this box or
-        any of its children. This value will be false if the mouse is
-        inside a portion of this box which is covered up by one of
-        this box's siblings, or one of its ancestors' descendants. Puts
-        to this value are ignored.
-        </property>
-    
-    <property name="static" type="object" default="N/A">
-        Reading from this property will return the parent scope used
-        to execute the <t><static/></t> block of the template
-        in which the currently-executing code resides.
-        </property>
-       
-    <property name="thisbox" type="box" default=" ">
-       Returns a reference to the box itself.
-       If <t>null</t> is written to this property, and this box is
-       the root box of a surface, the box will be detached and the
-       surface destroyed. If this box has a parent, it will be
-       detached from its parent.
-       </property>
-    
-    <property name="indexof()" type="function" default=" ">
-        This property is actually a function; invoking
-        <t>parent.indexof(child)</t> will return the numerical index
-        of <t>child</t> in <t>parent</t> if <t>child</t> is a
-        child of <t>parent</t> (or <t>parent</t>'s redirect
-        target), and <t>-1</t> otherwise. Writing to this property
-        has no effect.
-        </property>
-
-    <property name="childadded" type=" " default=" ">
-
-        These properties are meant to be trapped on FIXME defined later?. Placing a trap on
-        <t>childadded/childremoved</t> lets a box receive
-        notification when a child is added/removed. In either
-        situation, the child will be passed as an argument to the trap
-        function <i>after</i> the addition or removal has been
-        performed.
-
-        Note that if the parent's redirect target is set to another
-        box, these traps will only be invoked when children are
-        manipulated by reading and writing to the parent.  Reads and
-        writes directly to the redirect target will <i>not</i> trigger
-        the traps.
-
-        Note also that these traps are still triggered if a box's
-        <t>redirect</t> target is <i>null</i>.  This is useful for
-        boxes that need to accept children and then relocate them
-        elsewhere.
-        </property>
-    
-    </section>
-
-  <section title="Notification Properties">
-    
-    The following properties are used to notify a box of changes specific
-    to that particular box.
-    
-    <property name="Enter">
-        The value <t>true</t> is written to this property when the mouse enters the box.
-        </property>
-    
-    <property name="Leave">
-        The value <t>true</t> is written to this property when the mouse leaves the box.
-        </property>
-    
-    <property name="SizeChange">
-        The value <t>true</t> is put to this property after the size
-        of this box changes.
-        </property>
-    
-    </section>
-
-  <section title="Root Box Properties">
-    
-    The following special properties are only meaningful on the root box
-    of a surface.
-    
-    <property name="Focused">
-        The value <t>true</t> is put to this property on the root box
-        when the surface gains the input focus, and <t>false</t> when
-        the surface loses the input focus. Reading from this value will
-        return <t>true</t> if the surface is focused and <t>false</t>
-        if it is not. Putting <t>true</t> to this property will
-        <i>not</i> cause the surface to "steal" the input focus from other
-        windows.
-        </property>
-    
-    <property name="Maximized">
-        The value <t>true</t> is put to this property on the root box
-        when the surface is maximized, and <t>false</t> when the surface
-        is un-maximized. Reading from this value will return <t>true</t>
-        if the surface is maximized and <t>false</t> if it is
-        not. Putting <t>true</t> to this property will maximize the
-        window, and putting <t>false</t> to this property will
-        unmaximize the window.
-        Note that not all platforms support maximization.
-        </property>
-    
-    <property name="Minimized">
-        The value <t>true</t> is put to this property on the root box
-        when the surface is minimized, and <t>false</t> when the surface
-        is unminimized. Reading from this value will return <t>true</t>
-        if the surface is minimized and <t>false</t> if it is
-        not. Putting <t>true</t> to this property will minimize the
-        window, and putting <t>false</t> will unminimize it.
-        </property>
-    
-    <property name="Close">
-        When the user attempts to close a surface, the value
-        <t>true</t> will be put to this property. Scripts may trap
-        this property FIXME defined later? to
-        prevent the window from closing. Putting the value
-        <t>true</t> to this property on a root box has the same
-        effect as putting <t>null</t> to the <t>thisbox</t>
-        property.
-        </property>
-    
-    <property name="icon">
-        The surface's icon. This is usually displayed on the titlebar of a
-        window. The value should be the stream name of a PNG image. Note
-        that not all platforms support this property.
-        </property>
-    
-    <property name="titlebar">
-        The surface's titlebar text. Note that not all platforms support
-        this property. Only ASCII characters 0x20-0x7F are permitted.
-        </property>
-    
-    </section>
-
-  </section>
-
-<!-- ----------------------------------------------------------------------- -->
-<section title="Streams">
-    
-  <section title="Every object has a stream...">
-
-    Every object has a <i>stream</i> associated with it.  A stream is a
-    sequence of bytes that can be read or written to.
-    
-    By default an object has an empty stream (zero bytes).  However, some objects
-    (returned from special methods on the <t>ibex</t> object) have
-    streams yielding data read from an url, file, or a component of a zip
-    archive.  In a future release, the stream associated with a box will
-    be an .ibex template which, when applied, will fully reconstitute the
-    box's state.
-    
-    </section>
-
-  <section title="...but streams are not objects">
-    
-    Despite the ubiquity of streams, you cannot actually reference a
-    stream, since it is not an object.  Instead, you simply reference the
-    object it belongs to.  If you are familiar with Java, this is similar
-    to how every Java object has a monitor associated with it, but you
-    cannot directly manipulate the monitor (you can't pass around a
-    reference to just the monitor).
-    
-    In the rest of the section we will sometimes refer to "getting
-    properties from a stream" or "passing a stream to a function"; this is
-    just shorthand for saying to perform those actions on the object the
-    stream belongs to.
-    
-    </section>
-
-  <section title="Creating Streams from URLs">
-    
-    You can create a stream from a URL by calling
-    
-    <pre>
-    var r = ibex.stream.url("http://...");
-    </pre>
-    
-    This will return an object whose stream draws data from the specified
-    URL.  Streams are loaded lazily whenever possible.
-    
-    </section>
-
-  <section title="Getting Substreams">
-
-    Most stream objects let you access
-    substreams using the usual JavaScript operators <t>[]</t> and
-    <t>.</t>, as well as the <t>for..in</t> syntax.
-    
-    <pre>
-    // r1 and r2 are equivalent but not equal (!=)
-    var r1 = ibex.stream.url("http://www.ibex.org/foo/bar.html");
-    var r2 = ibex.stream.url("http://www.ibex.org/foo")["bar.html"];
-    </pre>
-    
-    </section>
-
-  <section title="The Root Stream">
-
-    The empty-string property on the <t>ibex</t> object is called the
-    <i>root stream</i>.  You can access this object as <t>ibex..</t> or
-    <t>ibex[""]</t>.  Additionally, any expression which starts with a
-    dot is treated as property to be retrieved from the root stream.  The
-    following three expressions are equivalent:
-    
-    <pre>
-    ibex..foo
-    ibex[""].foo
-    .foo
-    </pre>
-
-    </section>
-
-  <section title="Static Blocks">
-
-    You can access variables within the static block of a template by
-    appending a double period (<t>..</t>) and the variable name to the
-    stream used to load that template:
-    
-    <pre>
-    <!-- org/ibex/themes/monopoly/scrollbar.ibex -->
-            foo = 12;
-    ...
-    // elsewhere
-    ibex.log.print(org.ibex.themes.monopoly.scrollbar..foo);   // prints "12"
-    </pre>
-    
-    </section>
-
-  <section title="Formatting Streams">
-
-    If you attempt to send a stream as part of an XML-RPC call, the
-    stream will be read in its entirity, Base64-encoded, and transmitted
-    as a <t><base64/></t> element.
-    
-    Ibex supports two special URL protocols.  The first is <t>data:</t>,
-    which inteprets the rest of the URL as a Base64 encoded sequence of
-    bytes to use as a source.  The other is <t>utf8:</t> which
-    interpretets the rest of the string as a Unicode character sequence to
-    be UTF-8 encoded as a string of bytes to use as a source.
-    
-    <pre>
-    var r5 = ibex.stream.url("data:WFWE876WEh99sd76f");
-    var r6 = ibex.stream.url("utf8:this is a test");
-    </pre>
-
-    You can read a UTF-8 encoded string from a stream like this:
-    
-    <pre>
-    var myString = ibex.stream.fromUTF(ibex.stream.url("utf8:this is a test"));
-    </pre>
-    You can also parse XML from a stream using SAX like this:
-    
-    <pre>
-    ibex.stream.xml.sax(
-        ibex.stream.url("http://foo.com/foo.xml"),
-            { beginElement : function(tagname, attributeKeyValuePairs) { ... },
-              endElement   : function(tagname) { ... },
-              content      : function(contentString) { ... }
-              whitespace   : function(whitespaceString) { ... }
-            });
-    </pre>
-    
-    </section>
-
-  </section>
-
-<!-- ----------------------------------------------------------------------- -->
-<section title="The Ibex object">
-
-    The <t>ibex</t> object is present in the top-level scope of every
-    script.  It has the following properties:
-    
-  <heading title="General"/>
-
-    <property name="ibex.box">
-        reading from this property returns a new box
-        </property>
-    <property name="ibex.clone(o)">
-        creates a clone of object
-        </property>
-    <property name="ibex.bless(s)">
-        returns a blessed clone of stream
-        </property>
-
-  <heading title="ECMA Library Objects"/>
-
-    <property name="ibex.date">
-        reading from this property returns a new date
-        </property>
-    <property name="ibex.math">
-        this object contains the ECMA math functions
-        </property>
-    <property name="ibex.regexp(s)">
-        return a regexp object corresponding to string <i>s</i>
-        </property>
-    <property name="ibex.string">
-        this object contains the ECMA string manipulation functions
-        </property>
-
-  <heading title="Logging"/>
-
-    <property name="ibex.log.debug(m, o)">
-        log the debug message <i>m</i>, optionally dumping object
-        <i>o</i>
-        </property>
-
-    <property name="ibex.log.info(m, o)">
-        log the informational message <i>m</i>, optionally dumping
-        object <i>o</i>
-        </property>
-
-    <property name="ibex.log.warn(m, o)">
-        log the warning message <i>m</i>, optionally dumping object
-        <i>o</i>
-        </property>
-
-    <property name="ibex.log.error(m, o)">
-        log the error message <i>m</i>, optionally dumping object
-        <i>o</i>
-        </property>
-
-    <heading title="User Interface"/>
-
-    <property name="ibex.ui.browser(u)">
-        opens a new browser window with URL <i>u</i>
-        </property>
-
-    <property name="ibex.ui.key.control">
-        true if the control key is depressed
-        </property>
-
-    <property name="ibex.ui.key.shift">
-        true if the shift key is depressed
-        </property>
-
-    <property name="ibex.ui.key.alt">
-        true if the alt key is depressed
-        </property>
-
-    <property name="ibex.ui.key.name.alt">
-        the name of the "alt" key (usually either "alt", "meta", or
-        "option")
-        </property>
-
-    <property name="ibex.ui.clipboard">
-        the contents of the clipboard; can be read and written to
-        </property>
-
-    <property name="ibex.ui.maxdim">
-        the maximum dimension of any UI element; usually
-        2<sup>31</sup>, but may be smaller
-        </property>
-
-    <property name="ibex.ui.screen.width">
-        the width of the screen, in pixels
-        </property>
-
-    <property name="ibex.ui.screen.height">
-        the height of the screen, in pixels
-        </property>
-
-    <property name="ibex.ui.mouse.button">
-        either 0, 1, 2, or 3, indicating the mouse button currently
-        being pressed
-        </property>
-
-    <property name="ibex.ui.frame">
-        when a box is written to this property, it becomes the root
-        box of a new window
-        </property>
-
-    <property name="ibex.ui.window">
-        when a box is written to this property, it becomes the root
-        box of a new frame
-        </property>
-
-    <property name="ibex.ui.font.serif">
-        an object whose stream is a a builtin serif font
-        </property>
-
-    <property name="ibex.ui.font.sansserif">
-        an object whose stream is a builtin sans-serif font
-        </property>
-
-    <property name="ibex.ui.font.monospace">
-        an object whose stream is a a builtin fixed-width font
-        </property>
-
-  <heading title="Networking"/>
-
-    <property name="ibex.net.http">
-        not yet implemented
-        </property>
-
-    <property name="ibex.net.rpc.xml(u)">
-        return an XML-RPC call object with endpoint URL <i>u</i>
-        </property>
-
-    <property name="ibex.net.rpc.soap(u,">
-        return a SOAP call object with endpoint URL <i>u</i>,
-        SoapAction <i>a</i>, and XML Namespace <i>n</i>
-        </property>
-
-  <heading title="Threads"/>
-
-    <property name="ibex.thread">
-        when a function is written to this property, a new thread is
-        forked to call it
-        </property>
-
-    <property name="ibex.thread.yield()">
-        yield the current thread
-        </property>
-
-    <property name="ibex.thread.sleep(n)">
-        sleep for <i>n</i> milliseconds
-        </property>
-
-  <heading title="Streams"/>
-
-    <property name="ibex.stream.url(u)">
-         returns a new object whose stream is drawn from URL <i>u</i>
-        </property>
-
-    <property name="ibex.stream.unzip(s)">
-        unpacks a zip archive from <i>s</i>'s stream
-        </property>
-
-    <property name="ibex.stream.uncab(s)">
-        unpacks a cab archive from <i>s</i>'s stream
-        </property>
-
-    <property name="ibex.stream.cache(s,k)">
-        valign=top>wraps a disk-backed read cache keyed on <i>k</i>
-        around <i>s</i>'s stream
-        </property>
-
-    <property name="ibex.stream.watch(s,f)">
-        returns an object whose stream is drawn from <i>s</i>'s
-        stream, but invokes <i>f(n,d)</i> as it is read from.
-        </property>
-
-    <property name="ibex.stream.parse.xml(s, h)">
-        Use SAX to parse the XML document on stream <i>s</i> with
-        handler <i>h</i>
-        </property>
-
-    <property name="ibex.stream.parse.html(s, h)">
-        Same as <t>parse.xml()</t>, but tries to fix broken HTML.
-        </property>
-
-    <property name="ibex.stream.parse.utf8(s)">
-        treat <i>s</i>'s stream as a string encoded as a UTF-8 byte stream and return the string
-        </property>
-
-    <property name="ibex.stream.homedir">
-        <t>ibex.stream.tempdir</t>
-        </property>
-
-  <heading title="Cryptography"/>
-
-    <property name="ibex.crypto.rsa(k,s)">
-        <i>not implemented yet:</i> return a
-        stream which rsa-decrypts stream <i>s</i> with key <i>k</i>
-        </property>
-
-    <property name="ibex.crypto.rc4(k,s)">
-        <i>not implemented yet:</i> return a
-        stream which rc4-decrypts stream <i>s</i> with key <i>k</i>
-        </property>
-
-    <property name="ibex.crypto.md5(s)">
-        <i>not implemented yet:</i> immediately
-        MD5-hash stream <i>s</i>
-        </property>
-
-    <property name="ibex.crypto.sha1(s)">
-        <i>not implemented yet:</i> immediately
-        SHA1-hash stream <i>s</i>
-        </property>
-
-</section>
-<!-- ----------------------------------------------------------------------- -->
-<section title="Traps">
-
-    You can add a trap to a property by applying the <t>++=</t> operator
-    to a function with one argument.  The trap will be invoked whenever
-    that property is written to.
-    
-    <pre>
-    <box>
-        foo ++= function(z) {
-           ibex.log.info("foo is " + z);
-        }
-    </box>
-    </pre>
-
-    If another script were to set the property "<t>foo</t>"
-    on the box above to the value <t>5</t>, the function above would be
-    invoked with the argument <t>5</t>. The function would then log
-    the string "<t>foo is 5</t>".
-    
-    Within a trap, the expression <t>trapee</t> can be used to
-    get a reference to the box on which the trap was placed.
-    
-    The expression <t>trapname</t> returns the name of the
-    trap executing the current function. This is useful when a function
-    is applied to multiple traps. For example:
-    
-    <pre>
-    <box>
-        func ++= function(z) {
-            ibex.log.info("called trap " + trapname);
-        }
-        foo ++= func;
-        bar ++= func;
-    </box>
-    </pre>
-    
-  <section title="Removing Traps">
-
-    You can remove a trap by using the <t>--=</t> operator with the same
-    function you added as a trap:
-    
-    <pre>
-    <box>
-        var myfunc = function(z) { /* ... */ }
-        // add the trap
-        func ++= myfunc;
-        // ...
-        // remove the trap
-        func --= myfunc;
-    </box>
-    </pre>
-    
-    </section>
-
-  <heading title="Multiple Traps on the Same Property"/>
-
-    When the property is <i>written</i> to, each of the trap functions placed
-    on it will be invoked in the opposite order that they were placed on
-    the box -- the most recently placed trap will execute first. This
-    last-to-first execution of traps is called <i>cascading</i>. After the
-    last trap is invoked, the value is stored on the box (remember, boxes
-    are objects, so they can hold properties just like all other
-    ECMAscript objects).
-    
-  <section title="Manual Cascades">
-
-    There are two additional tricks you can use when placing traps. The
-    first is a <i>manual cascade</i>. If you want to cascade to lower
-    traps in the middle of a function, or you want to cascade with a
-    different value than the value passed to you (in effect "lying" to
-    lower traps), you can use <t>cascade</t>. For example:
-    
-    <pre>
-    <box color="black">
-        color ++= function(c) {
-            ibex.log.info("refusing to change colors!");
-            cascade = "black";
-        }
-    </box>
-    </pre>
-
-    This effectively creates a box whose color cannot be changed, and
-    which complains loudly if you try to do so.
-    
-    Do <i>not</i> try to do something like this:
-    
-    <pre>
-    <box color="black">
-        color ++= function(z) {
-            color = "black";      // INFINITE LOOP! BAD!!!
-        }
-    </box>
-    </pre>
-    To prevent automatic cascading, return <t>true</t> from your function:
-    
-    <pre>
-    <box color="black">
-        color ++= function(z) {
-            return true;          // the box's color will not change
-        }
-    </box>
-    </pre>
-
-    </section>
-
-  <section title="Read Traps">
-
-    The other trick is a <i>read-trap</i>. Read traps are just like normal
-    traps, except that you  use a function that takes zero arguments instead of one. Read traps
-    also do not automatically cascade.
-    
-    <pre>
-    <box>
-        doublewidth <t>++=</t> function() { return 2 * width; }
-    </box>
-    </pre>
-
-    If another script attempts to read from the <t>doublewidth</t>
-    property on this box, the value it gets will be twice the actual width
-    of the box.  Note that
-    the actual <t>doublewidth</t> property on the box never gets written
-    to, since the trap does not cascade.
-    
-    You can manually cascade on read traps as well:
-    
-    <pre>
-    <box>
-        text <t>++=</t> function() { return "my text is " + cascade; }
-    </box>
-    </pre>
-
-    Read traps are only rarely needed -- most of the time a write trap
-    should be enough.
-    
-    </section>
-
-  <heading title="Prohibited Traps"/>
-
-    To prevent confusing and hard-to-debug behaviors, scripts may not
-    place traps on any of the properties described in the sections
-    <link text="Box Layout Properties" section="Layout Properties"/>, <link
-    section="Child-Control Properties"/>, or <link section="Other Box
-    Properties"/> except for <t>childadded</t>,
-    <t>childremoved</t> and <t>surface</t>.  FIXME: remove?
-    
-  <heading title="Exceptions and Traps "/>
-
-    If an uncaught exception is thrown from a trap, Ibex will log the
-    exception, but will <i>not</i> propagate it to the code which
-    triggered the trap. If the trap was a read trap, the value
-    <t>null</t> will be returned.
-    FIXME: is this right?
-
-  <heading title="Architectural Significance of Traps"/>
-
-    Traps are the backbone of Ibex. Since almost all UI programming is
-    event/demand driven, traps eliminate the need for separate
-    member/getter/setter declarations, often cutting the amount of typing
-    you have to do to a third of what it would normally be.
-
-  <section title="Cloning">
-
-    <i>Cloning</i> is a companion technique for traps; together they can
-    be used to simulate any sort of environment you might need.  When you
-    call <t>ibex.clone(o)</t>, Ibex returns a new object (called the
-    <i>clone</i>) which compares with equality (<t>==</t>) to the
-    original object.  Furthermore, both objects are "equal" as keys in
-    hashtables, so:
-    
-    <pre>
-    var hash = {};
-    var theclone = ibex.clone(o);
-    hash[o] = 5;
-    ibex.log.info(hash[theclone]);    // prints "5"
-    </pre>
-
-    Any writes to properties on the clone will actually write to
-    properties on the original object, and reads from properties on the
-    clone will read properties on the original object.  In fact, the only
-    thing that can be used to distinguish the original from the clone is
-    traps -- a trap placed on the clone is <i>not</i> placed on the
-    original object as well.
-    
-    </section>
-
-
-<!-- ----------------------------------------------------------------------- -->
-<section title="Threads">
-
-  <section title="Contexts">
-
-    From the perspective of an application writer, Ibex is strictly
-    single-threaded.  Ibex is always in exactly one of the following three
-    <i>contexts</i>:
-    
-    <list type="unordered">
-
-        <b>Rendering Context</b> -- (redrawing the screen)
-        
-        <b>Event Context</b> (executing javascript traps triggered by an event)
-        
-        <b>Thread Context</b> (executing a background thread spawned with <t>ibex.thread</t>)
-
-    </list>
-    
-    There are two important restrictions on what can be done in particular contexts:
-    
-    <list type="unordered">
-
-        The <t>box.mouse</t> property and its subproperties
-        (<t>x</t>, <t>y</t>, and <t>inside</t>) can only be read
-        from within the Event Context, or in a thread context
-        <i>after</i> a the <t>box.mouse</t> property on this box or
-        an ancestor box has been written to.
-        
-        Blocking operations (anything that accesses the network or
-        disk) can only be performed in the Thread Context.
-
-    </list>
-
-    </section>
-
-  <section title="Background Threads">
-
-    Ibex offers easy access to threads. Spawning a background thread is as
-    simple as writing a function to the <t>ibex.thread</t> property:
-    
-    <pre>
-    ibex.thread = function() {
-        ibex.log.info("this is happening in a background thread!");
-    }
-    </pre>
-
-    The argument set passed to the function is currently undefined and is
-    reserved for use in future versions of Ibex. Scripts should not
-    depend on the number or content of these arguments.
-    
-    Ibex is <i>cooperatively multitasked</i>, so threads must not process
-    for too long.  This was a deliberate choice; cooperatively
-    multitasked environments do not require complex locking primitives
-    like mutexes and semaphores which are difficult for novices to
-    understand.  The disadvantage of cooperative multitasking is that one
-    thread can hog the CPU.  This is unlikely to happen in Ibex for two reasons:
-    first, all blocking I/O operations <i>automatically</i> yield the CPU,
-    so the overall user interface never becomes unresponsive because it is
-    waiting for a disk or network transfer.  Second, since Ibex is strictly
-    a user interface platform, Ibex scripts are unlikely to perform highly
-    compute-intensive operations that keep the CPU busy for more than a
-    few milliseconds.
-    
-    </section>
-</section>
-
-<section title="Events">
-
-    Every execution of the Event Context begins with an event, which
-    consists of a key/value pair, and a mouse position, which consists of
-    an x and y coordinate.  The possible keys are <t>_Press[1-3]</t>,
-    <t>_Release[1-3]</t>, <t>_Click[1-3]</t>, <t>_DoubleClick[1-3]</t>,
-    <t>_Move</t>, <t>_KeyPressed</t>, and <t>_KeyReleased</t>.
-    
-    Here are two example events:
-    
-    An event is triggered by writing the key to the value on a box.  This
-    triggers any trap handlers which may be present.  Once these handlers
-    have executed, Ibex figures out which child of the current box contains
-    the mouse (taking into account that some boxes may cover up others)
-    and writes the key and value to that box.  If none of the box's
-    children contain the mouse position, Ibex removes the leading
-    underscore from the key name and writes the value to
-    <i>that</i> property.  Once all the traps on that property have
-    executed, the value is written to the box's parent.
-    
-    Intuitively, Ibex delivers the underscored event to every box from the
-    root to the target, and then delivers the non-underscored event to
-    that same set of boxes in reverse order.  So the event travels down
-    the tree to the target, and then back up to the root.  The following
-    example prints out "first second third fourth" in that order.
-    
-    <pre>
-    <box>
-        _Press1 ++= function(b) { ibex.log.info("first"); }
-         Press1 ++= function(b) { ibex.log.info("fourth"); }
-        <box>
-          _Press1 ++= function(b) { ibex.log.info("second"); }
-           Press1 ++= function(b) { ibex.log.info("third"); }
-        </box>
-    </box>
-    </pre>
-
-    In general, you should use the <i>non-underscore</i> names to respond
-    to user input and use the underscored names when you want to override
-    child boxes' behavior or route events to particular boxes (for
-    example, when implementing a focus protocol).  This is why the
-    underscored elements are delivered to parents before children (so
-    parents can override their childrens' behavior), but non-underscored
-    events are delivered to children before parents (since, visually, a
-    mouse click is usually "intended" for the leaf box underneath the
-    cursor).
-    
-    </section>
-
-  <heading title="Stopping the Process"/>
-
-    At any point in this sequence, a trap handler can choose not to
-    cascade (by returning <t>true</t> from the trap handler function).
-    This will immediately cease the propagation of the event.  This is how
-    you would indicate that an event has been "handled".
-    
-  <heading title="Enter and Leave"/>
-
-    Ibex will trigger the <t>Enter</t> and <t>Leave</t> properties as
-    it walks down the tree, based on the position of the mouse (or the
-    faked position if the <t>mouse</t> property has been written to).
-    However, <t>Enter</t> and <t>Leave</t> are not events since they
-    do not implicitly cascade up or down the tree.
-    
-  <section title="Listing of Events">
-    
-    <property name="Press1 / Press2 / Press3">
-        Indicates that the use has pressed a mouse button.  On
-        platforms with three mouse buttons, the <i>middle</i> button
-        is button 3 -- this ensures that applications written to only
-        use two buttons (1 and 2) will work intuitively on three button
-        platforms.
-        </property>
-    
-    <property name="Release1 / Release2 / Release3">
-        Indicates that the use has released a mouse button.
-        </property>
-    
-    <property name="Click1 / Click2 / Click3">
-        Indicates that the user has pressed and released the
-        mouse button without moving the mouse much (exactly how
-        much is platform-dependent).
-        </property>
-    
-    <property name="DoubleClick1 / DoubleClick2 / DoubleClick3">
-        Indicates that the user has clicked the 
-        mouse button twice within a short period of time (exactly how long is platform-dependent).
-        </property>
-    
-    <property name="Move">
-        Indicates that the mouse has moved while within this box, or that
-        the mouse while outside this box <i>if a button was pressed while within this box and has not yet been released</i>
-        </property>
-    
-    <property name="KeyPressed KeyReleased">
-        A string is written to this property when a key is pressed or
-        released If the key was any other key, a multi-character
-        string describing the key will be put. For simplicity, we use
-        the VK_ constants in the <link
-        url="http://java.sun.com/products/jdk/1.1/docs/api/java.awt.event.KeyEvent.html#VK_0"
-        text=" Java 1.1 API java.awt.event.KeyEvent class"/>. When a
-        key is pressed or released, the string put will be the portion
-        of its VK_ constant after the underscore, all in lower case.
-        If the shift key was depressed immediately before the event
-        took place, then the string will be capitalized. Special
-        keynames are also capitalized; shift+home is reported as
-        "<t>HOME</t>". Symbols are capitalized as they appear on the
-        keyboard; for example, on an American QWERTY keyboard, shift+2
-        is reported as "<t>@</t>".  If the alt, meta, or command key
-        was depressed immediately before this key was pressed, then
-        the string will be prefixed with the string "<t>A-</t>". If
-        the control key was depressed while this key was pressed, then
-        the string will be prefixed with the string "<t>C-</t>". If
-        both alt and control are depressed, the string is prefixed
-        with "<t>C-A-</t>".  Ibex does not distinguish between a key
-        press resulting from the user physically pushing down a key,
-        and a 'key press' resulting from the keyboard's typematic
-        repeat. In the rare case that an application needs to
-        distinguish between these two events, it should watch for
-        KeyReleased messages and maintain an internal key-state
-        vector.
-        </property>
-
-    </section>
-
-</section>
-
-<!-- ----------------------------------------------------------------------- -->
-<section title="Networking">
-    
-  <section title="XML-RPC">
-    
-    XML-RPC objects can be created by calling <t>ibex.net.rpc.xml(<i>XML-RPC
-    URL</i>)</t>, and then invoking methods on that object. For example,
-    
-    <pre>
-    Press1 += function(v) {
-        ibex.thread = function() {
-            color = ibex.net.rpc.xml("http://xmlrpc.ibex.org/RPC2/").
-                       color.getTodaysColor("Friday");
-        }
-    }
-    </pre>
-    
-    When the user clicks the first mouse button on this box, it will
-    contact the server <t>xmlrpc.ibex.org</t>, route to the
-    <t>/RPC2/</t> handler and invoke the <t>getTodaysColor()</t>
-    method on the <t>color</t> object with a single string argument
-    "<t>Friday</t>". The return value will be used to change the color
-    of the box the user clicked on.
-    
-    Note that in this example we spawned a background thread to handle the
-    request -- the <t>Press1</t> event is delivered in the foreground
-    thread, and XML-RPC methods may only be invoked in background
-    threads. This is to prevent the UI from "locking up" if the server
-    takes a long time to reply.
-    
-    If the XML-RPC method faults, an object will be thrown with two
-    properties: <t>faultCode</t> and <t>faultString</t>, as defined in
-    the <link url="http://www.xmlrpc.org/spec" text="XML-RPC specification"/>. If
-    Ibex encounters a network, transport, or session-layer error, it will
-    throw a <t>String</t> object describing the error in a
-    human-readable format. Scripts should not rely on the contents of
-    this string having any special structure or significance.
-    
-    If an object with an associated non-empty stream is passed as an
-    argument to an XML-RPC method, it will be sent as a <base64/>
-    element. If a <base64/> element is found in the XML-RPC reply, it
-    will be returned as an object with a stream drawn from that byte sequence.
-    
-    Each object returned by <t>ibex.net.rpc.xml()</t> represents a
-    single HTTP connection.  The connection will be held open until
-    the object is garbage collected or the server closes the
-    connection.  If a second call is issued on the object before the
-    first one returns (usually from a seperate thread), the two calls
-    will be <link
-    url="http://www.w3.org/Protocols/rfc2616/rfc2616-sec8.html#sec8.1.2.2"
-    text="pipelined"/>.  This can dramatically improve performance.
-    
-    Ibex supports HTTP Basic and Digest authentication. To use
-    authentication, pass <t>ibex.net.rpc.xml()</t> a URL in the form
-    <t>http[s]://user:password@hostname/</t>.  Ibex will use Digest
-    authentication if the server supports it; otherwise it will use
-    Basic authentication.  Please be aware that many XML-RPC server
-    implementations contain a <link
-    url="http://www.ibex.org/faq.html#auth" text="broken implementation of Basic authentication"/>.
-    
-    </section>
-
-  <section title="SOAP">
-    
-    SOAP methods are invoked the same way as XML-RPC methods, but with three differences:
-    
-    <list type="ordered">
-
-        <t>ibex.net.rpc.soap()</t> is used instead of
-        <t>ibex.net.rpc.xml()</t>
-        
-        Instead of specifying just the URL of the service itself, you
-        must specify the URL, the SOAPAction argument, and the
-        namespace to use.
-        
-        The actual method invocation takes only one argument, which
-        must be an object. This is necessary since SOAP arguments are
-        specified by name, rather than ordering.
-
-    </list>
-    
-    SOAP faults are handled the same way as XML-RPC faults except that the
-    capitalization of the <t>faultstring</t> and <t>faultcode</t>
-    members is all lower-case, to match the SOAP spec. Here is a
-    SOAP example:
-    
-    <pre>
-    Press1 ++= function(v) {
-        ibex.thread = function() {
-            color = ibex.net.rpc.soap("http://soap.ibex.org/SOAP",
-                                     "GETTODAYSCOLOR",            
-                                     "http://ibex.org/namespace"  
-                                ).color.getTodaysColor( {
-                                    whichday : Friday
-                                } );
-        }
-    }
-    </pre>
-
-    As you can see, SOAP is much more verbose, yet does not offer
-    substantially improved functionality. We recommend that XML-RPC be
-    used whenever possible, and that SOAP be reserved for legacy
-    applications.
-    
-    The current Ibex SOAP stack does not support 'document style' or
-    multi-ref (<t>href</t>) data structures.
-    
-    </section>
-
-  <section title="Security">
-
-    Applications downloaded from the network (as opposed to those loaded
-    from the filesystem) may only make certain kinds of connections to
-    certain hosts.  See Appendix A for a detailed description of the
-    security policy.
-    
-    </section>
-
-  </section>
-<!-- ----------------------------------------------------------------------- -->
-<section title="Error Handling">
-
-    If the Ibex Core encounters an error while servicing a function call
-    originating in JavaScript, the core will throw a string consisting of
-    an error code followed by a colon, a space, and a descriptive message.
-    For example:
-    
-    <pre>
-    "ibex.net.dns.unknownhostexception: unable to resolve host foo.com"
-    </pre>
-
-    The code should be used to determine how the program should respond to
-    an error.  The codes are organized in a hierarchy, so the
-    string.startsWith() method can be used to determine if an error lies
-    within a particular subhierarchy.  The descriptive message portion of
-    the string may be shown to the user.
-    
-    <property name="ibex.assertion.failed">
-        an assertion failed
-        </property>
-    <property name="ibex.io">
-        General I/O exceptions
-        </property>
-    <property name="ibex.io.encoding">
-        Error translating between character encodings.
-        </property>
-    <property name="ibex.io.zip">
-        Attempted to access a corrupt zip archive.
-        </property>
-    <property name="ibex.io.eof">
-        End of file encountered unexpectedly
-        </property>
-    <property name="ibex.net.security.prohibitedHost">
-        A piece of untrusted Ibex code attempted to contact a
-        restricted host.  See <link appendix="Security Architecture and Considerations"/> for details.
-        </property>
-    <property name="ibex.net.dns.temporaryFailure">
-        An attempt to resolve a hostname failed but it is not known
-        for certain that the hostname is invalid.
-        </property>
-    <property name="ibex.net.dns.unknownHost">
-        An attempt to resolve a hostname failed because the hostname
-        was invalid.
-        </property>
-    <property name="ibex.net.socket.closed">
-        A socket was closed unexpectedly.
-        </property>
-    <property name="ibex.net.socket.connectionFailed">
-        A connection could not be made to the remote host.
-        </property>
-    <property name="ibex.net.url.malformed">
-        Tried to parse a malformed URL.
-        </property>
-    <property name="ibex.net.ssl">
-        General SSL protocol errors.
-        </property>
-    <property name="ibex.net.ssl.untrustedCertificate">
-        The server's certificate was not signed by a CA trusted by Ibex.
-        </property>
-    <property name="ibex.net.http.">
-        Thrown when an HTTP error code is returned during an
-            operation.  The three characters <t><i>xyz</i></t> will be
-            the three-digit HTTP status code.
-        </property>
-    <property name="ibex.net.xmlrpc.null">
-        The caller attempted to transmit the <t>null</t> value via XML-RPC.
-        </property>
-    <property name="ibex.net.xmlrpc.circular">
-        The caller attempted to transmit a circular data structure via XML-RPC.
-        </property>
-    <property name="ibex.net.xmlrpc.specialObject">
-        The caller attempted to transmit a "special" object via
-        XML-RPC (for example, a Box or the Ibex object).
-        </property>
-    <property name="ibex.null.put">
-        A JavaScript attempted to put to a property on the <t>null</t> value
-        </property>
-    <property name="ibex.null.get">
-        A JavaScript attempted to get from a property on the <t>null</t> value
-        </property>
-    <property name="ibex.null.call">
-        A JavaScript attempted to call the <t>null</t> value
-        </property>
-    
-    If an exception is thrown inside a trap, the exception will propagate
-    to the script that triggered the trap.
-    
-    If an uncaught exception is thrown while applying a template, or the
-    requested template could not be found, an error will be logged and the
-    box to which the template was being applied will be made invisible
-    (<t>visible = false</t>).  This ensures that half-applied widgets are
-    never shown to the user.
-    
-  </section>
-
-<!-- ----------------------------------------------------------------------- -->
-<section title="Advanced Topics">
-
-  <section title="Re-routing events">
-
-    At any point in the Event Context, you can write to the <t>mouse</t>
-    property on any box.  The value written should be an object with two
-    properties, <t>x</t> and <t>y</t>.  For example:
-    
-    <pre>
-    _Press1 ++= function(p) {
-        mouse = { x: 32, y: 77 };
-    }
-    </pre>
-
-    The coordinates specified are relative to the box whose <t>mouse</t>
-    property is being written to.  There is no need to supply the
-    <t>inside</t> property; it is computed automatically.  Writing to
-    the <t>mouse</t> property causes Ibex to recompute the eventual
-    target box, and also alter the values returned by <t>mouse.x</t>,
-    <t>mouse.y</t>, and <t>mouse.inside</t> for any <i>descendants</i>
-    of the current box.  Writing to the <t>mouse</t> property also
-    automatically prevents the event from returning to the box's parents
-    -- it is equivalent to not cascading on the non-underscored event.
-    This ensures that child boxes cannot trick their parent boxes into
-    thinking that the mouse has moved.
-    
-    If you want the event to "skip over" the boxes between the trapee
-    and the target, or if you want to re-route an event to a box which
-    is not a descendant of the current box, simply write the value to
-    the proper key on the target box.
-    
-    <pre>
-    <box>
-        _KeyPressed = function(k) { ibex.log.info("first"); }
-         KeyPressed = function(k) { ibex.log.info("sixth"); }
-        $recipient.target = $target;
-        <box id="recipient">
-            _KeyPressed = function(k) {
-                ibex.log.info("second");
-                thisbox.target.KeyPressed = k;
-                // inhibit cascade; keep event from going to $excluded
-                return true;
-            }
-             KeyPressed = function(k) { ibex.log.info("fifth"); }
-            <box id="excluded">
-                _KeyPressed = function(k) {
-                   ibex.log.info("this never happens");
-                }
-            </box>
-        </box>
-        <box id="target"> 
-            _KeyPressed = function(k) { ibex.log.info("third"); }
-             KeyPressed = function(k) { ibex.log.info("fourth"); }
-        </box>
-    </box>
-    </pre>
-
-    </section>
-
-  <section title="Synthesizing Your Own Events">
-
-    You can create "fake events" by simply writing to the <t>mouse</t>
-    property and then writing a value to one of the underscored properties
-    on a box.  This will have exactly the same effect as if the use had
-    actually pressed a key, clicked a button, or moved the mouse -- they
-    are indistinguishable.
-    
-    </section>
-
-  <section title="Ibex self-emulation">
-
-    When the core first starts up, it clones the <t>ibex</t> object,
-    creates a stream for the initial .ibex, and then places a trap on the
-    cloned <t>ibex</t> object so that its empty-string property returns
-    the .ibex stream.  The cloned Ibex object is then passed as the third
-    (optional) argument to <t>ibex.apply()</t>, making it the default
-    <t>ibex</t> object for the scripts that are executed as part of the
-    template instantiation.
-    
-    <pre>
-    var new_ibex = ibex.clone(ibex);
-    var stream = ibex.bless(ibex.stream.url("http://..."));
-    new_ibex[""] ++= function() { return stream; }
-    ibex.apply(ibex.box, new_ibex..main, new_ibex);
-    </pre>
-
-    Note that we called <t>ibex.bless()</t> on the stream before tacking
-    it on to the new Ibex object.  The bless function returns a clone of
-    the object passed to it, with a few traps which are explained below.
-    Additionally, any sub-streams retrieved by accessing properties of the
-    blessed stream will also automatically be blessed (blessed streams are
-    <i>monadic</i>).
-    
-    Blessing a stream serves three purposes:
-    
-    <list type="unordered">
-        
-        Blessed clones always return the appropriate static block when
-        their empty property is accessed; this ensures that references
-        to the static blocks of other templates work properly.
-        
-        Blessed substreams can return their parent stream by accessing
-        a hidden property which is reserved for internal use by Ibex.
-        This ensures that Ibex can automatically add filename
-        extensions where needed, according to the following rules:
-
-        <list>
-            If the stream is a template to be applied, the string
-            "<t>.ibex</t>" is appended.
-        
-            If the stream is an image, the string "<t>.png</t>" is
-            appended.  If no stream is found, "<t>.jpeg</t>" and
-            "<t>.gif</t>" are tried, in that order.
-        
-            If the stream is an font, the string "<t>.ttf</t>" is
-            appended.
-        </list>
-        
-        Every call to <t>ibex.bless()</t> returns a different object
-        (which happens to be a clone of the object passed to it) with
-        a completely separate set of static blocks.
-
-    </list>
-
-    Ibex can self-emulate by using <t>ibex.clone()</t> on the Ibex object;
-    this technique is very similar to the use of ClassLoaders in
-    Java. This is useful for a number of applications, including
-    debuggers, IDEs, sandboxing untrusted code, remote-control, and
-    others.  For example:
-    
-    <pre>
-    var newLoadFunction = function(url) { /* ... */ };
-    var new_ibex = ibex.clone(ibex);
-    new_ibex.load ++= function() { return newLoadFunction; }
-    ibex.apply(ibex.box, .main, new_ibex);
-    </pre>
-  </section>
-</section>
-
-<!-- ----------------------------------------------------------------------- -->
-<appendix title="Security Architecture and Considerations">
-    
-    Due to the expense and hassle imposed by the commercial PKI code
-    signing architecture, and the fact that it <link
-    url="http://www.counterpane.com/pki-risks-ft.txt" text="doesn't
-    really provide any security anyways"/>, Ibex user interfaces are
-    distributed as unsigned, untrusted code. As such, they are handled
-    very carefully by the Ibex Core, and assumed to be potentially
-    malicious.
-    
-    Ibex's security architecture is divided into defenses against four
-    major classes of attacks:
-    
-  <heading title="Malicious UI attempts to acquire or alter data on the client"/>
-    
-    Ibex user interfaces are run in an extremely restrictive sandbox. The
-    environment does not provide primitives for accessing any data outside
-    the Ibex core except via XML-RPC and SOAP calls. There are no
-    facilities to allow Ibex user interfaces to access the client's
-    operating system or to interact with other applications on the same
-    host (unless they provide a public XML-RPC or SOAP interface).
-    An Ibex script may only access a file on the user's hard disk if the
-    user explicitly chooses that file from an "open file" or "save file"
-    dialog. There is one exception to this rule: if all templates
-    currently loaded in the Ibex core originated from the local
-    filesystem, those templates can load additional .ibexs from the local
-    filesystem.
-    
-    The Ibex Core is written in Java, so it is not possible for
-    scripts to perform buffer overflow attacks against the core
-    itself.
-    
-    Ibex applications may only read from the clipboard when the user
-    middle-clicks (X11 paste), presses control-V (Windows paste), or
-    presses alt-V (Macintosh paste; the command key is mapped to Ibex
-    "alt"). This ensures that Ibex applications are only granted access to
-    data that other applications have placed on the clipboard when the user
-    specifically indicates that that information should be made available
-    to the Ibex application.
-    
-  <heading title="Malicious UI attempts to use client to circumvent firewalls"/>
-    
-    Ibex user interfaces may only make XML-RPC or SOAP calls and load .ibex
-    archives via HTTP; they cannot execute arbitrary HTTP GET's or open
-    regular TCP sockets.
-    
-    Ibex will not allow a script to connect to a non-public IP address
-    (10.0.0.0/8, 172.16.0.0/12, or 192.168.0.0/16, as specified in <link
-    url="http://www.cis.ohio-state.edu/cgi-bin/rfc/rfc1918.html" text="RFC
-    1918"/>). There is one exception -- if all templates currently loaded
-    in the core originated from the same IP address, those scripts may
-    make calls to that IP address regardless of whether or not it is
-    firewalled.  If Ibex does not have access to a DNS resolver (because it
-    is using a proxy which performs DNS lookups), Ibex will provide the
-    proxy with the appropriate <link
-    url="http://www.ibex.org/x-requestorigin.html"
-    text="X-RequestOrigin"/> header that the proxy needs in order
-    to maintain security.
-    
-    The only remaining possible attack is against a XML-RPC or SOAP
-    service running on a firewalled host with a public address. Assigning
-    such machines public IP addresses is a poor network security policy,
-    and doing so squanders scarce public IPv4 addresses. As such, the onus
-    is on the administrators of such machines to explicitly block access
-    to clients reporting a <t>User-Agent:</t> header beginning with the
-    three characters "<t>Ibex</t>".
-    
-  <heading title="Malicious UI attempts to trick user into divulging secret information"/>
-    
-    All top-level windows created by Ibex are <i>scarred</i> -- a stripe
-    and a lock is drawn across the corner of the window. There is no way
-    for a user interface to remove this scar. Ibex user interfaces may not
-    create windows smaller than the size of the scar.
-    
-  <heading title="Malicious network attempts to snoop or man-in-the-middle transactions"/>
-    
-    Ibex user interfaces may transmit network data using HTTPS (SSL 3.0)
-    for encryption. Ibex will attempt 128-bit encryption, but will
-    negotiate down to 40-bit if the server does not support strong
-    crypto. Ibex's SSL implementation is currently provided by <link
-    url="http://www.ibex.org/tinyssl" text="TinySSL"/> and <link
-    url="http://www.bouncycastle.org" text="The Legion of the Bouncy
-    Castle."/>
-    
-    All HTTPS connections must be authenticated by the server using a
-    certificate whose name matches the domain name of the HTTPS URL. The
-    certificate must be signed by a trusted root CA. Ibex trusts the same
-    93 root CAs whose certificates are included as "trusted" in Microsoft
-    Internet Explorer 5.5 SP2. This provides a minimal level of protection
-    against man-in-the-middle attacks; you should not trust this
-    connection with any data you would not normally trust an SSL-enabled
-    web browser with.
-    
-</appendix>
-
-<!-- ----------------------------------------------------------------------- -->
-<appendix title="ECMAscript compliance">
-    
-    Ibex's scripts are written in a modified subset of ECMA-262, revision 3
-    (aka JavaScript 1.5). The interpreter strays from the spec in a few
-    ways.
-    
-  <section title="Omissions">
-    
-    The following ECMA features are not supported:
-    
-    <list type="unordered">
-
-        The <t>undefined</t> value, <t>===</t>, and <t>!==</t>
-        
-        The <t>new</t> keyword (and ECMAScript object inheritance)
-        <t>eval</t>
-        
-        <t>getter</t> and <t>setter</t>
-        
-        The ECMA <t>this</t> keyword.
-        
-        The <t>String</t>, <t>Number</t>, and <t>Boolean</t>
-        classes.  Note that <t>string</t>, <t>number</t>, and
-        <t>boolean</t> values are supported, however.
-        
-        You may not <t>throw</t> the <t>null</t> value.
-
-    </list>
-    
-    Additionally, you must declare all root-scope variables (with
-    <t>var</t>) before using them; failure to do so will result in an
-    exception.  Box properties are pre-defined in the scope that scripts
-    are executed in.
-    
-    </section>
-
-  <section title="Extensions">
-    
-    <list type="unordered">
-    
-        The token <t>..</t> is equivalent to <t>[""]</t>.
-    
-        Trapping
-    
-        Cloning
-    
-        Extended <t>catch</t> syntax.  The following code:
-        <pre>
-        } catch(e propname "foo.bar.baz") {
-           // ...
-        }
-        </pre>
-        Is equivalent to:
-        <pre>
-        } catch(e) {
-           if (e.propname != null and e.propname >= "foo.bar.baz" and
-               "foo.bar.baz/" > e.propname) {
-               // ...
-           }
-        }
-        </pre>
-        Multiple extended-catch blocks can appear at the end of a single try
-        block.  However, at most one non-extended catch block may appear, and
-        if it does appear, it must be the last one.
-    
-        Since Ibex ECMAscripts are wrapped in XML, the lexical token
-        "<t>lt</t>" is be interpreted as <t>&lt;</t>, the lexical
-        token "<t>gt</t>" is be interpreted as <t>&gt;</t>, and the
-        token "<t>and</t>" is interpreted as <t>&amp;&amp;</t>.
-        Thus these tokens cannot be used as variable names.
-    
-        The identifier <t>static</t> is a reserved word in
-        ECMAScript, but not in Ibex.
-    
-        Ibex defines an additional reserved word, "<t>assert</t>",
-        which will evaluate the expression which follows it, throwing
-        a <t>ibex.assertion.failed</t> exception if the expression
-        evaluates to <t>false</t>.
-    
-        To ensure that Ibex files appear the same in all text editors, tab
-        characters are not allowed in Ibex files.
-
-    </list>
-    
-    Some useful tutorials include:
-    
-    <list type="unordered">
-        
-        Netscape's <link
-        url="http://developer.netscape.com/docs/manuals/communicator/jsref/index.htm"
-        text=" JavaScript 1.2 Reference"/>. Although this document is
-        out of date, it is arguably the best guide available for free
-        on the Internet. The changes from JavaScript 1.2 (aka ECMA-262
-        r1) to 1.5 were minimal, and many of them were <link
-        url="ecmascriptcompliance" text="omitted"/> from Ibex.
-        
-        O'Reilly's <link
-        url="http://search.barnesandnoble.com/booksearch/isbnInquiry.asp?isbn=0596000480"
-        text=" JavaScript: The Definitive Guide"/>, by David Flanagan
-        and Paula Ferguson. The latest edition of this book covers
-        JavaScript 1.5 (ECMA-262 r3).
-        
-        The official <link
-        url="http://www.ecma.ch/ecma1/STAND/ECMA-262.HTM"
-        text="ECMA-262"/> specification. This is an extremely
-        technical document.
-
-    </list>
-    </section>
-</appendix>
-
-<!-- ----------------------------------------------------------------------- -->
-<appendix title="Logging and Command Line Invocation">
-    
-    Very early in the loading process, Ibex begins logging messages about
-    what it is doing.  Where this output is logged to differs by platform;
-    currently it goes to standard output when running inside a JVM, and to
-    <t>$TMPDIR\ibex-log.txt</t> on Win32 (where <t>$TMPDIR</t> is the
-    value returned by <t>GetTempPath()</t>). The logs contain a lot of
-    valuable debugging information and performance hints; if you are
-    having trouble developing an Ibex application, be sure to check the
-    logs.
-    
-    If Ibex encounters a serious problem before it starts logging
-    information, or if it is unable to open the log file, it will abort
-    immediately with a critical abort, which will be displayed on the
-    console for POSIX-native cores and in a dialog box for JVM-based and
-    Win32-native cores.
-    
-    You can invoke Ibex directly from the command line during
-    development. When using a JVM, the invocation format is:
-    
-    <pre>    
-  java -jar path-to-ibex-jar [-sv] source-location [initial-template]
-    </pre>
-    
-    Where <t><i>path-to-ibex-jar</i></t> is the path to <t>ibex.jar</t>,
-    which can be downloaded <link url="http://www.ibex.org/dist/ibex.jar" text="here"/>.
-    
-    On Win32, the invocation format is:
-    
-    <pre>
-    ibex.exe [-v] source-location [initial-template]
-    </pre>
-    
-    The file <t>ibex.exe</t> is placed in Windows' ActiveX cache
-    directory the first time Ibex is used on the machine. The ActiveX
-    cache location depends on what version of Windows you are using;
-    on newer versions of Windows it is <t>C:\WINDOWS\DOWNLOADED
-    PROGRAM FILES\</t>. You can also extract <t>ibex.exe</t> from
-    <t>ibex.cab</t>, which is available <link
-    url="http://www.ibex.org/dist/ibex.cab" text="here"/>.
-    
-    The <t><i>source-location</i></t> parameter can be either the path
-    to an .ibex archive, the http url of an .ibex archive, or the path to a
-    directory comprising an unpacked .ibex archive.
-    
-    The <t><i>initial-template</i></t> parameter is the stream name of
-    a template to be used as the initial template. If ommitted, it
-    defaults to <t>main</t>.
-    
-    The <t>-v</t> option causes Ibex to enable verbose logging; this will
-    cause it to log <i>lots</i> of information to the log file. This
-    option will also substantially decrease Ibex's performance.
-    
-  </appendix>
-
-<!-- ----------------------------------------------------------------------- -->
-    <!--
-<appendix title="Grammars">
-
-    <i>Grammar support is experimental in this release
-    and may not work properly.  It may change in incompatible ways or
-    disappear completely from future releases</i>
-    
-    Grammars are defined with a statement in the following form:
-    
-    <pre>
-    a ::= b { c }
-    </pre>
-    A grammar is really just another function; once defined you can't tell
-    it apart from an ordinary function.  A grammar takes one argument,
-    which can be a string or stream.  The argument is parsed and the
-    result of executing the code block 'c' is returned.
-    
-    The property 'a' is read; if the value is a grammar, a new production
-    rule (ie a new alternative, as with '<t>|</t>') is added to that grammar
-    (this is a destructive update).  This allows you to add productions to
-    pre-existing grammars (for example, adding a new type of expression to
-    a programming language by extending the 'expr' grammar).  If the old
-    value is not a grammar, the value is discarded and a new grammar
-    object is created.
-    
-    The value 'b' is a pattern, which may consist of seven simple
-    primitives:
-    
-    <list type="unordered">
-        string literals
-         
-        grouping parens <t>()</t>
-         
-        combinators:   <t> | + * ?</t>
-         
-        references to other grammars
-    </list>
-
-    The value 'c' and the braces surrounding it are an *optional* code
-    block, in which the following identifiers are bound:
-    
-    <list type="unordered">
-         
-       The identifier 'whole' is bound to the string matched by the
-       entire expression.  If the code block is omitted it behaves
-       as if it were "<t>{ return whole; }</t>".
-         
-       For every reference to another grammar which was matched in the
-       pattern, the *name used to reference that other grammar* will
-       be bound to the value returned by its code block.  Here's an
-       example of this important distinction:
-        
-       <pre>
-       var foo ::= 'a' | 'b';
-       var bar ::= foo;
-       var baz ::= 'c' | bar    {  /* foo is not defined here, but bar is */ };
-       </pre>
-        
-       On the last line, the identifier 'bar' serves two purposes: it
-       pulls in the definition of the pattern *and* acts as a binder
-       within the scope of the braces.
-        
-       If a reference is matched multiple times (either because it
-       appears multiple times in the pattern or because the * or +
-       operator was applied to it) then its name will be bound to an
-       array containing the matches.
-
-    </list>
-
-    Here is the metacircular definition of the grammar facility:
-    
-    <pre>
-         grammar ::= identifier '::=' pattern (';' | '{' code '}' ';'?)
-      identifier ::= ('a'..'z' | 'A'..'Z' | '_' | '$') (identifier | '0'..'9')*
-            char ::= '\0x0000'..'\0xffff'
-         literal ::= '\'' char+ '\''
-                   | '\'' char '\'' '..' '\'' char '\''
-         pattern ::= identifier
-                   | literal
-                   | '(' pattern ')'
-                   | pattern '+'
-                   | pattern '?'
-                   | pattern '*'
-                   | pattern pattern
-                   | pattern '|' pattern
-    </pre>
-    -->
-    
-<i>
-Copyright (C) 2004 Adam Megacz, verbatim redistribution permitted.
-Ibex is a trademark of Adam Megacz
-</i>
-    
-</ibex-doc>
\ No newline at end of file