added reference in new xml format
authoradam <adam@megacz.com>
Mon, 22 Mar 2004 06:57:47 +0000 (06:57 +0000)
committeradam <adam@megacz.com>
Mon, 22 Mar 2004 06:57:47 +0000 (06:57 +0000)
darcs-hash:20040322065747-5007d-783fdee8ab45209e01130134ac7611be891a4167.gz

doc/reference.xml [new file with mode: 0644]

diff --git a/doc/reference.xml b/doc/reference.xml
new file mode 100644 (file)
index 0000000..37b410d
--- /dev/null
@@ -0,0 +1,2439 @@
+<ibex-doc title="The Ibex Reference">
+    
+    Nitrogen Release
+    
+    by <link url="mailto:adam@ibex.org" text="Adam Megacz"/>
+    
+<!-- ----------------------------------------------------------------------- -->
+<section title="Preface">
+    
+    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 section="Appendix G"/>
+    
+    The <i>shoehorn sequence</i> (how the Ibex Core gets onto the
+    client's computer, and how it knows where to download the initial .ibex
+    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>
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="Key Concepts">
+
+  <section title="Definitions">
+    
+    <definition term="The Core">
+         Ibex itself; the native code (or Java bytecode) that runs on
+         the client.  This term does not include the <i>shoehorn</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 Shoehorn">
+         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
+         Shoehorn 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
+         "<tt>foo.bar = 5</tt>" <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 "<tt>return (3 + foo.bar)</tt>" <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
+        section="Appendix C"/> for details).  </definition>
+    
+    </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").
+    
+    <font color=red>FIXME: diagram here</font>
+    
+    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>
+
+  <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 <tt>clip</tt> attribute is <tt>false</tt>, 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:
+    
+    <font color=red>FIXME: diagram</font>
+    
+    <list type="unordered">
+
+        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.
+
+            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.
+
+        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 <tt>scrollbar</tt> 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 title="Templates">
+
+    Each template is an XML document whose root element
+    is <tt>&lt;ibex></tt>.  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>
+    
+    </section>
+
+  <section 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.  <font color=RED>FIXME:
+    easier description</font>.  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 <b>X</b> to a box <b>B</b>, perform the following
+    operations, in this order:
+    
+    <list type="ordered">
+
+        Allocate a fresh scope <b>s</b> whose parent scope is
+        <b>B</b>.
+        
+        Process each child element or text segment of <b>X</b> in the
+        order they appear in the document: For each <i>text
+        segment</i> <b>t</b>:
+
+            Treat <b>t</b> a JavaScript script, and execute it
+            with <b>s</b> as the root scope.
+
+        For each <i>child element</i> <b>x</b> of <b>X</b>:  
+
+            Create a new box <b>b</b>.
+            
+            If the name of tag <b>x</b> is not <tt>"box"</tt> (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 <b>b</b>.
+            
+            (recursively) apply <b>x</b> to <b>b</b>.
+            
+            If <b>x</b> has an <tt>id</tt> attribute, declare a variable
+            in <b>s</b> whose name is the value of the <tt>id</tt>
+            attribute, prefixed with the <tt>$</tt> character, and whose
+            value is <b>b</b>
+            
+            Copy any <tt>$</tt>-variables created during the application
+            of <b>x</b> into scope <b>s</b>.
+            
+            Append <b>b</b> as the last child of <b>B</b>.
+        
+        Apply any attributes on <b>X</b> to <b>B</b>, except for
+        <tt>id</tt>.  Since XML specifies that the order of attributes
+        cannot be significant, Ibex processes attributes in
+        alphabetical order by attribute name.  For example, if
+        <b>X</b> has the attribute <tt>foo="bar"</tt>, then the
+        equivalent of the statement <tt>B.foo="bar";</tt> will be
+        performed, with the following exceptions:
+
+            If the value portion of the attribute is the string
+            <tt>"true"</tt>, put the boolean <tt>true</tt>. If the
+            value is <tt>"false"</tt>, put the boolean <tt>false</tt>.
+        
+            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 (<tt>$</tt>),
+            retrieve the value of the corresponding variable in
+            <b>s</b> and use that value instead.
+         
+            If the value begins with a dot (<tt>.</tt>), 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>
+
+    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>shoehorn</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 <tt>main.ibex</tt> 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.
+    
+    <font color="red">
+    DIAGRAM: graphic here showing the circular feedback cycle.
+    </font>
+    
+    The Ibex core quits when the last remaining surface has been destroyed.
+    
+    </section>
+
+  </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 <tt>minwidth</tt>, 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
+    <tt>maxwidth</tt> and <tt>maxheight</tt> 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
+    <tt>minwidth</tt> and <tt>minheight</tt>.  If the <tt>hshrink</tt> or
+    <tt>vshrink</tt> 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 <tt>align</tt> property is <tt>"center"</tt>, then the
+        alignment point is the center of the box.
+        
+        If the <tt>align</tt> property is <tt>"topleft"</tt>,
+        <tt>"bottomleft"</tt>, <tt>"topright"</tt>, or
+        <tt>"bottomright"</tt>, then the alignment point is
+        corresponding corner of the box.
+        
+        If the <tt>align</tt> property is <tt>"top"</tt>,
+        <tt>"bottom"</tt>, <tt>"right"</tt>, or <tt>"left"</tt>, then
+        the alignment point is middle of the corresponding edge of the
+        box.
+
+    </list>
+
+    <font color=red>FIXME: diagram</font>
+    
+    When positioning a child box, the alignment point is determined by the
+    <i>parent's</i> <tt>align</tt> 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> <tt>align</tt> 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
+    <tt>cols</tt> property is set to 0, the cell grid has an infinite
+    number of columns.  Either <tt>cols</tt> or <tt>rows</tt> must be
+    zero, but not both.
+        
+    If a child's <tt>visible</tt> property is <tt>false</tt>, it does
+    not occupy any cells (and is not rendered).  Otherwise, each child
+    occupies a rectangular set of cells <tt>child.colspan</tt> cells
+    wide and <tt>child.rowspan</tt> cells high.
+        
+    The Core iterates over the cells in the grid in the following
+    order: if <tt>rows</tt> 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 <tt>colspan</tt> 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).
+    
+    <img src="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:
+
+            Its <tt>minwidth</tt>
+             
+            The width of the box's <tt>text</tt> (after applying the
+            box's <tt>transform</tt>).
+             
+            The width of the box's path (after applying the box's
+            <tt>transform</tt>) <i>if the box is <tt>packed</tt></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
+        <tt>colspan</tt>.
+        
+        If a box's <tt>hshrink</tt> property is set to
+        <tt>true</tt>, the box's maximum width is the same as its
+        minimum width; otherwise it is the box's
+        <tt>maxwidth</tt>.
+        
+        The maximum width of each cell is the <tt>maxwidth</tt> of
+        the box occupying it divided by the box's
+        <tt>colspan</tt>.
+
+    </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 <tt>minwidth</tt> or
+        larger than its <tt>maxwidth</tt>.
+        
+        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 <tt>transform</tt> 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 <tt>align</tt>
+        property).  <font color=red>FIXME: diagram</font>
+    
+        <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 <tt>transform</tt> property and then
+        positioned so that its alignment point is <tt>(child.x,
+        child.y)</tt> pixels from the parent's alignment point (both
+        alignment points are determined by the parent's <tt>align</tt>
+        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 <tt>transform</tt> 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-<tt>null</tt> 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 <tt>align</tt>
+        property).
+        
+        If a box has a path, that path is filled with the color,
+        gradient, or image specified by the <tt>fill</tt> property and
+        stroked with the color and width specified by the
+        <tt>strokecolor</tt> and <tt>strokewidth</tt> properties.
+        
+        If the box has a non-<tt>null</tt> <tt>text</tt> attribute,
+        the text is rendered in <tt>font</tt> with size
+        <tt>fontsize</tt> and color <tt>textcolor</tt>.  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 <tt>align</tt>
+        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 (<tt>#RGB</tt>),
+             7-character hex string (<tt>#RRGGBB</tt>), 9-character hex
+             string (<tt>#AARRGGBB</tt>), 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 <tt>null</tt>, the stroke color will be set to
+             clear (<tt>#00000000</tt>).
+             </property>
+    
+    <property name="strokewidth" type="int" default="1">
+             The width (in pixels) to stroke the path with.
+             </property>
+    
+    <property term="fill">
+             This property can be set to any of the values specified for
+             <tt>strokecolor</tt>.  
+             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
+             <tt>minwidth</tt> and <tt>minheight</tt> properties will be
+             automatically set to the dimensions of the image.
+             </property>
+    
+    <property name="path" type="string" default="&quot;&quot;">
+            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="&quot;&quot;">
+            The box's text; writing <tt>null</tt> to this property sets it
+            to <tt>""</tt>.
+            </property>
+    
+    <property name="font" type="stream" default="<tt>.ibex.font.sansserif</tt>">
+            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 <tt>text</tt>.
+            </property>
+            
+    <property name="fontsize" type="number" default="<tt>10</tt>">
+            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 <tt>strokecolor</tt>.
+            </property>
+    
+    </section>
+
+  <section title="Layout Properties">
+    
+    <property name="shrink" type="boolean" default="<tt>false</tt>">
+        If set to <tt>true</tt>, 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="<i>varies</i>">
+        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="<i>varies</i>">
+        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 (<tt>x</tt>/<tt>y</tt>) property,
+        except that it is relative to the root box rather than to this
+        box's parent. <font color=red>FIXME is this fakeable?  How is
+        distance measured?</font>
+        </property>
+    
+    <property name="minwidth" type="integer" default="<tt>0</tt>">
+        The desired minimum width and height.
+        </property>
+    
+    <property name="maxwidth" type="integer" default="<tt>ibex.maxint</tt>">
+        The desired maximum width and height.
+        </property>
+    
+    <property name="width" type="integer" default="<i>varies</i>">
+        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="<tt>0</tt>">
+        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 <tt>rows</tt> or <tt>cols</tt> must be zero.  If
+        <tt>0</tt> is written to <tt>cols</tt> when <tt>rows</tt> is
+        <tt>0</tt>, the write is ignored.  If a nonzero value is
+        written to <tt>cols</tt> when <tt>rows</tt> is nonzero,
+        <tt>rows</tt> is set to <tt>0</tt>, and vice versa.
+        </property>
+    
+    <property name="colspan" type="integer" default="<tt>1</tt>">
+        The number of (columns/rows) that this box spans within its parent.
+        </property>
+    
+    <property name="align" type="string" default="<tt>"center"</tt>">
+        Determines the box's alignment point for positioning its text,
+        texture, path, and children.
+        </property>
+    
+    <property name="visible" type="boolean" default="<tt>true</tt>">
+        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
+        <tt>false</tt> will be returned if this box <i>or any of its
+        ancestors</i> is not visible.  Thus it is possible to write
+        <tt>true</tt> to a box's <tt>visible</tt> property and then
+        read back <tt>false</tt>.
+        </property>
+    
+    <property name="packed" type="boolean" default="<tt>true</tt>">
+         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 <tt>id</tt> 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 <tt>redirect</tt> 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 <tt>b</tt> can be accessed by reading from
+        <tt>b[n]</tt>. The <i>n</i>th child can be removed by writing
+        <tt>null</tt> to <tt>b[n]</tt> (the child will become parentless). A
+        new child can be inserted <i>before</i> the <i>n</i>th child by
+        writing it to <tt>b[n]</tt>; if the value written is already a child of
+        <tt>b</tt>, it will be removed from <tt>b</tt> first. It is important
+        to note that this behavior is different from ECMAscript arrays --
+        writing a non-<tt>null</tt> value to <tt>b[n]</tt> 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 <tt>for..in</tt> construct will
+        enumerate <i>only</i> the box's children and not any other properties.
+        </property>
+    
+    <property name="clip" type="boolean" default="<tt>true</tt>">
+        If <tt>true</tt>, the visual representation of this box's
+        children will be clipped to the boundaries of this box.
+        <b>Note:</b> setting this property to <tt>false</tt> imposes a
+        substantial performance penalty.
+        </property>
+    
+    <property name="numchildren" type="integer" default="<tt>0</tt>">
+        The number of children this box has.
+        </property>
+    
+    <property name="redirect" type="box" default="<tt>thisbox</tt>">
+        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="<tt>null</tt>">
+        If this box has a parent, this property returns
+        <tt><i>parent</i>.surface</tt>; 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="<tt>null</tt>">
+        The shape that the cursor should take when inside this
+        box. Valid values are: <tt>"default"</tt>, <tt>"wait"</tt>,
+        <tt>"crosshair"</tt>, <tt>"text"</tt>, <tt>"hand"</tt>, and
+        <tt>"move"</tt>, as well as resizing cursors<tt>"east"</tt>,
+        <tt>"west"</tt>, <tt>"north"</tt>, <tt>"south"</tt>,
+        <tt>"northwest"</tt>, <tt>"northeast"</tt>,
+        <tt>"southwest"</tt>, and <tt>"southeast"</tt>. Note that on
+        some platforms, resize cursors for opposite directions (such
+        as <tt>northwest</tt> and <tt>southeast</tt> are the
+        same).
+        If a box's cursor is <tt>null</tt>, its parent's cursor will
+        be used. If the root box's cursor is null, the
+        <tt>"default"</tt> cursor will be used.
+        </property>
+
+    <property name="mouse.x" type="integer" default="<i>varies</i>">
+         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="<tt>false</tt>">
+        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 <tt><static/></tt> block of the template
+        in which the currently-executing code resides.
+        </property>
+       
+    <property name="thisbox" type="box" default="<tt> </tt>">
+       Returns a reference to the box itself.
+       If <tt>null</tt> 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="<tt> </tt>">
+        This property is actually a function; invoking
+        <tt>parent.indexof(child)</tt> will return the numerical index
+        of <tt>child</tt> in <tt>parent</tt> if <tt>child</tt> is a
+        child of <tt>parent</tt> (or <tt>parent</tt>'s redirect
+        target), and <tt>-1</tt> otherwise. Writing to this property
+        has no effect.
+        </property>
+
+    <property name="childadded" type=" " default="<tt> </tt>">
+
+        These properties are meant to be trapped on <font
+        color=red>FIXME defined later?</font>. Placing a trap on
+        <tt>childadded/childremoved</tt> 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
+        <tt>redirect</tt> 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 <tt>true</tt> is written to this property when the mouse enters the box.
+        </property>
+    
+    <property name="Leave">
+        The value <tt>true</tt> is written to this property when the mouse leaves the box.
+        </property>
+    
+    <property name="SizeChange">
+        The value <tt>true</tt> 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 <tt>true</tt> is put to this property on the root box
+        when the surface gains the input focus, and <tt>false</tt> when
+        the surface loses the input focus. Reading from this value will
+        return <tt>true</tt> if the surface is focused and <tt>false</tt>
+        if it is not. Putting <tt>true</tt> to this property will
+        <i>not</i> cause the surface to "steal" the input focus from other
+        windows.
+        </property>
+    
+    <property name="Maximized">
+        The value <tt>true</tt> is put to this property on the root box
+        when the surface is maximized, and <tt>false</tt> when the surface
+        is un-maximized. Reading from this value will return <tt>true</tt>
+        if the surface is maximized and <tt>false</tt> if it is
+        not. Putting <tt>true</tt> to this property will maximize the
+        window, and putting <tt>false</tt> to this property will
+        unmaximize the window.
+        Note that not all platforms support maximization.
+        </property>
+    
+    <property name="Minimized">
+        The value <tt>true</tt> is put to this property on the root box
+        when the surface is minimized, and <tt>false</tt> when the surface
+        is unminimized. Reading from this value will return <tt>true</tt>
+        if the surface is minimized and <tt>false</tt> if it is
+        not. Putting <tt>true</tt> to this property will minimize the
+        window, and putting <tt>false</tt> will unminimize it.
+        </property>
+    
+    <property name="Close">
+        When the user attempts to close a surface, the value
+        <tt>true</tt> will be put to this property. Scripts may trap
+        this property <font color=red>FIXME defined later?</font> to
+        prevent the window from closing. Putting the value
+        <tt>true</tt> to this property on a root box has the same
+        effect as putting <tt>null</tt> to the <tt>thisbox</tt>
+        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 <tt>ibex</tt> 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 <tt>[]</tt> and
+    <tt>.</tt>, as well as the <tt>for..in</tt> 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 <tt>ibex</tt> object is called the
+    <i>root stream</i>.  You can access this object as <tt>ibex..</tt> or
+    <tt>ibex[""]</tt>.  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 (<tt>..</tt>) and the variable name to the
+    stream used to load that template:
+    
+    <pre>
+      <!-- org/ibex/themes/monopoly/scrollbar.ibex -->
+      <ibex>
+          <static>
+              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 <tt><base64/></tt> element.
+    
+    Ibex supports two special URL protocols.  The first is <tt>data:</tt>,
+    which inteprets the rest of the URL as a Base64 encoded sequence of
+    bytes to use as a source.  The other is <tt>utf8:</tt> 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 <tt>ibex</tt> object is present in the top-level scope of every
+    script.  It has the following properties:
+    
+  <section title="General">
+
+    <table class="props">
+    <tr><td><tt>ibex.box</tt></td>                      <td>reading from this property returns a new box</td></tr>
+    <tr><td><tt>ibex.clone(o)</tt></td>                 <td>creates a clone of object <i>o</i></tr>
+    <tr><td><tt>ibex.bless(s)</tt></td>                 <td>returns a blessed clone of stream <i>s</i></tr>
+    </table>
+
+    </section>
+
+  <section title="ECMA Library Objects">
+
+    <table class="props">
+    <tr><td><tt>ibex.date</tt></td>                     <td>reading from this property returns a new date</td></tr>
+    <tr><td><tt>ibex.math</tt></td>                     <td>this object contains the ECMA math functions</td></tr>
+    <tr><td><tt>ibex.regexp(s)</tt></td>                <td>return a regexp object corresponding to string <i>s</i></td></tr>
+    <tr><td><tt>ibex.string</tt></td>                   <td>this object contains the ECMA string manipulation functions</td></tr>
+    </table>
+
+    </section>
+
+  <section 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>
+
+    </section>
+
+  </section>
+<!-- ----------------------------------------------------------------------- -->
+<section 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>
+
+  <section title="Networking">
+
+    <property name="ibex.net.http">
+        <font color=red><i>not yet implemented</font>
+        </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>
+
+    </section>
+
+  <section 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>
+
+    </section>
+
+  <section 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 <tt>parse.xml()</tt>, but tries to fix broken HTML.
+        </property>
+
+    <property name="ibex.stream.parse.utf8(s)">
+        </property>
+        treat <i>s</i>'s stream as a string encoded as a UTF-8 byte stream and return the string</tr>
+
+    <property name="ibex.stream.homedir">
+        <tt>ibex.stream.tempdir</tt>
+        </property>
+
+    </section>
+
+  <section title="Cryptography">
+
+    <property name="ibex.crypto.rsa(k,s)">
+        <i><font color=red>not implemented yet:</font></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><font color=red>not implemented yet:</font></i> return a
+        stream which rc4-decrypts stream <i>s</i> with key <i>k</i>
+        </property>
+
+    <property name="ibex.crypto.md5(s)">
+        <i><font color=red>not implemented yet:</font></i> immediately
+        MD5-hash stream <i>s</i>
+        </property>
+
+    <property name="ibex.crypto.sha1(s)">
+        <i><font color=red>not implemented yet:</font></i> immediately
+        SHA1-hash stream <i>s</i>
+        </property>
+
+    </section>
+
+  </section>
+<!-- ----------------------------------------------------------------------- -->
+<section title="Traps">
+
+  <section title="Simple Traps">
+
+    You can add a trap to a property by applying the <tt>++=</tt> 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 <tt>"foo"</tt>
+    on the box above to the value <tt>5</tt>, the function above would be
+    invoked with the argument <tt>5</tt>. The function would then log
+    the string <tt>"foo is 5"</tt>.
+    
+    Within a trap, the expression <tt>trapee</tt> can be used to
+    get a reference to the box on which the trap was placed.
+    
+    The expression <tt>trapname</tt> 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>
+
+  <section title="Removing Traps">
+
+    You can remove a trap by using the <tt>--=</tt> 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>
+
+  <section 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>
+
+  <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 <tt>cascade</tt>. 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 <tt>true</tt> 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 <tt>++=</tt> function() { return 2 * width; }
+        </box>
+    </pre>
+
+    If another script attempts to read from the <tt>doublewidth</tt>
+    property on this box, the value it gets will be twice the actual width
+    of the box.  Note that
+    the actual <tt>doublewidth</tt> 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 <tt>++=</tt> 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>
+
+  <section 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 section="Box Layout Properties"/>, <link
+    section="Child-Control Properties"/>, or <link section="Other Box
+    Properties"/> except for <tt>childadded</tt>,
+    <tt>childremoved</tt> and <tt>surface</tt>.  <font
+    color=red>FIXME: remove?</font>
+    
+    </section>
+
+  <section 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
+    <tt>null</tt> will be returned.
+    <font color=red>FIXME: is this right?</font>
+    
+    </section>
+
+  <section 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>
+
+  <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 <tt>ibex.clone(o)</tt>, Ibex returns a new object (called the
+    <i>clone</i>) which compares with equality (<tt>==</tt>) 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="Ibex self-emulation">
+
+    When the core first starts up, it clones the <tt>ibex</tt> object,
+    creates a stream for the initial .ibex, and then places a trap on the
+    cloned <tt>ibex</tt> object so that its empty-string property returns
+    the .ibex stream.  The cloned Ibex object is then passed as the third
+    (optional) argument to <tt>ibex.apply()</tt>, making it the default
+    <tt>ibex</tt> 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 <tt>ibex.bless()</tt> 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:
+
+            If the stream is a template to be applied, the string
+            <tt>".ibex"</tt> is appended.
+        
+            If the stream is an image, the string <tt>".png"</tt> is
+            appended.  If no stream is found, <tt>".jpeg"</tt> and
+            <tt>".gif"</tt> are tried, in that order.
+        
+            If the stream is an font, the string <tt>".ttf"</tt> is
+            appended.
+        
+        Every call to <tt>ibex.bless()</tt> 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 <tt>ibex.clone()</tt> 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>
+<!-- ----------------------------------------------------------------------- -->
+<section title="Contexts and Threading">
+
+  <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 <tt>ibex.thread</tt>)
+
+    </list>
+    
+    There are two important restrictions on what can be done in particular contexts:
+    
+    <list type="unordered">
+
+        The <tt>box.mouse</tt> property and its subproperties
+        (<tt>x</tt>, <tt>y</tt>, and <tt>inside</tt>) can only be read
+        from within the Event Context, or in a thread context
+        <i>after</i> a the <tt>box.mouse</tt> 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 <tt>ibex.thread</tt> 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 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 <tt>_Press[1-3]</tt>,
+    <tt>_Release[1-3]</tt>, <tt>_Click[1-3]</tt>, <tt>_DoubleClick[1-3]</tt>,
+    <tt>_Move</tt>, <tt>_KeyPressed</tt>, and <tt>_KeyReleased</tt>.
+    
+    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>
+
+  <section title="Stopping the Process">
+
+    At any point in this sequence, a trap handler can choose not to
+    cascade (by returning <tt>true</tt> 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".
+    
+    </section>
+
+  <section title="Re-routing events">
+
+    At any point in the Event Context, you can write to the <tt>mouse</tt>
+    property on any box.  The value written should be an object with two
+    properties, <tt>x</tt> and <tt>y</tt>.  For example:
+    
+    <pre>
+        _Press1 ++= function(p) {
+            mouse = { x: 32, y: 77 };
+        }
+    </pre>
+
+    The coordinates specified are relative to the box whose <tt>mouse</tt>
+    property is being written to.  There is no need to supply the
+    <tt>inside</tt> property; it is computed automatically.  Writing to
+    the <tt>mouse</tt> property causes Ibex to recompute the eventual
+    target box, and also alter the values returned by <tt>mouse.x</tt>,
+    <tt>mouse.y</tt>, and <tt>mouse.inside</tt> for any <i>descendants</i>
+    of the current box.  Writing to the <tt>mouse</tt> 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 to keep the 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 <tt>mouse</tt>
+    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="Enter and Leave">
+
+    Ibex will trigger the <tt>Enter</tt> and <tt>Leave</tt> properties as
+    it walks down the tree, based on the position of the mouse (or the
+    faked position if the <tt>mouse</tt> property has been written to).
+    However, <tt>Enter</tt> and <tt>Leave</tt> are not events since they
+    do not implicitly cascade up or down the tree.
+    
+    </section>
+
+  <section title="Detailed Description 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
+        "<tt>HOME</tt>". Symbols are capitalized as they appear on the
+        keyboard; for example, on an American QWERTY keyboard, shift+2
+        is reported as "<tt>@</tt>".  If the alt, meta, or command key
+        was depressed immediately before this key was pressed, then
+        the string will be prefixed with the string "<tt>A-</tt>". If
+        the control key was depressed while this key was pressed, then
+        the string will be prefixed with the string "<tt>C-</tt>". If
+        both alt and control are depressed, the string is prefixed
+        with "<tt>C-A-</tt>".  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 <tt>ibex.net.rpc.xml(<<i>XML-RPC
+    URL</i>>)</tt>, 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 <tt>xmlrpc.ibex.org</tt>, route to the
+    <tt>/RPC2/</tt> handler and invoke the <tt>getTodaysColor()</tt>
+    method on the <tt>color</tt> object with a single string argument
+    <tt>"Friday"</tt>. 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 <tt>Press1</tt> 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: <tt>faultCode</tt> and <tt>faultString</tt>, 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 <tt>String</tt> 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 <tt>ibex.net.rpc.xml()</tt> 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 <tt>ibex.net.rpc.xml()</tt> a URL in the form
+    <tt>http[s]://user:password@hostname/</tt>.  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">
+
+        <tt>ibex.net.rpc.soap()</tt> is used instead of
+        <tt>ibex.net.rpc.xml()</tt>
+        
+        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 <tt>faultstring</tt> and <tt>faultcode</tt>
+    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",   // endpoint
+                                         "GETTODAYSCOLOR",             // SOAPAction header
+                                         "http://ibex.org/namespace"    // namespace for SOAP-ENV
+                                    ).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 (<tt>href</tt>) 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 Appendix A 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 <tt><i>xyz</i></tt> will be
+            the three-digit HTTP status code.
+        </property>
+    <property name="ibex.net.xmlrpc.null">
+        The caller attempted to transmit the <tt>null</tt> 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 <tt>null</tt> value
+        </property>
+    <property name="ibex.null.get">
+        A JavaScript attempted to get from a property on the <tt>null</tt> value
+        </property>
+    <property name="ibex.null.call">
+        A JavaScript attempted to call the <tt>null</tt> value
+        </property>
+    </table>
+    
+    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
+    (<tt>visible = false</tt>).  This ensures that half-applied widgets are
+    never shown to the user.
+    
+  </section>
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="A: 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:
+    
+  <section 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.
+    
+    </section>
+
+  <section 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</tt></a> 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 <tt>User-Agent:</tt> header beginning with the
+    three characters "<tt>Ibex</tt>".
+    
+    </section>
+
+  <section 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.
+    
+    </section>
+
+  <section 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.
+    
+    </section>
+
+  </section>
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="B: 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 <tt>undefined</tt> value, <tt>===</tt>, and <tt>!==</tt>
+        
+        The <tt>new</tt> keyword (and ECMAScript object inheritance)
+        <tt>eval</tt>
+        
+        <tt>getter</tt> and <tt>setter</tt>
+        
+        The ECMA <tt>this</tt> keyword.
+        
+        The <tt>String</tt>, <tt>Number</tt>, and <tt>Boolean</tt>
+        classes.  Note that <tt>string</tt>, <tt>number</tt>, and
+        <tt>boolean</tt> values are supported, however.
+        
+        You may not <tt>throw</tt> the <tt>null</tt> value.
+
+    </list>
+    
+    Additionally, you must declare all root-scope variables (with
+    <tt>var</tt>) 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 <tt>..</tt> is equivalent to <tt>[""]</tt>.
+    
+        Trapping
+    
+        Cloning
+    
+        Extended <tt>catch</tt> syntax.  The following code:
+        <pre>
+            } catch(e propname "foo.bar.baz") {
+               // ...
+            }
+        </pre>
+        Is equivalent to:
+        <pre>
+        } catch(e) {
+           if (e.propname != null &amp;&amp; e.propname >= "foo.bar.baz" &amp;&amp; e.propname < "foo.bar.baz/") {
+               // ...
+           }
+        }
+        </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
+        "<tt>lt</tt>" is be interpreted as <tt><</tt>, the lexical
+        token "<tt>gt</tt>" is be interpreted as <tt>></tt>, and the
+        token "<tt>and</tt>" is interpreted as <tt>&amp;&amp;</tt>.
+        Thus these tokens cannot be used as variable names.
+    
+        The identifier <tt>static</tt> is a reserved word in
+        ECMAScript, but not in Ibex.
+    
+        Ibex defines an additional reserved word, "<tt>assert</tt>",
+        which will evaluate the expression which follows it, throwing
+        a <tt>ibex.assertion.failed</tt> exception if the expression
+        evaluates to <tt>false</tt>.
+    
+        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>
+
+  </section>
+
+<!-- ----------------------------------------------------------------------- -->
+<section title="C: 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
+    <tt>$TMPDIR\ibex-log.txt</tt> on Win32 (where <tt>$TMPDIR</tt> is the
+    value returned by <tt>GetTempPath()</tt>). 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 <i>path-to-ibex-jar</i> [-sv] <i>source-location</i> [<i>initial-template</i>]
+    </pre>
+    
+    Where <tt><i>path-to-ibex-jar</i></tt> is the path to <tt>ibex.jar</tt>,
+    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] <i>source-location</i> [<i>initial-template</i>]
+    </pre>
+    
+    The file <tt>ibex.exe</tt> 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 <tt>C:\WINDOWS\DOWNLOADED
+    PROGRAM FILES\</tt>. You can also extract <tt>ibex.exe</tt> from
+    <tt>ibex.cab</tt>, which is available <link
+    url="http://www.ibex.org/dist/ibex.cab" text="here"/>.
+    
+    The <tt><i>source-location</i></tt> 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 <tt><i>initial-template</i></tt> parameter is the stream name of
+    a template to be used as the initial template. If ommitted, it
+    defaults to <tt>main</tt>.
+    
+    The <tt>-v</tt> 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.
+    
+  </section>
+
+<!-- ----------------------------------------------------------------------- -->
+    <!--
+<section title="E: Grammars">
+
+    <font color=red><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></font>
+    
+    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 '<tt>|</tt>') 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 <tt>()</tt>
+         
+        combinators:   <tt> | + * ?</tt>
+         
+        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 <tt>"{ return whole; }"</tt>.
+         
+       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