From e78747b85b8a5cb55d31691b980824993286b188 Mon Sep 17 00:00:00 2001 From: Kevin Chabowski Date: Thu, 4 Oct 2012 16:19:29 +0200 Subject: New docu and fixed mkdocu.sh mkdocu.sh will now test, if the executable is named "naturaldocs" or "NaturalDocs". --- docu/nd/files/stupid_template_engine-php.html | 40 +- docu/nd/index/Classes.html | 4 +- docu/nd/index/Constants.html | 4 +- docu/nd/index/Files.html | 4 +- docu/nd/index/Functions.html | 22 +- docu/nd/index/General.html | 24 +- docu/nd/index/Variables.html | 6 +- docu/nd/javascript/main.js | 1677 +++++++++++++------------ docu/nd/javascript/prettify.js | 1526 ++++++++++++++++++++++ docu/nd/search/ClassesC.html | 4 +- docu/nd/search/ClassesF.html | 4 +- docu/nd/search/ClassesR.html | 4 +- docu/nd/search/ClassesS.html | 4 +- docu/nd/search/ConstantsM.html | 4 +- docu/nd/search/ConstantsT.html | 4 +- docu/nd/search/FilesS.html | 4 +- docu/nd/search/FunctionsC.html | 4 +- docu/nd/search/FunctionsE.html | 4 +- docu/nd/search/FunctionsG.html | 4 +- docu/nd/search/FunctionsL.html | 4 +- docu/nd/search/FunctionsP.html | 4 +- docu/nd/search/FunctionsR.html | 4 +- docu/nd/search/FunctionsS.html | 4 +- docu/nd/search/FunctionsSymbols.html | 4 +- docu/nd/search/FunctionsT.html | 4 +- docu/nd/search/GeneralB.html | 4 +- docu/nd/search/GeneralC.html | 4 +- docu/nd/search/GeneralE.html | 4 +- docu/nd/search/GeneralF.html | 4 +- docu/nd/search/GeneralG.html | 4 +- docu/nd/search/GeneralL.html | 4 +- docu/nd/search/GeneralM.html | 4 +- docu/nd/search/GeneralP.html | 4 +- docu/nd/search/GeneralR.html | 4 +- docu/nd/search/GeneralS.html | 4 +- docu/nd/search/GeneralSymbols.html | 4 +- docu/nd/search/GeneralT.html | 4 +- docu/nd/search/GeneralV.html | 4 +- docu/nd/search/NoResults.html | 4 +- docu/nd/search/VariablesB.html | 4 +- docu/nd/search/VariablesF.html | 4 +- docu/nd/search/VariablesM.html | 4 +- docu/nd/search/VariablesP.html | 4 +- docu/nd/search/VariablesV.html | 4 +- docu/nd/styles/main.css | 1595 ++++++++++++----------- mkdocu.sh | 9 +- 46 files changed, 3325 insertions(+), 1726 deletions(-) create mode 100644 docu/nd/javascript/prettify.js diff --git a/docu/nd/files/stupid_template_engine-php.html b/docu/nd/files/stupid_template_engine-php.html index 1567591..91d6080 100644 --- a/docu/nd/files/stupid_template_engine-php.html +++ b/docu/nd/files/stupid_template_engine-php.html @@ -1,9 +1,9 @@ -stupid_template_engine.php - + @@ -23,15 +23,15 @@ if (browserType) {document.write("
");if (browserV

Functions

-

precompile

function precompile($code)

Precompiling STE T/PL templates.  You only need this function, if you want to manually transcompile a template.

Parameters

$codeThe input code

Returns

The precompiled code.

+

precompile

function precompile($code)

Precompiling STE T/PL templates.  You only need this function, if you want to manually transcompile a template.

Parameters

$codeThe input code

Returns

The precompiled code.

-

parse

function parse($code,
$tpl)

Parsing a STE T/PL template.  You only need this function, if you want to manually transcompile a template.

Parameters

$codeThe STE T/PL code.
$tplThe name of the template.

Returns

An abstract syntax tree, which can be used with transcompile.

+

parse

function parse($code,
$tpl)

Parsing a STE T/PL template.  You only need this function, if you want to manually transcompile a template.

Parameters

$codeThe STE T/PL code.
$tplThe name of the template.

Returns

An abstract syntax tree, which can be used with transcompile.

-

transcompile

function transcompile($ast) /* Transcompile and add some boilerplate code. */

Transcompiles an abstract syntax tree to PHP.  You only need this function, if you want to manually transcompile a template.

Parameters

$astThe abstract syntax tree to transcompile.

Returns

PHP code.  The PHP code is an anonymous function expecting a STECore instance as its parameter and returns a string (everything that was not pached into a section).

+

transcompile

function transcompile($ast) /* Transcompile and add some boilerplate code. */

Transcompiles an abstract syntax tree to PHP.  You only need this function, if you want to manually transcompile a template.

Parameters

$astThe abstract syntax tree to transcompile.

Returns

PHP code.  The PHP code is an anonymous function expecting a STECore instance as its parameter and returns a string (everything that was not pached into a section).

Constants

-

Template modes

MODE_SOURCEThe Templates source
MODE_TRANSCOMPILEDThe transcompiled template
+

Template modes

MODE_SOURCEThe Templates source
MODE_TRANSCOMPILEDThe transcompiled template

CantLoadTemplate

An exception that a StorageAccess implementation can throw, if it is unable to load a template.

@@ -41,41 +41,41 @@ if (browserType) {document.write("
");if (browserV

Functions

-

load

public function load($tpl,
&$mode)

Loading a template.

Parameters

$tplThe name of the template.
&$modeWhich mode is preferred?  One of the <Template modes>.  If <MODE_SOURCE>, the raw sourcecode is expected, if <MODE_TRANSCOMPILED> the transcompiled template as a callable function (expecting an STECore instance as first parameter) is expected.  If the transcompiled version is not available or older than the source, you can set this parameter to <MODE_SOURCE> and return the source.

Throws

A CantLoadTemplate exception if the template could not be loaded.

Returns

Either the sourcecode or a callable function (first, and only parameter: an STECore instance).

+

load

public function load($tpl,
&$mode)

Loading a template.

Parameters

$tplThe name of the template.
&$modeWhich mode is preferred?  One of the <Template modes>.  If <MODE_SOURCE>, the raw sourcecode is expected, if <MODE_TRANSCOMPILED> the transcompiled template as a callable function (expecting an STECore instance as first parameter) is expected.  If the transcompiled version is not available or older than the source, you can set this parameter to <MODE_SOURCE> and return the source.

Throws

A CantLoadTemplate exception if the template could not be loaded.

Returns

Either the sourcecode or a callable function (first, and only parameter: an STECore instance).

-

save

public function save($tpl,
$data,
$mode)

Saves a template.

Throws

A CantSaveTemplate exception if the template could not be saved.

Parameters

$tpl -The name of the template.  $data - The data to be saved.  $mode - A <Template mode> constant.

+

save

public function save($tpl,
$data,
$mode)

Saves a template.

Throws

A CantSaveTemplate exception if the template could not be saved.

Parameters

$tpl -The name of the template.  $data - The data to be saved.  $mode - A <Template mode> constant.

FilesystemStorageAccess

The default StorageAccess implementation for loading / saving templates into a directory structure.

Functions

-

__construct

public function __construct($src,
$transc)

Parameters

$srcThe directory with the sources (Writing permissions are not mandatory, because STE does not save template sources).
$transcThe directory with the transcompiled templates (the PHP instance / the HTTP Server needs writing permissions to this directory).
+

__construct

public function __construct($src,
$transc)

Parameters

$srcThe directory with the sources (Writing permissions are not mandatory, because STE does not save template sources).
$transcThe directory with the transcompiled templates (the PHP instance / the HTTP Server needs writing permissions to this directory).

STECore

The Core of STE

Summary
Variables
Public variables
Functions
__construct
register_tagRegister a custom tag.
call_tagCalling a custom tag (builtin ones can not be called)
exectemplateExecutes a template and returns the result.
get_var_referenceGet a reference to a template variable using a variable name.
set_var_by_nameSet a template variable by its name.
get_var_by_nameGet a template variable by its name.
loadLoad a template and return its result (blocks not included, use exectemplate for this).
evalboolTest, if a text represents false (an empty / only whitespace text) or true (everything else).

Variables

-

Public variables

$blocksAssociative array of blocks (see the language definition).
$blockorderThe order of the blocks (an array)
$varsAssociative array of all template variables.  Use this to pass data to your templates.
$mute_runtime_errorsIf True (default) a RuntimeError exception will result in no output from the tag, if False a error message will be written to output.
$fatal_error_on_missing_tagIf True, STE will throw a FatalRuntimeError if a tag was called that was not registered, otherwise (default) a regular RuntimeError will be thrown and automatically handled by STE (see <$mute_runtime_errors>).
+

Public variables

$blocksAssociative array of blocks (see the language definition).
$blockorderThe order of the blocks (an array)
$varsAssociative array of all template variables.  Use this to pass data to your templates.
$mute_runtime_errorsIf True (default) a RuntimeError exception will result in no output from the tag, if False a error message will be written to output.
$fatal_error_on_missing_tagIf True, STE will throw a FatalRuntimeError if a tag was called that was not registered, otherwise (default) a regular RuntimeError will be thrown and automatically handled by STE (see $mute_runtime_errors).

Functions

-

__construct

public function __construct($storage_access)

Parameters

$storage_accessAn Instance of a StorageAccess implementation.
+

__construct

public function __construct($storage_access)

Parameters

$storage_accessAn Instance of a StorageAccess implementation.
-

register_tag

public function register_tag($name,
$callback)

Register a custom tag.

Parameters

$nameThe name of the tag.
$callbackA callable function (This must tage three parameters: The STECore instance, an associative array of parameters, and a function representing the tags content(This expects the STECore instance as its only parameter and returns its text result, i.e to get the text, you neeed to call this function with the STECore instance as a parameter)).

Throws

An Exception if the tag could not be registered (if $callback is not callable or if $name is empty)

+

register_tag

public function register_tag($name,
$callback)

Register a custom tag.

Parameters

$nameThe name of the tag.
$callbackA callable function (This must tage three parameters: The STECore instance, an associative array of parameters, and a function representing the tags content(This expects the STECore instance as its only parameter and returns its text result, i.e to get the text, you neeed to call this function with the STECore instance as a parameter)).

Throws

An Exception if the tag could not be registered (if $callback is not callable or if $name is empty)

-

call_tag

public function call_tag($name,
$params,
$sub)

Calling a custom tag (builtin ones can not be called)

Parameters

$nameThe Tag’s name
$paramsAssociative array of parameters
$subA callable function (expecting an STECore instance as it’s parameter) that represents the tag’s content.

Throws

Might throw a FatalRuntimeError (see $fatal_error_on_missing_tag.

Returns

The output of the tag or, if a RuntimeError was thrown, the appropiate result (see <$mute_runtime_errors>).

+

call_tag

public function call_tag($name,
$params,
$sub)

Calling a custom tag (builtin ones can not be called)

Parameters

$nameThe Tag’s name
$paramsAssociative array of parameters
$subA callable function (expecting an STECore instance as it’s parameter) that represents the tag’s content.

Throws

Might throw a FatalRuntimeError (see $fatal_error_on_missing_tag.

Returns

The output of the tag or, if a RuntimeError was thrown, the appropiate result (see $mute_runtime_errors).

-

exectemplate

public function exectemplate($tpl)

Executes a template and returns the result.  The huge difference to load is that this function will also output all blocks.

Parameters

$tplThe name of the template to execute.

Throws

Returns

The output of the template.

+

exectemplate

public function exectemplate($tpl)

Executes a template and returns the result.  The huge difference to load is that this function will also output all blocks.

Parameters

$tplThe name of the template to execute.

Throws

Returns

The output of the template.

-

get_var_reference

public function &get_var_reference($name,
$create_if_not_exist)

Get a reference to a template variable using a variable name.  This can be used,if your custom tag takes a variable name as a parameter.

Parameters

$nameThe variables name.
$create_if_not_existShould the variable be created, if it does not exist?  Otherwise NULL will be returned, if the variable does not exist.

Throws

RuntimeError if the variable name can not be parsed (e.g. unbalanced brackets).

Returns

A Reference to the variable.

+

get_var_reference

public function &get_var_reference($name,
$create_if_not_exist)

Get a reference to a template variable using a variable name.  This can be used,if your custom tag takes a variable name as a parameter.

Parameters

$nameThe variables name.
$create_if_not_existShould the variable be created, if it does not exist?  Otherwise NULL will be returned, if the variable does not exist.

Throws

RuntimeError if the variable name can not be parsed (e.g. unbalanced brackets).

Returns

A Reference to the variable.

-

set_var_by_name

public function set_var_by_name($name,
$val)

Set a template variable by its name.  This can be used,if your custom tag takes a variable name as a parameter.

Parameters

$nameThe variables name.
$valThe new value.

Throws

RuntimeError if the variable name can not be parsed (e.g. unbalanced brackets).

+

set_var_by_name

public function set_var_by_name($name,
$val)

Set a template variable by its name.  This can be used,if your custom tag takes a variable name as a parameter.

Parameters

$nameThe variables name.
$valThe new value.

Throws

RuntimeError if the variable name can not be parsed (e.g. unbalanced brackets).

-

get_var_by_name

public function get_var_by_name($name)

Get a template variable by its name.  This can be used,if your custom tag takes a variable name as a parameter.

Parameters

$nameThe variables name.

Throws

RuntimeError if the variable name can not be parsed (e.g. unbalanced brackets).

Returns

The variables value.

+

get_var_by_name

public function get_var_by_name($name)

Get a template variable by its name.  This can be used,if your custom tag takes a variable name as a parameter.

Parameters

$nameThe variables name.

Throws

RuntimeError if the variable name can not be parsed (e.g. unbalanced brackets).

Returns

The variables value.

-

load

public function load($tpl,  
$quiet = False)

Load a template and return its result (blocks not included, use exectemplate for this).

Parameters

$tplThe name of the template to be loaded.
$quietIf true, do not output anything and do notmodify the blocks.  This can be useful to load custom tags that are programmed in STE T/PL.  Default: false.

Throws

Returns

The result of the template (if $quiet == false).

+

load

public function load($tpl,  
$quiet = False)

Load a template and return its result (blocks not included, use exectemplate for this).

Parameters

$tplThe name of the template to be loaded.
$quietIf true, do not output anything and do notmodify the blocks.  This can be useful to load custom tags that are programmed in STE T/PL.  Default: false.

Throws

Returns

The result of the template (if $quiet == false).

-

evalbool

public function evalbool($txt)

Test, if a text represents false (an empty / only whitespace text) or true (everything else).

Parameters

$txtThe text to test.

Returns

true/false.

+

evalbool

public function evalbool($txt)

Test, if a text represents false (an empty / only whitespace text) or true (everything else).

Parameters

$txtThe text to test.

Returns

true/false.

@@ -90,7 +90,7 @@ var searchPanel = new SearchPanel("searchPanel", "HTML", "../search"); -
function precompile($code)
Precompiling STE T/PL templates.
function parse($code,
$tpl)
Parsing a STE T/PL template.
function transcompile($ast) /* Transcompile and add some boilerplate code. */
Transcompiles an abstract syntax tree to PHP.
An interface.
public function load($tpl,
&$mode)
Loading a template.
public function save($tpl,
$data,
$mode)
Saves a template.
public function __construct($src,
$transc)
public function __construct($storage_access)
public function register_tag($name,
$callback)
Register a custom tag.
public function call_tag($name,
$params,
$sub)
Calling a custom tag (builtin ones can not be called)
public function exectemplate($tpl)
Executes a template and returns the result.
public function &get_var_reference($name,
$create_if_not_exist)
Get a reference to a template variable using a variable name.
public function set_var_by_name($name,
$val)
Set a template variable by its name.
public function get_var_by_name($name)
Get a template variable by its name.
public function load($tpl,  
$quiet = False)
Load a template and return its result (blocks not included, use exectemplate for this).
public function evalbool($txt)
Test, if a text represents false (an empty / only whitespace text) or true (everything else).
If True (default) a RuntimeError exception will result in no output from the tag, if False a error message will be written to output.
The Core of STE
An exception that a StorageAccess implementation can throw, if it is unable to load a template.
An exception that a StorageAccess implementation can throw, if it is unable to save a template.
An Exception that a tag can throw, if a non-fatal runtime error occurred.
An Exception a tag can throw, if a fatal (irreparable) runtime error occurred.
If True, STE will throw a FatalRuntimeError if a tag was called that was not registered, otherwise (default) a regular RuntimeError will be thrown and automatically handled by STE (see <$mute_runtime_errors>).
+
function precompile($code)
Precompiling STE T/PL templates.
function parse($code,
$tpl)
Parsing a STE T/PL template.
function transcompile($ast) /* Transcompile and add some boilerplate code. */
Transcompiles an abstract syntax tree to PHP.
An interface.
public function load($tpl,
&$mode)
Loading a template.
public function save($tpl,
$data,
$mode)
Saves a template.
public function __construct($src,
$transc)
public function __construct($storage_access)
public function register_tag($name,
$callback)
Register a custom tag.
public function call_tag($name,
$params,
$sub)
Calling a custom tag (builtin ones can not be called)
public function exectemplate($tpl)
Executes a template and returns the result.
public function &get_var_reference($name,
$create_if_not_exist)
Get a reference to a template variable using a variable name.
public function set_var_by_name($name,
$val)
Set a template variable by its name.
public function get_var_by_name($name)
Get a template variable by its name.
public function load($tpl,  
$quiet = False)
Load a template and return its result (blocks not included, use exectemplate for this).
public function evalbool($txt)
Test, if a text represents false (an empty / only whitespace text) or true (everything else).
If True (default) a RuntimeError exception will result in no output from the tag, if False a error message will be written to output.
The Core of STE
An exception that a StorageAccess implementation can throw, if it is unable to load a template.
An exception that a StorageAccess implementation can throw, if it is unable to save a template.
An Exception that a tag can throw, if a non-fatal runtime error occurred.
An Exception a tag can throw, if a fatal (irreparable) runtime error occurred.
If True, STE will throw a FatalRuntimeError if a tag was called that was not registered, otherwise (default) a regular RuntimeError will be thrown and automatically handled by STE (see $mute_runtime_errors).
diff --git a/docu/nd/index/Classes.html b/docu/nd/index/Classes.html index d2bee20..7b2f5e8 100644 --- a/docu/nd/index/Classes.html +++ b/docu/nd/index/Classes.html @@ -1,9 +1,9 @@ -Class Index - + diff --git a/docu/nd/index/Constants.html b/docu/nd/index/Constants.html index 53106b3..be1aa6c 100644 --- a/docu/nd/index/Constants.html +++ b/docu/nd/index/Constants.html @@ -1,9 +1,9 @@ -Constant Index - + diff --git a/docu/nd/index/Files.html b/docu/nd/index/Files.html index 59196fe..5418d4b 100644 --- a/docu/nd/index/Files.html +++ b/docu/nd/index/Files.html @@ -1,9 +1,9 @@ -File Index - + diff --git a/docu/nd/index/Functions.html b/docu/nd/index/Functions.html index 5087083..3bc9e21 100644 --- a/docu/nd/index/Functions.html +++ b/docu/nd/index/Functions.html @@ -1,9 +1,9 @@ -Function Index - + @@ -13,39 +13,39 @@ if (browserType) {document.write("
");if (browserV
Function Index
$#! · 0-9 · A · B · C · D · E · F · G · H · I · J · K · L · M · N · O · P · Q · R · S · T · U · V · W · X · Y · Z
$#!
 __construct
C
 call_tag, STECore
E
 evalbool, STECore
 exectemplate, STECore
G
 get_var_by_name, STECore
 get_var_reference, STECore
L
 load
P
 parse, FatalRuntimeError
 precompile, FatalRuntimeError
R
 register_tag, STECore
S
 save, StorageAccess
 set_var_by_name, STECore
T
 transcompile, FatalRuntimeError
-
public function __construct($src,
$transc)
public function __construct($storage_access)
+
public function __construct($src,
$transc)
public function __construct($storage_access)
-
public function call_tag($name,
$params,
$sub)
Calling a custom tag (builtin ones can not be called)
+
public function call_tag($name,
$params,
$sub)
Calling a custom tag (builtin ones can not be called)
-
public function evalbool($txt)
Test, if a text represents false (an empty / only whitespace text) or true (everything else).
public function exectemplate($tpl)
Executes a template and returns the result.
+
public function evalbool($txt)
Test, if a text represents false (an empty / only whitespace text) or true (everything else).
public function exectemplate($tpl)
Executes a template and returns the result.
-
public function get_var_by_name($name)
Get a template variable by its name.
public function &get_var_reference($name,
$create_if_not_exist)
Get a reference to a template variable using a variable name.
+
public function get_var_by_name($name)
Get a template variable by its name.
public function &get_var_reference($name,
$create_if_not_exist)
Get a reference to a template variable using a variable name.
-
public function load($tpl,  
$quiet = False)
Load a template and return its result (blocks not included, use exectemplate for this).
public function load($tpl,
&$mode)
Loading a template.
+
public function load($tpl,  
$quiet = False)
Load a template and return its result (blocks not included, use exectemplate for this).
public function load($tpl,
&$mode)
Loading a template.
-
function parse($code,
$tpl)
Parsing a STE T/PL template.
function precompile($code)
Precompiling STE T/PL templates.
+
function parse($code,
$tpl)
Parsing a STE T/PL template.
function precompile($code)
Precompiling STE T/PL templates.
-
public function register_tag($name,
$callback)
Register a custom tag.
+
public function register_tag($name,
$callback)
Register a custom tag.
-
public function save($tpl,
$data,
$mode)
Saves a template.
public function set_var_by_name($name,
$val)
Set a template variable by its name.
+
public function save($tpl,
$data,
$mode)
Saves a template.
public function set_var_by_name($name,
$val)
Set a template variable by its name.
-
function transcompile($ast) /* Transcompile and add some boilerplate code. */
Transcompiles an abstract syntax tree to PHP.
+
function transcompile($ast) /* Transcompile and add some boilerplate code. */
Transcompiles an abstract syntax tree to PHP.
diff --git a/docu/nd/index/General.html b/docu/nd/index/General.html index 626bc81..73eecbb 100644 --- a/docu/nd/index/General.html +++ b/docu/nd/index/General.html @@ -1,9 +1,9 @@ -Index - + @@ -13,7 +13,7 @@ if (browserType) {document.write("
");if (browserV
Index
$#! · 0-9 · A · B · C · D · E · F · G · H · I · J · K · L · M · N · O · P · Q · R · S · T · U · V · W · X · Y · Z
$#!
 __construct
B
$blockorder, STECore
$blocks, STECore
C
 call_tag, STECore
 CantLoadTemplate
 CantSaveTemplate
 Constants, FatalRuntimeError
E
 evalbool, STECore
 exectemplate, STECore
F
$fatal_error_on_missing_tag, STECore
 FatalRuntimeError
 FilesystemStorageAccess
 Functions
G
 get_var_by_name, STECore
 get_var_reference, STECore
L
 License
 load
M
 MODE_SOURCE, FatalRuntimeError
 MODE_TRANSCOMPILED, FatalRuntimeError
$mute_runtime_errors, STECore
P
 parse, FatalRuntimeError
 precompile, FatalRuntimeError
 Public variables, STECore
R
 register_tag, STECore
 RuntimeError
S
 save, StorageAccess
 set_var_by_name, STECore
 ste
 STECore
 StorageAccess
 stupid_template_engine.php
T
 Template modes, FatalRuntimeError
 transcompile, FatalRuntimeError
V
 Variables, STECore
$vars, STECore
-
public function __construct($src,
$transc)
public function __construct($storage_access)
+
public function __construct($src,
$transc)
public function __construct($storage_access)
@@ -21,23 +21,23 @@ if (browserType) {document.write("
");if (browserV -
public function call_tag($name,
$params,
$sub)
Calling a custom tag (builtin ones can not be called)
An exception that a StorageAccess implementation can throw, if it is unable to load a template.
An exception that a StorageAccess implementation can throw, if it is unable to save a template.
+
public function call_tag($name,
$params,
$sub)
Calling a custom tag (builtin ones can not be called)
An exception that a StorageAccess implementation can throw, if it is unable to load a template.
An exception that a StorageAccess implementation can throw, if it is unable to save a template.
-
public function evalbool($txt)
Test, if a text represents false (an empty / only whitespace text) or true (everything else).
public function exectemplate($tpl)
Executes a template and returns the result.
+
public function evalbool($txt)
Test, if a text represents false (an empty / only whitespace text) or true (everything else).
public function exectemplate($tpl)
Executes a template and returns the result.
-
If True, STE will throw a FatalRuntimeError if a tag was called that was not registered, otherwise (default) a regular RuntimeError will be thrown and automatically handled by STE (see <$mute_runtime_errors>).
An Exception a tag can throw, if a fatal (irreparable) runtime error occurred.
The default StorageAccess implementation for loading / saving templates into a directory structure.
+
If True, STE will throw a FatalRuntimeError if a tag was called that was not registered, otherwise (default) a regular RuntimeError will be thrown and automatically handled by STE (see $mute_runtime_errors).
An Exception a tag can throw, if a fatal (irreparable) runtime error occurred.
The default StorageAccess implementation for loading / saving templates into a directory structure.
-
public function get_var_by_name($name)
Get a template variable by its name.
public function &get_var_reference($name,
$create_if_not_exist)
Get a reference to a template variable using a variable name.
+
public function get_var_by_name($name)
Get a template variable by its name.
public function &get_var_reference($name,
$create_if_not_exist)
Get a reference to a template variable using a variable name.
-
This file is licensed under the MIT/X11 License.
public function load($tpl,  
$quiet = False)
Load a template and return its result (blocks not included, use exectemplate for this).
public function load($tpl,
&$mode)
Loading a template.
+
This file is licensed under the MIT/X11 License.
public function load($tpl,  
$quiet = False)
Load a template and return its result (blocks not included, use exectemplate for this).
public function load($tpl,
&$mode)
Loading a template.
@@ -45,19 +45,19 @@ if (browserType) {document.write("
");if (browserV -
function parse($code,
$tpl)
Parsing a STE T/PL template.
function precompile($code)
Precompiling STE T/PL templates.
+
function parse($code,
$tpl)
Parsing a STE T/PL template.
function precompile($code)
Precompiling STE T/PL templates.
-
public function register_tag($name,
$callback)
Register a custom tag.
An Exception that a tag can throw, if a non-fatal runtime error occurred.
+
public function register_tag($name,
$callback)
Register a custom tag.
An Exception that a tag can throw, if a non-fatal runtime error occurred.
-
public function save($tpl,
$data,
$mode)
Saves a template.
public function set_var_by_name($name,
$val)
Set a template variable by its name.
Everything in this file is in this namespace.
The Core of STE
An interface.
The implementation of the Stupid Template Engine.
+
public function save($tpl,
$data,
$mode)
Saves a template.
public function set_var_by_name($name,
$val)
Set a template variable by its name.
Everything in this file is in this namespace.
The Core of STE
An interface.
The implementation of the Stupid Template Engine.
-
function transcompile($ast) /* Transcompile and add some boilerplate code. */
Transcompiles an abstract syntax tree to PHP.
+
function transcompile($ast) /* Transcompile and add some boilerplate code. */
Transcompiles an abstract syntax tree to PHP.
diff --git a/docu/nd/index/Variables.html b/docu/nd/index/Variables.html index 115906e..ae3494b 100644 --- a/docu/nd/index/Variables.html +++ b/docu/nd/index/Variables.html @@ -1,9 +1,9 @@ -Variable Index - + @@ -17,7 +17,7 @@ if (browserType) {document.write("
");if (browserV -
If True, STE will throw a FatalRuntimeError if a tag was called that was not registered, otherwise (default) a regular RuntimeError will be thrown and automatically handled by STE (see <$mute_runtime_errors>).
+
If True, STE will throw a FatalRuntimeError if a tag was called that was not registered, otherwise (default) a regular RuntimeError will be thrown and automatically handled by STE (see $mute_runtime_errors).
diff --git a/docu/nd/javascript/main.js b/docu/nd/javascript/main.js index 91991f5..3f42acd 100644 --- a/docu/nd/javascript/main.js +++ b/docu/nd/javascript/main.js @@ -1,836 +1,841 @@ -// This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure -// Natural Docs is licensed under the GPL - - -// -// Browser Styles -// ____________________________________________________________________________ - -var agt=navigator.userAgent.toLowerCase(); -var browserType; -var browserVer; - -if (agt.indexOf("opera") != -1) - { - browserType = "Opera"; - - if (agt.indexOf("opera 7") != -1 || agt.indexOf("opera/7") != -1) - { browserVer = "Opera7"; } - else if (agt.indexOf("opera 8") != -1 || agt.indexOf("opera/8") != -1) - { browserVer = "Opera8"; } - else if (agt.indexOf("opera 9") != -1 || agt.indexOf("opera/9") != -1) - { browserVer = "Opera9"; } - } - -else if (agt.indexOf("applewebkit") != -1) - { - browserType = "Safari"; - - if (agt.indexOf("version/3") != -1) - { browserVer = "Safari3"; } - else if (agt.indexOf("safari/4") != -1) - { browserVer = "Safari2"; } - } - -else if (agt.indexOf("khtml") != -1) - { - browserType = "Konqueror"; - } - -else if (agt.indexOf("msie") != -1) - { - browserType = "IE"; - - if (agt.indexOf("msie 6") != -1) - { browserVer = "IE6"; } - else if (agt.indexOf("msie 7") != -1) - { browserVer = "IE7"; } - } - -else if (agt.indexOf("gecko") != -1) - { - browserType = "Firefox"; - - if (agt.indexOf("rv:1.7") != -1) - { browserVer = "Firefox1"; } - else if (agt.indexOf("rv:1.8)") != -1 || agt.indexOf("rv:1.8.0") != -1) - { browserVer = "Firefox15"; } - else if (agt.indexOf("rv:1.8.1") != -1) - { browserVer = "Firefox2"; } - } - - -// -// Support Functions -// ____________________________________________________________________________ - - -function GetXPosition(item) - { - var position = 0; - - if (item.offsetWidth != null) - { - while (item != document.body && item != null) - { - position += item.offsetLeft; - item = item.offsetParent; - }; - }; - - return position; - }; - - -function GetYPosition(item) - { - var position = 0; - - if (item.offsetWidth != null) - { - while (item != document.body && item != null) - { - position += item.offsetTop; - item = item.offsetParent; - }; - }; - - return position; - }; - - -function MoveToPosition(item, x, y) - { - // Opera 5 chokes on the px extension, so it can use the Microsoft one instead. - - if (item.style.left != null) - { - item.style.left = x + "px"; - item.style.top = y + "px"; - } - else if (item.style.pixelLeft != null) - { - item.style.pixelLeft = x; - item.style.pixelTop = y; - }; - }; - - -// -// Menu -// ____________________________________________________________________________ - - -function ToggleMenu(id) - { - if (!window.document.getElementById) - { return; }; - - var display = window.document.getElementById(id).style.display; - - if (display == "none") - { display = "block"; } - else - { display = "none"; } - - window.document.getElementById(id).style.display = display; - } - -function HideAllBut(ids, max) - { - if (document.getElementById) - { - ids.sort( function(a,b) { return a - b; } ); - var number = 1; - - while (number < max) - { - if (ids.length > 0 && number == ids[0]) - { ids.shift(); } - else - { - document.getElementById("MGroupContent" + number).style.display = "none"; - }; - - number++; - }; - }; - } - - -// -// Tooltips -// ____________________________________________________________________________ - - -var tooltipTimer = 0; - -function ShowTip(event, tooltipID, linkID) - { - if (tooltipTimer) - { clearTimeout(tooltipTimer); }; - - var docX = event.clientX + window.pageXOffset; - var docY = event.clientY + window.pageYOffset; - - var showCommand = "ReallyShowTip('" + tooltipID + "', '" + linkID + "', " + docX + ", " + docY + ")"; - - tooltipTimer = setTimeout(showCommand, 1000); - } - -function ReallyShowTip(tooltipID, linkID, docX, docY) - { - tooltipTimer = 0; - - var tooltip; - var link; - - if (document.getElementById) - { - tooltip = document.getElementById(tooltipID); - link = document.getElementById(linkID); - } -/* else if (document.all) - { - tooltip = eval("document.all['" + tooltipID + "']"); - link = eval("document.all['" + linkID + "']"); - } -*/ - if (tooltip) - { - var left = GetXPosition(link); - var top = GetYPosition(link); - top += link.offsetHeight; - - - // The fallback method is to use the mouse X and Y relative to the document. We use a separate if and test if its a number - // in case some browser snuck through the above if statement but didn't support everything. - - if (!isFinite(top) || top == 0) - { - left = docX; - top = docY; - } - - // Some spacing to get it out from under the cursor. - - top += 10; - - // Make sure the tooltip doesnt get smushed by being too close to the edge, or in some browsers, go off the edge of the - // page. We do it here because Konqueror does get offsetWidth right even if it doesnt get the positioning right. - - if (tooltip.offsetWidth != null) - { - var width = tooltip.offsetWidth; - var docWidth = document.body.clientWidth; - - if (left + width > docWidth) - { left = docWidth - width - 1; } - - // If there's a horizontal scroll bar we could go past zero because it's using the page width, not the window width. - if (left < 0) - { left = 0; }; - } - - MoveToPosition(tooltip, left, top); - tooltip.style.visibility = "visible"; - } - } - -function HideTip(tooltipID) - { - if (tooltipTimer) - { - clearTimeout(tooltipTimer); - tooltipTimer = 0; - } - - var tooltip; - - if (document.getElementById) - { tooltip = document.getElementById(tooltipID); } - else if (document.all) - { tooltip = eval("document.all['" + tooltipID + "']"); } - - if (tooltip) - { tooltip.style.visibility = "hidden"; } - } - - -// -// Blockquote fix for IE -// ____________________________________________________________________________ - - -function NDOnLoad() - { - if (browserVer == "IE6") - { - var scrollboxes = document.getElementsByTagName('blockquote'); - - if (scrollboxes.item(0)) - { - NDDoResize(); - window.onresize=NDOnResize; - }; - }; - }; - - -var resizeTimer = 0; - -function NDOnResize() - { - if (resizeTimer != 0) - { clearTimeout(resizeTimer); }; - - resizeTimer = setTimeout(NDDoResize, 250); - }; - - -function NDDoResize() - { - var scrollboxes = document.getElementsByTagName('blockquote'); - - var i; - var item; - - i = 0; - while (item = scrollboxes.item(i)) - { - item.style.width = 100; - i++; - }; - - i = 0; - while (item = scrollboxes.item(i)) - { - item.style.width = item.parentNode.offsetWidth; - i++; - }; - - clearTimeout(resizeTimer); - resizeTimer = 0; - } - - - -/* ________________________________________________________________________________________________________ - - Class: SearchPanel - ________________________________________________________________________________________________________ - - A class handling everything associated with the search panel. - - Parameters: - - name - The name of the global variable that will be storing this instance. Is needed to be able to set timeouts. - mode - The mode the search is going to work in. Pass CommandLineOption()>, so the - value will be something like "HTML" or "FramedHTML". - - ________________________________________________________________________________________________________ -*/ - - -function SearchPanel(name, mode, resultsPath) - { - if (!name || !mode || !resultsPath) - { alert("Incorrect parameters to SearchPanel."); }; - - - // Group: Variables - // ________________________________________________________________________ - - /* - var: name - The name of the global variable that will be storing this instance of the class. - */ - this.name = name; - - /* - var: mode - The mode the search is going to work in, such as "HTML" or "FramedHTML". - */ - this.mode = mode; - - /* - var: resultsPath - The relative path from the current HTML page to the results page directory. - */ - this.resultsPath = resultsPath; - - /* - var: keyTimeout - The timeout used between a keystroke and when a search is performed. - */ - this.keyTimeout = 0; - - /* - var: keyTimeoutLength - The length of in thousandths of a second. - */ - this.keyTimeoutLength = 500; - - /* - var: lastSearchValue - The last search string executed, or an empty string if none. - */ - this.lastSearchValue = ""; - - /* - var: lastResultsPage - The last results page. The value is only relevant if is set. - */ - this.lastResultsPage = ""; - - /* - var: deactivateTimeout - - The timeout used between when a control is deactivated and when the entire panel is deactivated. Is necessary - because a control may be deactivated in favor of another control in the same panel, in which case it should stay - active. - */ - this.deactivateTimout = 0; - - /* - var: deactivateTimeoutLength - The length of in thousandths of a second. - */ - this.deactivateTimeoutLength = 200; - - - - - // Group: DOM Elements - // ________________________________________________________________________ - - - // Function: DOMSearchField - this.DOMSearchField = function() - { return document.getElementById("MSearchField"); }; - - // Function: DOMSearchType - this.DOMSearchType = function() - { return document.getElementById("MSearchType"); }; - - // Function: DOMPopupSearchResults - this.DOMPopupSearchResults = function() - { return document.getElementById("MSearchResults"); }; - - // Function: DOMPopupSearchResultsWindow - this.DOMPopupSearchResultsWindow = function() - { return document.getElementById("MSearchResultsWindow"); }; - - // Function: DOMSearchPanel - this.DOMSearchPanel = function() - { return document.getElementById("MSearchPanel"); }; - - - - - // Group: Event Handlers - // ________________________________________________________________________ - - - /* - Function: OnSearchFieldFocus - Called when focus is added or removed from the search field. - */ - this.OnSearchFieldFocus = function(isActive) - { - this.Activate(isActive); - }; - - - /* - Function: OnSearchFieldChange - Called when the content of the search field is changed. - */ - this.OnSearchFieldChange = function() - { - if (this.keyTimeout) - { - clearTimeout(this.keyTimeout); - this.keyTimeout = 0; - }; - - var searchValue = this.DOMSearchField().value.replace(/ +/g, ""); - - if (searchValue != this.lastSearchValue) - { - if (searchValue != "") - { - this.keyTimeout = setTimeout(this.name + ".Search()", this.keyTimeoutLength); - } - else - { - if (this.mode == "HTML") - { this.DOMPopupSearchResultsWindow().style.display = "none"; }; - this.lastSearchValue = ""; - }; - }; - }; - - - /* - Function: OnSearchTypeFocus - Called when focus is added or removed from the search type. - */ - this.OnSearchTypeFocus = function(isActive) - { - this.Activate(isActive); - }; - - - /* - Function: OnSearchTypeChange - Called when the search type is changed. - */ - this.OnSearchTypeChange = function() - { - var searchValue = this.DOMSearchField().value.replace(/ +/g, ""); - - if (searchValue != "") - { - this.Search(); - }; - }; - - - - // Group: Action Functions - // ________________________________________________________________________ - - - /* - Function: CloseResultsWindow - Closes the results window. - */ - this.CloseResultsWindow = function() - { - this.DOMPopupSearchResultsWindow().style.display = "none"; - this.Activate(false, true); - }; - - - /* - Function: Search - Performs a search. - */ - this.Search = function() - { - this.keyTimeout = 0; - - var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); - var searchTopic = this.DOMSearchType().value; - - var pageExtension = searchValue.substr(0,1); - - if (pageExtension.match(/^[a-z]/i)) - { pageExtension = pageExtension.toUpperCase(); } - else if (pageExtension.match(/^[0-9]/)) - { pageExtension = 'Numbers'; } - else - { pageExtension = "Symbols"; }; - - var resultsPage; - var resultsPageWithSearch; - var hasResultsPage; - - // indexSectionsWithContent is defined in searchdata.js - if (indexSectionsWithContent[searchTopic][pageExtension] == true) - { - resultsPage = this.resultsPath + '/' + searchTopic + pageExtension + '.html'; - resultsPageWithSearch = resultsPage+'?'+escape(searchValue); - hasResultsPage = true; - } - else - { - resultsPage = this.resultsPath + '/NoResults.html'; - resultsPageWithSearch = resultsPage; - hasResultsPage = false; - }; - - var resultsFrame; - if (this.mode == "HTML") - { resultsFrame = window.frames.MSearchResults; } - else if (this.mode == "FramedHTML") - { resultsFrame = window.top.frames['Content']; }; - - - if (resultsPage != this.lastResultsPage || - - // Bug in IE. If everything becomes hidden in a run, none of them will be able to be reshown in the next for some - // reason. It counts the right number of results, and you can even read the display as "block" after setting it, but it - // just doesn't work in IE 6 or IE 7. So if we're on the right page but the previous search had no results, reload the - // page anyway to get around the bug. - (browserType == "IE" && hasResultsPage && - (!resultsFrame.searchResults || resultsFrame.searchResults.lastMatchCount == 0)) ) - - { - resultsFrame.location.href = resultsPageWithSearch; - } - - // So if the results page is right and there's no IE bug, reperform the search on the existing page. We have to check if there - // are results because NoResults.html doesn't have any JavaScript, and it would be useless to do anything on that page even - // if it did. - else if (hasResultsPage) - { - // We need to check if this exists in case the frame is present but didn't finish loading. - if (resultsFrame.searchResults) - { resultsFrame.searchResults.Search(searchValue); } - - // Otherwise just reload instead of waiting. - else - { resultsFrame.location.href = resultsPageWithSearch; }; - }; - - - var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); - - if (this.mode == "HTML" && domPopupSearchResultsWindow.style.display != "block") - { - var domSearchType = this.DOMSearchType(); - - var left = GetXPosition(domSearchType); - var top = GetYPosition(domSearchType) + domSearchType.offsetHeight; - - MoveToPosition(domPopupSearchResultsWindow, left, top); - domPopupSearchResultsWindow.style.display = 'block'; - }; - - - this.lastSearchValue = searchValue; - this.lastResultsPage = resultsPage; - }; - - - - // Group: Activation Functions - // Functions that handle whether the entire panel is active or not. - // ________________________________________________________________________ - - - /* - Function: Activate - - Activates or deactivates the search panel, resetting things to their default values if necessary. You can call this on every - control's OnBlur() and it will handle not deactivating the entire panel when focus is just switching between them transparently. - - Parameters: - - isActive - Whether you're activating or deactivating the panel. - ignoreDeactivateDelay - Set if you're positive the action will deactivate the panel and thus want to skip the delay. - */ - this.Activate = function(isActive, ignoreDeactivateDelay) - { - // We want to ignore isActive being false while the results window is open. - if (isActive || (this.mode == "HTML" && this.DOMPopupSearchResultsWindow().style.display == "block")) - { - if (this.inactivateTimeout) - { - clearTimeout(this.inactivateTimeout); - this.inactivateTimeout = 0; - }; - - this.DOMSearchPanel().className = 'MSearchPanelActive'; - - var searchField = this.DOMSearchField(); - - if (searchField.value == 'Search') - { searchField.value = ""; } - } - else if (!ignoreDeactivateDelay) - { - this.inactivateTimeout = setTimeout(this.name + ".InactivateAfterTimeout()", this.inactivateTimeoutLength); - } - else - { - this.InactivateAfterTimeout(); - }; - }; - - - /* - Function: InactivateAfterTimeout - - Called by , which is set by . Inactivation occurs on a timeout because a control may - receive OnBlur() when focus is really transferring to another control in the search panel. In this case we don't want to - actually deactivate the panel because not only would that cause a visible flicker but it could also reset the search value. - So by doing it on a timeout instead, there's a short period where the second control's OnFocus() can cancel the deactivation. - */ - this.InactivateAfterTimeout = function() - { - this.inactivateTimeout = 0; - - this.DOMSearchPanel().className = 'MSearchPanelInactive'; - this.DOMSearchField().value = "Search"; - - this.lastSearchValue = ""; - this.lastResultsPage = ""; - }; - }; - - - - -/* ________________________________________________________________________________________________________ - - Class: SearchResults - _________________________________________________________________________________________________________ - - The class that handles everything on the search results page. - _________________________________________________________________________________________________________ -*/ - - -function SearchResults(name, mode) - { - /* - var: mode - The mode the search is going to work in, such as "HTML" or "FramedHTML". - */ - this.mode = mode; - - /* - var: lastMatchCount - The number of matches from the last run of . - */ - this.lastMatchCount = 0; - - - /* - Function: Toggle - Toggles the visibility of the passed element ID. - */ - this.Toggle = function(id) - { - if (this.mode == "FramedHTML") - { return; }; - - var parentElement = document.getElementById(id); - - var element = parentElement.firstChild; - - while (element && element != parentElement) - { - if (element.nodeName == 'DIV' && element.className == 'ISubIndex') - { - if (element.style.display == 'block') - { element.style.display = "none"; } - else - { element.style.display = 'block'; } - }; - - if (element.nodeName == 'DIV' && element.hasChildNodes()) - { element = element.firstChild; } - else if (element.nextSibling) - { element = element.nextSibling; } - else - { - do - { - element = element.parentNode; - } - while (element && element != parentElement && !element.nextSibling); - - if (element && element != parentElement) - { element = element.nextSibling; }; - }; - }; - }; - - - /* - Function: Search - - Searches for the passed string. If there is no parameter, it takes it from the URL query. - - Always returns true, since other documents may try to call it and that may or may not be possible. - */ - this.Search = function(search) - { - if (!search) - { - search = window.location.search; - search = search.substring(1); // Remove the leading ? - search = unescape(search); - }; - - search = search.replace(/^ +/, ""); - search = search.replace(/ +$/, ""); - search = search.toLowerCase(); - - if (search.match(/[^a-z0-9]/)) // Just a little speedup so it doesn't have to go through the below unnecessarily. - { - search = search.replace(/\_/g, "_und"); - search = search.replace(/\ +/gi, "_spc"); - search = search.replace(/\~/g, "_til"); - search = search.replace(/\!/g, "_exc"); - search = search.replace(/\@/g, "_att"); - search = search.replace(/\#/g, "_num"); - search = search.replace(/\$/g, "_dol"); - search = search.replace(/\%/g, "_pct"); - search = search.replace(/\^/g, "_car"); - search = search.replace(/\&/g, "_amp"); - search = search.replace(/\*/g, "_ast"); - search = search.replace(/\(/g, "_lpa"); - search = search.replace(/\)/g, "_rpa"); - search = search.replace(/\-/g, "_min"); - search = search.replace(/\+/g, "_plu"); - search = search.replace(/\=/g, "_equ"); - search = search.replace(/\{/g, "_lbc"); - search = search.replace(/\}/g, "_rbc"); - search = search.replace(/\[/g, "_lbk"); - search = search.replace(/\]/g, "_rbk"); - search = search.replace(/\:/g, "_col"); - search = search.replace(/\;/g, "_sco"); - search = search.replace(/\"/g, "_quo"); - search = search.replace(/\'/g, "_apo"); - search = search.replace(/\/g, "_ran"); - search = search.replace(/\,/g, "_com"); - search = search.replace(/\./g, "_per"); - search = search.replace(/\?/g, "_que"); - search = search.replace(/\//g, "_sla"); - search = search.replace(/[^a-z0-9\_]i/gi, "_zzz"); - }; - - var resultRows = document.getElementsByTagName("div"); - var matches = 0; - - var i = 0; - while (i < resultRows.length) - { - var row = resultRows.item(i); - - if (row.className == "SRResult") - { - var rowMatchName = row.id.toLowerCase(); - rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); - - if (search.length <= rowMatchName.length && rowMatchName.substr(0, search.length) == search) - { - row.style.display = "block"; - matches++; - } - else - { row.style.display = "none"; }; - }; - - i++; - }; - - document.getElementById("Searching").style.display="none"; - - if (matches == 0) - { document.getElementById("NoMatches").style.display="block"; } - else - { document.getElementById("NoMatches").style.display="none"; } - - this.lastMatchCount = matches; - - return true; - }; - }; - +// This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure +// Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL) +// Refer to License.txt for the complete details + +// This file may be distributed with documentation files generated by Natural Docs. +// Such documentation is not covered by Natural Docs' copyright and licensing, +// and may have its own copyright and distribution terms as decided by its author. + + +// +// Browser Styles +// ____________________________________________________________________________ + +var agt=navigator.userAgent.toLowerCase(); +var browserType; +var browserVer; + +if (agt.indexOf("opera") != -1) + { + browserType = "Opera"; + + if (agt.indexOf("opera 7") != -1 || agt.indexOf("opera/7") != -1) + { browserVer = "Opera7"; } + else if (agt.indexOf("opera 8") != -1 || agt.indexOf("opera/8") != -1) + { browserVer = "Opera8"; } + else if (agt.indexOf("opera 9") != -1 || agt.indexOf("opera/9") != -1) + { browserVer = "Opera9"; } + } + +else if (agt.indexOf("applewebkit") != -1) + { + browserType = "Safari"; + + if (agt.indexOf("version/3") != -1) + { browserVer = "Safari3"; } + else if (agt.indexOf("safari/4") != -1) + { browserVer = "Safari2"; } + } + +else if (agt.indexOf("khtml") != -1) + { + browserType = "Konqueror"; + } + +else if (agt.indexOf("msie") != -1) + { + browserType = "IE"; + + if (agt.indexOf("msie 6") != -1) + { browserVer = "IE6"; } + else if (agt.indexOf("msie 7") != -1) + { browserVer = "IE7"; } + } + +else if (agt.indexOf("gecko") != -1) + { + browserType = "Firefox"; + + if (agt.indexOf("rv:1.7") != -1) + { browserVer = "Firefox1"; } + else if (agt.indexOf("rv:1.8)") != -1 || agt.indexOf("rv:1.8.0") != -1) + { browserVer = "Firefox15"; } + else if (agt.indexOf("rv:1.8.1") != -1) + { browserVer = "Firefox2"; } + } + + +// +// Support Functions +// ____________________________________________________________________________ + + +function GetXPosition(item) + { + var position = 0; + + if (item.offsetWidth != null) + { + while (item != document.body && item != null) + { + position += item.offsetLeft; + item = item.offsetParent; + }; + }; + + return position; + }; + + +function GetYPosition(item) + { + var position = 0; + + if (item.offsetWidth != null) + { + while (item != document.body && item != null) + { + position += item.offsetTop; + item = item.offsetParent; + }; + }; + + return position; + }; + + +function MoveToPosition(item, x, y) + { + // Opera 5 chokes on the px extension, so it can use the Microsoft one instead. + + if (item.style.left != null) + { + item.style.left = x + "px"; + item.style.top = y + "px"; + } + else if (item.style.pixelLeft != null) + { + item.style.pixelLeft = x; + item.style.pixelTop = y; + }; + }; + + +// +// Menu +// ____________________________________________________________________________ + + +function ToggleMenu(id) + { + if (!window.document.getElementById) + { return; }; + + var display = window.document.getElementById(id).style.display; + + if (display == "none") + { display = "block"; } + else + { display = "none"; } + + window.document.getElementById(id).style.display = display; + } + +function HideAllBut(ids, max) + { + if (document.getElementById) + { + ids.sort( function(a,b) { return a - b; } ); + var number = 1; + + while (number < max) + { + if (ids.length > 0 && number == ids[0]) + { ids.shift(); } + else + { + document.getElementById("MGroupContent" + number).style.display = "none"; + }; + + number++; + }; + }; + } + + +// +// Tooltips +// ____________________________________________________________________________ + + +var tooltipTimer = 0; + +function ShowTip(event, tooltipID, linkID) + { + if (tooltipTimer) + { clearTimeout(tooltipTimer); }; + + var docX = event.clientX + window.pageXOffset; + var docY = event.clientY + window.pageYOffset; + + var showCommand = "ReallyShowTip('" + tooltipID + "', '" + linkID + "', " + docX + ", " + docY + ")"; + + tooltipTimer = setTimeout(showCommand, 1000); + } + +function ReallyShowTip(tooltipID, linkID, docX, docY) + { + tooltipTimer = 0; + + var tooltip; + var link; + + if (document.getElementById) + { + tooltip = document.getElementById(tooltipID); + link = document.getElementById(linkID); + } +/* else if (document.all) + { + tooltip = eval("document.all['" + tooltipID + "']"); + link = eval("document.all['" + linkID + "']"); + } +*/ + if (tooltip) + { + var left = GetXPosition(link); + var top = GetYPosition(link); + top += link.offsetHeight; + + + // The fallback method is to use the mouse X and Y relative to the document. We use a separate if and test if its a number + // in case some browser snuck through the above if statement but didn't support everything. + + if (!isFinite(top) || top == 0) + { + left = docX; + top = docY; + } + + // Some spacing to get it out from under the cursor. + + top += 10; + + // Make sure the tooltip doesnt get smushed by being too close to the edge, or in some browsers, go off the edge of the + // page. We do it here because Konqueror does get offsetWidth right even if it doesnt get the positioning right. + + if (tooltip.offsetWidth != null) + { + var width = tooltip.offsetWidth; + var docWidth = document.body.clientWidth; + + if (left + width > docWidth) + { left = docWidth - width - 1; } + + // If there's a horizontal scroll bar we could go past zero because it's using the page width, not the window width. + if (left < 0) + { left = 0; }; + } + + MoveToPosition(tooltip, left, top); + tooltip.style.visibility = "visible"; + } + } + +function HideTip(tooltipID) + { + if (tooltipTimer) + { + clearTimeout(tooltipTimer); + tooltipTimer = 0; + } + + var tooltip; + + if (document.getElementById) + { tooltip = document.getElementById(tooltipID); } + else if (document.all) + { tooltip = eval("document.all['" + tooltipID + "']"); } + + if (tooltip) + { tooltip.style.visibility = "hidden"; } + } + + +// +// Blockquote fix for IE +// ____________________________________________________________________________ + + +function NDOnLoad() + { + if (browserVer == "IE6") + { + var scrollboxes = document.getElementsByTagName('blockquote'); + + if (scrollboxes.item(0)) + { + NDDoResize(); + window.onresize=NDOnResize; + }; + }; + }; + + +var resizeTimer = 0; + +function NDOnResize() + { + if (resizeTimer != 0) + { clearTimeout(resizeTimer); }; + + resizeTimer = setTimeout(NDDoResize, 250); + }; + + +function NDDoResize() + { + var scrollboxes = document.getElementsByTagName('blockquote'); + + var i; + var item; + + i = 0; + while (item = scrollboxes.item(i)) + { + item.style.width = 100; + i++; + }; + + i = 0; + while (item = scrollboxes.item(i)) + { + item.style.width = item.parentNode.offsetWidth; + i++; + }; + + clearTimeout(resizeTimer); + resizeTimer = 0; + } + + + +/* ________________________________________________________________________________________________________ + + Class: SearchPanel + ________________________________________________________________________________________________________ + + A class handling everything associated with the search panel. + + Parameters: + + name - The name of the global variable that will be storing this instance. Is needed to be able to set timeouts. + mode - The mode the search is going to work in. Pass CommandLineOption()>, so the + value will be something like "HTML" or "FramedHTML". + + ________________________________________________________________________________________________________ +*/ + + +function SearchPanel(name, mode, resultsPath) + { + if (!name || !mode || !resultsPath) + { alert("Incorrect parameters to SearchPanel."); }; + + + // Group: Variables + // ________________________________________________________________________ + + /* + var: name + The name of the global variable that will be storing this instance of the class. + */ + this.name = name; + + /* + var: mode + The mode the search is going to work in, such as "HTML" or "FramedHTML". + */ + this.mode = mode; + + /* + var: resultsPath + The relative path from the current HTML page to the results page directory. + */ + this.resultsPath = resultsPath; + + /* + var: keyTimeout + The timeout used between a keystroke and when a search is performed. + */ + this.keyTimeout = 0; + + /* + var: keyTimeoutLength + The length of in thousandths of a second. + */ + this.keyTimeoutLength = 500; + + /* + var: lastSearchValue + The last search string executed, or an empty string if none. + */ + this.lastSearchValue = ""; + + /* + var: lastResultsPage + The last results page. The value is only relevant if is set. + */ + this.lastResultsPage = ""; + + /* + var: deactivateTimeout + + The timeout used between when a control is deactivated and when the entire panel is deactivated. Is necessary + because a control may be deactivated in favor of another control in the same panel, in which case it should stay + active. + */ + this.deactivateTimout = 0; + + /* + var: deactivateTimeoutLength + The length of in thousandths of a second. + */ + this.deactivateTimeoutLength = 200; + + + + + // Group: DOM Elements + // ________________________________________________________________________ + + + // Function: DOMSearchField + this.DOMSearchField = function() + { return document.getElementById("MSearchField"); }; + + // Function: DOMSearchType + this.DOMSearchType = function() + { return document.getElementById("MSearchType"); }; + + // Function: DOMPopupSearchResults + this.DOMPopupSearchResults = function() + { return document.getElementById("MSearchResults"); }; + + // Function: DOMPopupSearchResultsWindow + this.DOMPopupSearchResultsWindow = function() + { return document.getElementById("MSearchResultsWindow"); }; + + // Function: DOMSearchPanel + this.DOMSearchPanel = function() + { return document.getElementById("MSearchPanel"); }; + + + + + // Group: Event Handlers + // ________________________________________________________________________ + + + /* + Function: OnSearchFieldFocus + Called when focus is added or removed from the search field. + */ + this.OnSearchFieldFocus = function(isActive) + { + this.Activate(isActive); + }; + + + /* + Function: OnSearchFieldChange + Called when the content of the search field is changed. + */ + this.OnSearchFieldChange = function() + { + if (this.keyTimeout) + { + clearTimeout(this.keyTimeout); + this.keyTimeout = 0; + }; + + var searchValue = this.DOMSearchField().value.replace(/ +/g, ""); + + if (searchValue != this.lastSearchValue) + { + if (searchValue != "") + { + this.keyTimeout = setTimeout(this.name + ".Search()", this.keyTimeoutLength); + } + else + { + if (this.mode == "HTML") + { this.DOMPopupSearchResultsWindow().style.display = "none"; }; + this.lastSearchValue = ""; + }; + }; + }; + + + /* + Function: OnSearchTypeFocus + Called when focus is added or removed from the search type. + */ + this.OnSearchTypeFocus = function(isActive) + { + this.Activate(isActive); + }; + + + /* + Function: OnSearchTypeChange + Called when the search type is changed. + */ + this.OnSearchTypeChange = function() + { + var searchValue = this.DOMSearchField().value.replace(/ +/g, ""); + + if (searchValue != "") + { + this.Search(); + }; + }; + + + + // Group: Action Functions + // ________________________________________________________________________ + + + /* + Function: CloseResultsWindow + Closes the results window. + */ + this.CloseResultsWindow = function() + { + this.DOMPopupSearchResultsWindow().style.display = "none"; + this.Activate(false, true); + }; + + + /* + Function: Search + Performs a search. + */ + this.Search = function() + { + this.keyTimeout = 0; + + var searchValue = this.DOMSearchField().value.replace(/^ +/, ""); + var searchTopic = this.DOMSearchType().value; + + var pageExtension = searchValue.substr(0,1); + + if (pageExtension.match(/^[a-z]/i)) + { pageExtension = pageExtension.toUpperCase(); } + else if (pageExtension.match(/^[0-9]/)) + { pageExtension = 'Numbers'; } + else + { pageExtension = "Symbols"; }; + + var resultsPage; + var resultsPageWithSearch; + var hasResultsPage; + + // indexSectionsWithContent is defined in searchdata.js + if (indexSectionsWithContent[searchTopic][pageExtension] == true) + { + resultsPage = this.resultsPath + '/' + searchTopic + pageExtension + '.html'; + resultsPageWithSearch = resultsPage+'?'+escape(searchValue); + hasResultsPage = true; + } + else + { + resultsPage = this.resultsPath + '/NoResults.html'; + resultsPageWithSearch = resultsPage; + hasResultsPage = false; + }; + + var resultsFrame; + if (this.mode == "HTML") + { resultsFrame = window.frames.MSearchResults; } + else if (this.mode == "FramedHTML") + { resultsFrame = window.top.frames['Content']; }; + + + if (resultsPage != this.lastResultsPage || + + // Bug in IE. If everything becomes hidden in a run, none of them will be able to be reshown in the next for some + // reason. It counts the right number of results, and you can even read the display as "block" after setting it, but it + // just doesn't work in IE 6 or IE 7. So if we're on the right page but the previous search had no results, reload the + // page anyway to get around the bug. + (browserType == "IE" && hasResultsPage && + (!resultsFrame.searchResults || resultsFrame.searchResults.lastMatchCount == 0)) ) + + { + resultsFrame.location.href = resultsPageWithSearch; + } + + // So if the results page is right and there's no IE bug, reperform the search on the existing page. We have to check if there + // are results because NoResults.html doesn't have any JavaScript, and it would be useless to do anything on that page even + // if it did. + else if (hasResultsPage) + { + // We need to check if this exists in case the frame is present but didn't finish loading. + if (resultsFrame.searchResults) + { resultsFrame.searchResults.Search(searchValue); } + + // Otherwise just reload instead of waiting. + else + { resultsFrame.location.href = resultsPageWithSearch; }; + }; + + + var domPopupSearchResultsWindow = this.DOMPopupSearchResultsWindow(); + + if (this.mode == "HTML" && domPopupSearchResultsWindow.style.display != "block") + { + var domSearchType = this.DOMSearchType(); + + var left = GetXPosition(domSearchType); + var top = GetYPosition(domSearchType) + domSearchType.offsetHeight; + + MoveToPosition(domPopupSearchResultsWindow, left, top); + domPopupSearchResultsWindow.style.display = 'block'; + }; + + + this.lastSearchValue = searchValue; + this.lastResultsPage = resultsPage; + }; + + + + // Group: Activation Functions + // Functions that handle whether the entire panel is active or not. + // ________________________________________________________________________ + + + /* + Function: Activate + + Activates or deactivates the search panel, resetting things to their default values if necessary. You can call this on every + control's OnBlur() and it will handle not deactivating the entire panel when focus is just switching between them transparently. + + Parameters: + + isActive - Whether you're activating or deactivating the panel. + ignoreDeactivateDelay - Set if you're positive the action will deactivate the panel and thus want to skip the delay. + */ + this.Activate = function(isActive, ignoreDeactivateDelay) + { + // We want to ignore isActive being false while the results window is open. + if (isActive || (this.mode == "HTML" && this.DOMPopupSearchResultsWindow().style.display == "block")) + { + if (this.inactivateTimeout) + { + clearTimeout(this.inactivateTimeout); + this.inactivateTimeout = 0; + }; + + this.DOMSearchPanel().className = 'MSearchPanelActive'; + + var searchField = this.DOMSearchField(); + + if (searchField.value == 'Search') + { searchField.value = ""; } + } + else if (!ignoreDeactivateDelay) + { + this.inactivateTimeout = setTimeout(this.name + ".InactivateAfterTimeout()", this.inactivateTimeoutLength); + } + else + { + this.InactivateAfterTimeout(); + }; + }; + + + /* + Function: InactivateAfterTimeout + + Called by , which is set by . Inactivation occurs on a timeout because a control may + receive OnBlur() when focus is really transferring to another control in the search panel. In this case we don't want to + actually deactivate the panel because not only would that cause a visible flicker but it could also reset the search value. + So by doing it on a timeout instead, there's a short period where the second control's OnFocus() can cancel the deactivation. + */ + this.InactivateAfterTimeout = function() + { + this.inactivateTimeout = 0; + + this.DOMSearchPanel().className = 'MSearchPanelInactive'; + this.DOMSearchField().value = "Search"; + + this.lastSearchValue = ""; + this.lastResultsPage = ""; + }; + }; + + + + +/* ________________________________________________________________________________________________________ + + Class: SearchResults + _________________________________________________________________________________________________________ + + The class that handles everything on the search results page. + _________________________________________________________________________________________________________ +*/ + + +function SearchResults(name, mode) + { + /* + var: mode + The mode the search is going to work in, such as "HTML" or "FramedHTML". + */ + this.mode = mode; + + /* + var: lastMatchCount + The number of matches from the last run of . + */ + this.lastMatchCount = 0; + + + /* + Function: Toggle + Toggles the visibility of the passed element ID. + */ + this.Toggle = function(id) + { + if (this.mode == "FramedHTML") + { return; }; + + var parentElement = document.getElementById(id); + + var element = parentElement.firstChild; + + while (element && element != parentElement) + { + if (element.nodeName == 'DIV' && element.className == 'ISubIndex') + { + if (element.style.display == 'block') + { element.style.display = "none"; } + else + { element.style.display = 'block'; } + }; + + if (element.nodeName == 'DIV' && element.hasChildNodes()) + { element = element.firstChild; } + else if (element.nextSibling) + { element = element.nextSibling; } + else + { + do + { + element = element.parentNode; + } + while (element && element != parentElement && !element.nextSibling); + + if (element && element != parentElement) + { element = element.nextSibling; }; + }; + }; + }; + + + /* + Function: Search + + Searches for the passed string. If there is no parameter, it takes it from the URL query. + + Always returns true, since other documents may try to call it and that may or may not be possible. + */ + this.Search = function(search) + { + if (!search) + { + search = window.location.search; + search = search.substring(1); // Remove the leading ? + search = unescape(search); + }; + + search = search.replace(/^ +/, ""); + search = search.replace(/ +$/, ""); + search = search.toLowerCase(); + + if (search.match(/[^a-z0-9]/)) // Just a little speedup so it doesn't have to go through the below unnecessarily. + { + search = search.replace(/\_/g, "_und"); + search = search.replace(/\ +/gi, "_spc"); + search = search.replace(/\~/g, "_til"); + search = search.replace(/\!/g, "_exc"); + search = search.replace(/\@/g, "_att"); + search = search.replace(/\#/g, "_num"); + search = search.replace(/\$/g, "_dol"); + search = search.replace(/\%/g, "_pct"); + search = search.replace(/\^/g, "_car"); + search = search.replace(/\&/g, "_amp"); + search = search.replace(/\*/g, "_ast"); + search = search.replace(/\(/g, "_lpa"); + search = search.replace(/\)/g, "_rpa"); + search = search.replace(/\-/g, "_min"); + search = search.replace(/\+/g, "_plu"); + search = search.replace(/\=/g, "_equ"); + search = search.replace(/\{/g, "_lbc"); + search = search.replace(/\}/g, "_rbc"); + search = search.replace(/\[/g, "_lbk"); + search = search.replace(/\]/g, "_rbk"); + search = search.replace(/\:/g, "_col"); + search = search.replace(/\;/g, "_sco"); + search = search.replace(/\"/g, "_quo"); + search = search.replace(/\'/g, "_apo"); + search = search.replace(/\/g, "_ran"); + search = search.replace(/\,/g, "_com"); + search = search.replace(/\./g, "_per"); + search = search.replace(/\?/g, "_que"); + search = search.replace(/\//g, "_sla"); + search = search.replace(/[^a-z0-9\_]i/gi, "_zzz"); + }; + + var resultRows = document.getElementsByTagName("div"); + var matches = 0; + + var i = 0; + while (i < resultRows.length) + { + var row = resultRows.item(i); + + if (row.className == "SRResult") + { + var rowMatchName = row.id.toLowerCase(); + rowMatchName = rowMatchName.replace(/^sr\d*_/, ''); + + if (search.length <= rowMatchName.length && rowMatchName.substr(0, search.length) == search) + { + row.style.display = "block"; + matches++; + } + else + { row.style.display = "none"; }; + }; + + i++; + }; + + document.getElementById("Searching").style.display="none"; + + if (matches == 0) + { document.getElementById("NoMatches").style.display="block"; } + else + { document.getElementById("NoMatches").style.display="none"; } + + this.lastMatchCount = matches; + + return true; + }; + }; + diff --git a/docu/nd/javascript/prettify.js b/docu/nd/javascript/prettify.js new file mode 100644 index 0000000..fda4bf1 --- /dev/null +++ b/docu/nd/javascript/prettify.js @@ -0,0 +1,1526 @@ + +// This code comes from the December 2009 release of Google Prettify, which is Copyright © 2006 Google Inc. +// Minor modifications are marked with "ND Change" comments. +// As part of Natural Docs, this code is licensed under version 3 of the GNU Affero General Public License (AGPL.) +// However, it may also be obtained separately under version 2.0 of the Apache License. +// Refer to License.txt for the complete details + + +// Main code +// ____________________________________________________________________________ + +// Copyright (C) 2006 Google Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +/** + * @fileoverview + * some functions for browser-side pretty printing of code contained in html. + *

+ * + * For a fairly comprehensive set of languages see the + * README + * file that came with this source. At a minimum, the lexer should work on a + * number of languages including C and friends, Java, Python, Bash, SQL, HTML, + * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk + * and a subset of Perl, but, because of commenting conventions, doesn't work on + * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class. + *

+ * Usage:

    + *
  1. include this source file in an html page via + * {@code } + *
  2. define style rules. See the example page for examples. + *
  3. mark the {@code
    } and {@code } tags in your source with
    + *    {@code class=prettyprint.}
    + *    You can also use the (html deprecated) {@code } tag, but the pretty
    + *    printer needs to do more substantial DOM manipulations to support that, so
    + *    some css styles may not be preserved.
    + * </ol>
    + * That's it.  I wanted to keep the API as simple as possible, so there's no
    + * need to specify which language the code is in, but if you wish, you can add
    + * another class to the {@code <pre>} or {@code <code>} element to specify the
    + * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
    + * starts with "lang-" followed by a file extension, specifies the file type.
    + * See the "lang-*.js" files in this directory for code that implements
    + * per-language file handlers.
    + * <p>
    + * Change log:<br>
    + * cbeust, 2006/08/22
    + * <blockquote>
    + *   Java annotations (start with "@") are now captured as literals ("lit")
    + * </blockquote>
    + * @requires console
    + * @overrides window
    + */
    +
    +// JSLint declarations
    +/*global console, document, navigator, setTimeout, window */
    +
    +/**
    + * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
    + * UI events.
    + * If set to {@code false}, {@code prettyPrint()} is synchronous.
    + */
    +window['PR_SHOULD_USE_CONTINUATION'] = true;
    +
    +/** the number of characters between tab columns */
    +window['PR_TAB_WIDTH'] = 8;
    +
    +/** Walks the DOM returning a properly escaped version of innerHTML.
    +  * @param {Node} node
    +  * @param {Array.<string>} out output buffer that receives chunks of HTML.
    +  */
    +window['PR_normalizedHtml']
    +
    +/** Contains functions for creating and registering new language handlers.
    +  * @type {Object}
    +  */
    +  = window['PR']
    +
    +/** Pretty print a chunk of code.
    +  *
    +  * @param {string} sourceCodeHtml code as html
    +  * @return {string} code as html, but prettier
    +  */
    +  = window['prettyPrintOne']
    +/** Find all the {@code <pre>} and {@code <code>} tags in the DOM with
    +  * {@code class=prettyprint} and prettify them.
    +  * @param {Function?} opt_whenDone if specified, called when the last entry
    +  *     has been finished.
    +  */
    +  = window['prettyPrint'] = void 0;
    +
    +/** browser detection. @extern @returns false if not IE, otherwise the major version. */
    +window['_pr_isIE6'] = function () {
    +  var ieVersion = navigator && navigator.userAgent &&
    +      navigator.userAgent.match(/\bMSIE ([678])\./);
    +  ieVersion = ieVersion ? +ieVersion[1] : false;
    +  window['_pr_isIE6'] = function () { return ieVersion; };
    +  return ieVersion;
    +};
    +
    +
    +(function () {
    +  // Keyword lists for various languages.
    +  var FLOW_CONTROL_KEYWORDS =
    +      "break continue do else for if return while ";
    +  var C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "auto case char const default " +
    +      "double enum extern float goto int long register short signed sizeof " +
    +      "static struct switch typedef union unsigned void volatile ";
    +  var COMMON_KEYWORDS = C_KEYWORDS + "catch class delete false import " +
    +      "new operator private protected public this throw true try typeof ";
    +  var CPP_KEYWORDS = COMMON_KEYWORDS + "alignof align_union asm axiom bool " +
    +      "concept concept_map const_cast constexpr decltype " +
    +      "dynamic_cast explicit export friend inline late_check " +
    +      "mutable namespace nullptr reinterpret_cast static_assert static_cast " +
    +      "template typeid typename using virtual wchar_t where ";
    +  var JAVA_KEYWORDS = COMMON_KEYWORDS +
    +      "abstract boolean byte extends final finally implements import " +
    +      "instanceof null native package strictfp super synchronized throws " +
    +      "transient ";
    +  var CSHARP_KEYWORDS = JAVA_KEYWORDS +
    +      "as base by checked decimal delegate descending event " +
    +      "fixed foreach from group implicit in interface internal into is lock " +
    +      "object out override orderby params partial readonly ref sbyte sealed " +
    +      "stackalloc string select uint ulong unchecked unsafe ushort var ";
    +  var JSCRIPT_KEYWORDS = COMMON_KEYWORDS +
    +      "debugger eval export function get null set undefined var with " +
    +      "Infinity NaN ";
    +  var PERL_KEYWORDS = "caller delete die do dump elsif eval exit foreach for " +
    +      "goto if import last local my next no our print package redo require " +
    +      "sub undef unless until use wantarray while BEGIN END ";
    +  var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "and as assert class def del " +
    +      "elif except exec finally from global import in is lambda " +
    +      "nonlocal not or pass print raise try with yield " +
    +      "False True None ";
    +  var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "alias and begin case class def" +
    +      " defined elsif end ensure false in module next nil not or redo rescue " +
    +      "retry self super then true undef unless until when yield BEGIN END ";
    +  var SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "case done elif esac eval fi " +
    +      "function in local set then until ";
    +  var ALL_KEYWORDS = (
    +      CPP_KEYWORDS + CSHARP_KEYWORDS + JSCRIPT_KEYWORDS + PERL_KEYWORDS +
    +      PYTHON_KEYWORDS + RUBY_KEYWORDS + SH_KEYWORDS);
    +
    +  // token style names.  correspond to css classes
    +  /** token style for a string literal */
    +  var PR_STRING = 'str';
    +  /** token style for a keyword */
    +  var PR_KEYWORD = 'kwd';
    +  /** token style for a comment */
    +  var PR_COMMENT = 'com';
    +  /** token style for a type */
    +  var PR_TYPE = 'typ';
    +  /** token style for a literal value.  e.g. 1, null, true. */
    +  var PR_LITERAL = 'lit';
    +  /** token style for a punctuation string. */
    +  var PR_PUNCTUATION = 'pun';
    +  /** token style for a punctuation string. */
    +  var PR_PLAIN = 'pln';
    +
    +  /** token style for an sgml tag. */
    +  var PR_TAG = 'tag';
    +  /** token style for a markup declaration such as a DOCTYPE. */
    +  var PR_DECLARATION = 'dec';
    +  /** token style for embedded source. */
    +  var PR_SOURCE = 'src';
    +  /** token style for an sgml attribute name. */
    +  var PR_ATTRIB_NAME = 'atn';
    +  /** token style for an sgml attribute value. */
    +  var PR_ATTRIB_VALUE = 'atv';
    +
    +  /**
    +   * A class that indicates a section of markup that is not code, e.g. to allow
    +   * embedding of line numbers within code listings.
    +   */
    +  var PR_NOCODE = 'nocode';
    +
    +  /** A set of tokens that can precede a regular expression literal in
    +    * javascript.
    +    * http://www.mozilla.org/js/language/js20/rationale/syntax.html has the full
    +    * list, but I've removed ones that might be problematic when seen in
    +    * languages that don't support regular expression literals.
    +    *
    +    * <p>Specifically, I've removed any keywords that can't precede a regexp
    +    * literal in a syntactically legal javascript program, and I've removed the
    +    * "in" keyword since it's not a keyword in many languages, and might be used
    +    * as a count of inches.
    +    *
    +    * <p>The link a above does not accurately describe EcmaScript rules since
    +    * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
    +    * very well in practice.
    +    *
    +    * @private
    +    */
    +  var REGEXP_PRECEDER_PATTERN = function () {
    +      var preceders = [
    +          "!", "!=", "!==", "#", "%", "%=", "&", "&&", "&&=",
    +          "&=", "(", "*", "*=", /* "+", */ "+=", ",", /* "-", */ "-=",
    +          "->", /*".", "..", "...", handled below */ "/", "/=", ":", "::", ";",
    +          "<", "<<", "<<=", "<=", "=", "==", "===", ">",
    +          ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[",
    +          "^", "^=", "^^", "^^=", "{", "|", "|=", "||",
    +          "||=", "~" /* handles =~ and !~ */,
    +          "break", "case", "continue", "delete",
    +          "do", "else", "finally", "instanceof",
    +          "return", "throw", "try", "typeof"
    +          ];
    +      var pattern = '(?:^^|[+-]';
    +      for (var i = 0; i < preceders.length; ++i) {
    +        pattern += '|' + preceders[i].replace(/([^=<>:&a-z])/g, '\\$1');
    +      }
    +      pattern += ')\\s*';  // matches at end, and matches empty string
    +      return pattern;
    +      // CAVEAT: this does not properly handle the case where a regular
    +      // expression immediately follows another since a regular expression may
    +      // have flags for case-sensitivity and the like.  Having regexp tokens
    +      // adjacent is not valid in any language I'm aware of, so I'm punting.
    +      // TODO: maybe style special characters inside a regexp as punctuation.
    +    }();
    +
    +  // Define regexps here so that the interpreter doesn't have to create an
    +  // object each time the function containing them is called.
    +  // The language spec requires a new object created even if you don't access
    +  // the $1 members.
    +  var pr_amp = /&/g;
    +  var pr_lt = /</g;
    +  var pr_gt = />/g;
    +  var pr_quot = /\"/g;
    +  /** like textToHtml but escapes double quotes to be attribute safe. */
    +  function attribToHtml(str) {
    +    return str.replace(pr_amp, '&amp;')
    +        .replace(pr_lt, '&lt;')
    +        .replace(pr_gt, '&gt;')
    +        .replace(pr_quot, '&quot;');
    +  }
    +
    +  /** escapest html special characters to html. */
    +  function textToHtml(str) {
    +    return str.replace(pr_amp, '&amp;')
    +        .replace(pr_lt, '&lt;')
    +        .replace(pr_gt, '&gt;');
    +  }
    +
    +
    +  var pr_ltEnt = /&lt;/g;
    +  var pr_gtEnt = /&gt;/g;
    +  var pr_aposEnt = /&apos;/g;
    +  var pr_quotEnt = /&quot;/g;
    +  var pr_ampEnt = /&amp;/g;
    +  var pr_nbspEnt = /&nbsp;/g;
    +  /** unescapes html to plain text. */
    +  function htmlToText(html) {
    +    var pos = html.indexOf('&');
    +    if (pos < 0) { return html; }
    +    // Handle numeric entities specially.  We can't use functional substitution
    +    // since that doesn't work in older versions of Safari.
    +    // These should be rare since most browsers convert them to normal chars.
    +    for (--pos; (pos = html.indexOf('&#', pos + 1)) >= 0;) {
    +      var end = html.indexOf(';', pos);
    +      if (end >= 0) {
    +        var num = html.substring(pos + 3, end);
    +        var radix = 10;
    +        if (num && num.charAt(0) === 'x') {
    +          num = num.substring(1);
    +          radix = 16;
    +        }
    +        var codePoint = parseInt(num, radix);
    +        if (!isNaN(codePoint)) {
    +          html = (html.substring(0, pos) + String.fromCharCode(codePoint) +
    +                  html.substring(end + 1));
    +        }
    +      }
    +    }
    +
    +    return html.replace(pr_ltEnt, '<')
    +        .replace(pr_gtEnt, '>')
    +        .replace(pr_aposEnt, "'")
    +        .replace(pr_quotEnt, '"')
    +        .replace(pr_nbspEnt, ' ')
    +        .replace(pr_ampEnt, '&');
    +  }
    +
    +  /** is the given node's innerHTML normally unescaped? */
    +  function isRawContent(node) {
    +    return 'XMP' === node.tagName;
    +  }
    +
    +  var newlineRe = /[\r\n]/g;
    +  /**
    +   * Are newlines and adjacent spaces significant in the given node's innerHTML?
    +   */
    +  function isPreformatted(node, content) {
    +    // PRE means preformatted, and is a very common case, so don't create
    +    // unnecessary computed style objects.
    +    if ('PRE' === node.tagName) { return true; }
    +    if (!newlineRe.test(content)) { return true; }  // Don't care
    +    var whitespace = '';
    +    // For disconnected nodes, IE has no currentStyle.
    +    if (node.currentStyle) {
    +      whitespace = node.currentStyle.whiteSpace;
    +    } else if (window.getComputedStyle) {
    +      // Firefox makes a best guess if node is disconnected whereas Safari
    +      // returns the empty string.
    +      whitespace = window.getComputedStyle(node, null).whiteSpace;
    +    }
    +    return !whitespace || whitespace === 'pre';
    +  }
    +
    +  function normalizedHtml(node, out) {
    +    switch (node.nodeType) {
    +      case 1:  // an element
    +        var name = node.tagName.toLowerCase();
    +        out.push('<', name);
    +        for (var i = 0; i < node.attributes.length; ++i) {
    +          var attr = node.attributes[i];
    +          if (!attr.specified) { continue; }
    +          out.push(' ');
    +          normalizedHtml(attr, out);
    +        }
    +        out.push('>');
    +        for (var child = node.firstChild; child; child = child.nextSibling) {
    +          normalizedHtml(child, out);
    +        }
    +        if (node.firstChild || !/^(?:br|link|img)$/.test(name)) {
    +          out.push('<\/', name, '>');
    +        }
    +        break;
    +      case 2: // an attribute
    +        out.push(node.name.toLowerCase(), '="', attribToHtml(node.value), '"');
    +        break;
    +      case 3: case 4: // text
    +        out.push(textToHtml(node.nodeValue));
    +        break;
    +    }
    +  }
    +
    +  /**
    +   * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
    +   * matches the union o the sets o strings matched d by the input RegExp.
    +   * Since it matches globally, if the input strings have a start-of-input
    +   * anchor (/^.../), it is ignored for the purposes of unioning.
    +   * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
    +   * @return {RegExp} a global regex.
    +   */
    +  function combinePrefixPatterns(regexs) {
    +    var capturedGroupIndex = 0;
    +
    +    var needToFoldCase = false;
    +    var ignoreCase = false;
    +    for (var i = 0, n = regexs.length; i < n; ++i) {
    +      var regex = regexs[i];
    +      if (regex.ignoreCase) {
    +        ignoreCase = true;
    +      } else if (/[a-z]/i.test(regex.source.replace(
    +                     /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
    +        needToFoldCase = true;
    +        ignoreCase = false;
    +        break;
    +      }
    +    }
    +
    +    function decodeEscape(charsetPart) {
    +      if (charsetPart.charAt(0) !== '\\') { return charsetPart.charCodeAt(0); }
    +      switch (charsetPart.charAt(1)) {
    +        case 'b': return 8;
    +        case 't': return 9;
    +        case 'n': return 0xa;
    +        case 'v': return 0xb;
    +        case 'f': return 0xc;
    +        case 'r': return 0xd;
    +        case 'u': case 'x':
    +          return parseInt(charsetPart.substring(2), 16)
    +              || charsetPart.charCodeAt(1);
    +        case '0': case '1': case '2': case '3': case '4':
    +        case '5': case '6': case '7':
    +          return parseInt(charsetPart.substring(1), 8);
    +        default: return charsetPart.charCodeAt(1);
    +      }
    +    }
    +
    +    function encodeEscape(charCode) {
    +      if (charCode < 0x20) {
    +        return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
    +      }
    +      var ch = String.fromCharCode(charCode);
    +      if (ch === '\\' || ch === '-' || ch === '[' || ch === ']') {
    +        ch = '\\' + ch;
    +      }
    +      return ch;
    +    }
    +
    +    function caseFoldCharset(charSet) {
    +      var charsetParts = charSet.substring(1, charSet.length - 1).match(
    +          new RegExp(
    +              '\\\\u[0-9A-Fa-f]{4}'
    +              + '|\\\\x[0-9A-Fa-f]{2}'
    +              + '|\\\\[0-3][0-7]{0,2}'
    +              + '|\\\\[0-7]{1,2}'
    +              + '|\\\\[\\s\\S]'
    +              + '|-'
    +              + '|[^-\\\\]',
    +              'g'));
    +      var groups = [];
    +      var ranges = [];
    +      var inverse = charsetParts[0] === '^';
    +      for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
    +        var p = charsetParts[i];
    +        switch (p) {
    +          case '\\B': case '\\b':
    +          case '\\D': case '\\d':
    +          case '\\S': case '\\s':
    +          case '\\W': case '\\w':
    +            groups.push(p);
    +            continue;
    +        }
    +        var start = decodeEscape(p);
    +        var end;
    +        if (i + 2 < n && '-' === charsetParts[i + 1]) {
    +          end = decodeEscape(charsetParts[i + 2]);
    +          i += 2;
    +        } else {
    +          end = start;
    +        }
    +        ranges.push([start, end]);
    +        // If the range might intersect letters, then expand it.
    +        if (!(end < 65 || start > 122)) {
    +          if (!(end < 65 || start > 90)) {
    +            ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
    +          }
    +          if (!(end < 97 || start > 122)) {
    +            ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
    +          }
    +        }
    +      }
    +
    +      // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
    +      // -> [[1, 12], [14, 14], [16, 17]]
    +      ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
    +      var consolidatedRanges = [];
    +      var lastRange = [NaN, NaN];
    +      for (var i = 0; i < ranges.length; ++i) {
    +        var range = ranges[i];
    +        if (range[0] <= lastRange[1] + 1) {
    +          lastRange[1] = Math.max(lastRange[1], range[1]);
    +        } else {
    +          consolidatedRanges.push(lastRange = range);
    +        }
    +      }
    +
    +      var out = ['['];
    +      if (inverse) { out.push('^'); }
    +      out.push.apply(out, groups);
    +      for (var i = 0; i < consolidatedRanges.length; ++i) {
    +        var range = consolidatedRanges[i];
    +        out.push(encodeEscape(range[0]));
    +        if (range[1] > range[0]) {
    +          if (range[1] + 1 > range[0]) { out.push('-'); }
    +          out.push(encodeEscape(range[1]));
    +        }
    +      }
    +      out.push(']');
    +      return out.join('');
    +    }
    +
    +    function allowAnywhereFoldCaseAndRenumberGroups(regex) {
    +      // Split into character sets, escape sequences, punctuation strings
    +      // like ('(', '(?:', ')', '^'), and runs of characters that do not
    +      // include any of the above.
    +      var parts = regex.source.match(
    +          new RegExp(
    +              '(?:'
    +              + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
    +              + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
    +              + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
    +              + '|\\\\[0-9]+'  // a back-reference or octal escape
    +              + '|\\\\[^ux0-9]'  // other escape sequence
    +              + '|\\(\\?[:!=]'  // start of a non-capturing group
    +              + '|[\\(\\)\\^]'  // start/emd of a group, or line start
    +              + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
    +              + ')',
    +              'g'));
    +      var n = parts.length;
    +
    +      // Maps captured group numbers to the number they will occupy in
    +      // the output or to -1 if that has not been determined, or to
    +      // undefined if they need not be capturing in the output.
    +      var capturedGroups = [];
    +
    +      // Walk over and identify back references to build the capturedGroups
    +      // mapping.
    +      for (var i = 0, groupIndex = 0; i < n; ++i) {
    +        var p = parts[i];
    +        if (p === '(') {
    +          // groups are 1-indexed, so max group index is count of '('
    +          ++groupIndex;
    +        } else if ('\\' === p.charAt(0)) {
    +          var decimalValue = +p.substring(1);
    +          if (decimalValue && decimalValue <= groupIndex) {
    +            capturedGroups[decimalValue] = -1;
    +          }
    +        }
    +      }
    +
    +      // Renumber groups and reduce capturing groups to non-capturing groups
    +      // where possible.
    +      for (var i = 1; i < capturedGroups.length; ++i) {
    +        if (-1 === capturedGroups[i]) {
    +          capturedGroups[i] = ++capturedGroupIndex;
    +        }
    +      }
    +      for (var i = 0, groupIndex = 0; i < n; ++i) {
    +        var p = parts[i];
    +        if (p === '(') {
    +          ++groupIndex;
    +          if (capturedGroups[groupIndex] === undefined) {
    +            parts[i] = '(?:';
    +          }
    +        } else if ('\\' === p.charAt(0)) {
    +          var decimalValue = +p.substring(1);
    +          if (decimalValue && decimalValue <= groupIndex) {
    +            parts[i] = '\\' + capturedGroups[groupIndex];
    +          }
    +        }
    +      }
    +
    +      // Remove any prefix anchors so that the output will match anywhere.
    +      // ^^ really does mean an anchored match though.
    +      for (var i = 0, groupIndex = 0; i < n; ++i) {
    +        if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
    +      }
    +
    +      // Expand letters to groupts to handle mixing of case-sensitive and
    +      // case-insensitive patterns if necessary.
    +      if (regex.ignoreCase && needToFoldCase) {
    +        for (var i = 0; i < n; ++i) {
    +          var p = parts[i];
    +          var ch0 = p.charAt(0);
    +          if (p.length >= 2 && ch0 === '[') {
    +            parts[i] = caseFoldCharset(p);
    +          } else if (ch0 !== '\\') {
    +            // TODO: handle letters in numeric escapes.
    +            parts[i] = p.replace(
    +                /[a-zA-Z]/g,
    +                function (ch) {
    +                  var cc = ch.charCodeAt(0);
    +                  return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
    +                });
    +          }
    +        }
    +      }
    +
    +      return parts.join('');
    +    }
    +
    +    var rewritten = [];
    +    for (var i = 0, n = regexs.length; i < n; ++i) {
    +      var regex = regexs[i];
    +      if (regex.global || regex.multiline) { throw new Error('' + regex); }
    +      rewritten.push(
    +          '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
    +    }
    +
    +    return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
    +  }
    +
    +  var PR_innerHtmlWorks = null;
    +  function getInnerHtml(node) {
    +    // inner html is hopelessly broken in Safari 2.0.4 when the content is
    +    // an html description of well formed XML and the containing tag is a PRE
    +    // tag, so we detect that case and emulate innerHTML.
    +    if (null === PR_innerHtmlWorks) {
    +      var testNode = document.createElement('PRE');
    +      testNode.appendChild(
    +          document.createTextNode('<!DOCTYPE foo PUBLIC "foo bar">\n<foo />'));
    +      PR_innerHtmlWorks = !/</.test(testNode.innerHTML);
    +    }
    +
    +    if (PR_innerHtmlWorks) {
    +      var content = node.innerHTML;
    +      // XMP tags contain unescaped entities so require special handling.
    +      if (isRawContent(node)) {
    +        content = textToHtml(content);
    +      } else if (!isPreformatted(node, content)) {
    +        content = content.replace(/(<br\s*\/?>)[\r\n]+/g, '$1')
    +            .replace(/(?:[\r\n]+[ \t]*)+/g, ' ');
    +      }
    +      return content;
    +    }
    +
    +    var out = [];
    +    for (var child = node.firstChild; child; child = child.nextSibling) {
    +      normalizedHtml(child, out);
    +    }
    +    return out.join('');
    +  }
    +
    +  /** returns a function that expand tabs to spaces.  This function can be fed
    +    * successive chunks of text, and will maintain its own internal state to
    +    * keep track of how tabs are expanded.
    +    * @return {function (string) : string} a function that takes
    +    *   plain text and return the text with tabs expanded.
    +    * @private
    +    */
    +  function makeTabExpander(tabWidth) {
    +    var SPACES = '                ';
    +    var charInLine = 0;
    +
    +    return function (plainText) {
    +      // walk over each character looking for tabs and newlines.
    +      // On tabs, expand them.  On newlines, reset charInLine.
    +      // Otherwise increment charInLine
    +      var out = null;
    +      var pos = 0;
    +      for (var i = 0, n = plainText.length; i < n; ++i) {
    +        var ch = plainText.charAt(i);
    +
    +        switch (ch) {
    +          case '\t':
    +            if (!out) { out = []; }
    +            out.push(plainText.substring(pos, i));
    +            // calculate how much space we need in front of this part
    +            // nSpaces is the amount of padding -- the number of spaces needed
    +            // to move us to the next column, where columns occur at factors of
    +            // tabWidth.
    +            var nSpaces = tabWidth - (charInLine % tabWidth);
    +            charInLine += nSpaces;
    +            for (; nSpaces >= 0; nSpaces -= SPACES.length) {
    +              out.push(SPACES.substring(0, nSpaces));
    +            }
    +            pos = i + 1;
    +            break;
    +          case '\n':
    +            charInLine = 0;
    +            break;
    +          default:
    +            ++charInLine;
    +        }
    +      }
    +      if (!out) { return plainText; }
    +      out.push(plainText.substring(pos));
    +      return out.join('');
    +    };
    +  }
    +
    +  var pr_chunkPattern = new RegExp(
    +      '[^<]+'  // A run of characters other than '<'
    +      + '|<\!--[\\s\\S]*?--\>'  // an HTML comment
    +      + '|<!\\[CDATA\\[[\\s\\S]*?\\]\\]>'  // a CDATA section
    +      // a probable tag that should not be highlighted
    +      + '|<\/?[a-zA-Z](?:[^>\"\']|\'[^\']*\'|\"[^\"]*\")*>'
    +      + '|<',  // A '<' that does not begin a larger chunk
    +      'g');
    +  var pr_commentPrefix = /^<\!--/;
    +  var pr_cdataPrefix = /^<!\[CDATA\[/;
    +  var pr_brPrefix = /^<br\b/i;
    +  var pr_tagNameRe = /^<(\/?)([a-zA-Z][a-zA-Z0-9]*)/;
    +
    +  /** split markup into chunks of html tags (style null) and
    +    * plain text (style {@link #PR_PLAIN}), converting tags which are
    +    * significant for tokenization (<br>) into their textual equivalent.
    +    *
    +    * @param {string} s html where whitespace is considered significant.
    +    * @return {Object} source code and extracted tags.
    +    * @private
    +    */
    +  function extractTags(s) {
    +    // since the pattern has the 'g' modifier and defines no capturing groups,
    +    // this will return a list of all chunks which we then classify and wrap as
    +    // PR_Tokens
    +    var matches = s.match(pr_chunkPattern);
    +    var sourceBuf = [];
    +    var sourceBufLen = 0;
    +    var extractedTags = [];
    +    if (matches) {
    +      for (var i = 0, n = matches.length; i < n; ++i) {
    +        var match = matches[i];
    +        if (match.length > 1 && match.charAt(0) === '<') {
    +          if (pr_commentPrefix.test(match)) { continue; }
    +          if (pr_cdataPrefix.test(match)) {
    +            // strip CDATA prefix and suffix.  Don't unescape since it's CDATA
    +            sourceBuf.push(match.substring(9, match.length - 3));
    +            sourceBufLen += match.length - 12;
    +          } else if (pr_brPrefix.test(match)) {
    +            // <br> tags are lexically significant so convert them to text.
    +            // This is undone later.
    +            sourceBuf.push('\n');
    +            ++sourceBufLen;
    +          } else {
    +            if (match.indexOf(PR_NOCODE) >= 0 && isNoCodeTag(match)) {
    +              // A <span class="nocode"> will start a section that should be
    +              // ignored.  Continue walking the list until we see a matching end
    +              // tag.
    +              var name = match.match(pr_tagNameRe)[2];
    +              var depth = 1;
    +              var j;
    +              end_tag_loop:
    +              for (j = i + 1; j < n; ++j) {
    +                var name2 = matches[j].match(pr_tagNameRe);
    +                if (name2 && name2[2] === name) {
    +                  if (name2[1] === '/') {
    +                    if (--depth === 0) { break end_tag_loop; }
    +                  } else {
    +                    ++depth;
    +                  }
    +                }
    +              }
    +              if (j < n) {
    +                extractedTags.push(
    +                    sourceBufLen, matches.slice(i, j + 1).join(''));
    +                i = j;
    +              } else {  // Ignore unclosed sections.
    +                extractedTags.push(sourceBufLen, match);
    +              }
    +            } else {
    +              extractedTags.push(sourceBufLen, match);
    +            }
    +          }
    +        } else {
    +          var literalText = htmlToText(match);
    +          sourceBuf.push(literalText);
    +          sourceBufLen += literalText.length;
    +        }
    +      }
    +    }
    +    return { source: sourceBuf.join(''), tags: extractedTags };
    +  }
    +
    +  /** True if the given tag contains a class attribute with the nocode class. */
    +  function isNoCodeTag(tag) {
    +    return !!tag
    +        // First canonicalize the representation of attributes
    +        .replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,
    +                 ' $1="$2$3$4"')
    +        // Then look for the attribute we want.
    +        .match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/);
    +  }
    +
    +  /**
    +   * Apply the given language handler to sourceCode and add the resulting
    +   * decorations to out.
    +   * @param {number} basePos the index of sourceCode within the chunk of source
    +   *    whose decorations are already present on out.
    +   */
    +  function appendDecorations(basePos, sourceCode, langHandler, out) {
    +    if (!sourceCode) { return; }
    +    var job = {
    +      source: sourceCode,
    +      basePos: basePos
    +    };
    +    langHandler(job);
    +    out.push.apply(out, job.decorations);
    +  }
    +
    +  /** Given triples of [style, pattern, context] returns a lexing function,
    +    * The lexing function interprets the patterns to find token boundaries and
    +    * returns a decoration list of the form
    +    * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
    +    * where index_n is an index into the sourceCode, and style_n is a style
    +    * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
    +    * all characters in sourceCode[index_n-1:index_n].
    +    *
    +    * The stylePatterns is a list whose elements have the form
    +    * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
    +    *
    +    * Style is a style constant like PR_PLAIN, or can be a string of the
    +    * form 'lang-FOO', where FOO is a language extension describing the
    +    * language of the portion of the token in $1 after pattern executes.
    +    * E.g., if style is 'lang-lisp', and group 1 contains the text
    +    * '(hello (world))', then that portion of the token will be passed to the
    +    * registered lisp handler for formatting.
    +    * The text before and after group 1 will be restyled using this decorator
    +    * so decorators should take care that this doesn't result in infinite
    +    * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
    +    * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
    +    * '<script>foo()<\/script>', which would cause the current decorator to
    +    * be called with '<script>' which would not match the same rule since
    +    * group 1 must not be empty, so it would be instead styled as PR_TAG by
    +    * the generic tag rule.  The handler registered for the 'js' extension would
    +    * then be called with 'foo()', and finally, the current decorator would
    +    * be called with '<\/script>' which would not match the original rule and
    +    * so the generic tag rule would identify it as a tag.
    +    *
    +    * Pattern must only match prefixes, and if it matches a prefix, then that
    +    * match is considered a token with the same style.
    +    *
    +    * Context is applied to the last non-whitespace, non-comment token
    +    * recognized.
    +    *
    +    * Shortcut is an optional string of characters, any of which, if the first
    +    * character, gurantee that this pattern and only this pattern matches.
    +    *
    +    * @param {Array} shortcutStylePatterns patterns that always start with
    +    *   a known character.  Must have a shortcut string.
    +    * @param {Array} fallthroughStylePatterns patterns that will be tried in
    +    *   order if the shortcut ones fail.  May have shortcuts.
    +    *
    +    * @return {function (Object)} a
    +    *   function that takes source code and returns a list of decorations.
    +    */
    +  function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
    +    var shortcuts = {};
    +    var tokenizer;
    +    (function () {
    +      var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
    +      var allRegexs = [];
    +      var regexKeys = {};
    +      for (var i = 0, n = allPatterns.length; i < n; ++i) {
    +        var patternParts = allPatterns[i];
    +        var shortcutChars = patternParts[3];
    +        if (shortcutChars) {
    +          for (var c = shortcutChars.length; --c >= 0;) {
    +            shortcuts[shortcutChars.charAt(c)] = patternParts;
    +          }
    +        }
    +        var regex = patternParts[1];
    +        var k = '' + regex;
    +        if (!regexKeys.hasOwnProperty(k)) {
    +          allRegexs.push(regex);
    +          regexKeys[k] = null;
    +        }
    +      }
    +      allRegexs.push(/[\0-\uffff]/);
    +      tokenizer = combinePrefixPatterns(allRegexs);
    +    })();
    +
    +    var nPatterns = fallthroughStylePatterns.length;
    +    var notWs = /\S/;
    +
    +    /**
    +     * Lexes job.source and produces an output array job.decorations of style
    +     * classes preceded by the position at which they start in job.source in
    +     * order.
    +     *
    +     * @param {Object} job an object like {@code
    +     *    source: {string} sourceText plain text,
    +     *    basePos: {int} position of job.source in the larger chunk of
    +     *        sourceCode.
    +     * }
    +     */
    +    var decorate = function (job) {
    +      var sourceCode = job.source, basePos = job.basePos;
    +      /** Even entries are positions in source in ascending order.  Odd enties
    +        * are style markers (e.g., PR_COMMENT) that run from that position until
    +        * the end.
    +        * @type {Array.<number|string>}
    +        */
    +      var decorations = [basePos, PR_PLAIN];
    +      var pos = 0;  // index into sourceCode
    +      var tokens = sourceCode.match(tokenizer) || [];
    +      var styleCache = {};
    +
    +      for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
    +        var token = tokens[ti];
    +        var style = styleCache[token];
    +        var match = void 0;
    +
    +        var isEmbedded;
    +        if (typeof style === 'string') {
    +          isEmbedded = false;
    +        } else {
    +          var patternParts = shortcuts[token.charAt(0)];
    +          if (patternParts) {
    +            match = token.match(patternParts[1]);
    +            style = patternParts[0];
    +          } else {
    +            for (var i = 0; i < nPatterns; ++i) {
    +              patternParts = fallthroughStylePatterns[i];
    +              match = token.match(patternParts[1]);
    +              if (match) {
    +                style = patternParts[0];
    +                break;
    +              }
    +            }
    +
    +            if (!match) {  // make sure that we make progress
    +              style = PR_PLAIN;
    +            }
    +          }
    +
    +          isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
    +          if (isEmbedded && !(match && typeof match[1] === 'string')) {
    +            isEmbedded = false;
    +            style = PR_SOURCE;
    +          }
    +
    +          if (!isEmbedded) { styleCache[token] = style; }
    +        }
    +
    +        var tokenStart = pos;
    +        pos += token.length;
    +
    +        if (!isEmbedded) {
    +          decorations.push(basePos + tokenStart, style);
    +        } else {  // Treat group 1 as an embedded block of source code.
    +          var embeddedSource = match[1];
    +          var embeddedSourceStart = token.indexOf(embeddedSource);
    +          var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
    +          if (match[2]) {
    +            // If embeddedSource can be blank, then it would match at the
    +            // beginning which would cause us to infinitely recurse on the
    +            // entire token, so we catch the right context in match[2].
    +            embeddedSourceEnd = token.length - match[2].length;
    +            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
    +          }
    +          var lang = style.substring(5);
    +          // Decorate the left of the embedded source
    +          appendDecorations(
    +              basePos + tokenStart,
    +              token.substring(0, embeddedSourceStart),
    +              decorate, decorations);
    +          // Decorate the embedded source
    +          appendDecorations(
    +              basePos + tokenStart + embeddedSourceStart,
    +              embeddedSource,
    +              langHandlerForExtension(lang, embeddedSource),
    +              decorations);
    +          // Decorate the right of the embedded section
    +          appendDecorations(
    +              basePos + tokenStart + embeddedSourceEnd,
    +              token.substring(embeddedSourceEnd),
    +              decorate, decorations);
    +        }
    +      }
    +      job.decorations = decorations;
    +    };
    +    return decorate;
    +  }
    +
    +  /** returns a function that produces a list of decorations from source text.
    +    *
    +    * This code treats ", ', and ` as string delimiters, and \ as a string
    +    * escape.  It does not recognize perl's qq() style strings.
    +    * It has no special handling for double delimiter escapes as in basic, or
    +    * the tripled delimiters used in python, but should work on those regardless
    +    * although in those cases a single string literal may be broken up into
    +    * multiple adjacent string literals.
    +    *
    +    * It recognizes C, C++, and shell style comments.
    +    *
    +    * @param {Object} options a set of optional parameters.
    +    * @return {function (Object)} a function that examines the source code
    +    *     in the input job and builds the decoration list.
    +    */
    +  function sourceDecorator(options) {
    +    var shortcutStylePatterns = [], fallthroughStylePatterns = [];
    +    if (options['tripleQuotedStrings']) {
    +      // '''multi-line-string''', 'single-line-string', and double-quoted
    +      shortcutStylePatterns.push(
    +          [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
    +           null, '\'"']);
    +    } else if (options['multiLineStrings']) {
    +      // 'multi-line-string', "multi-line-string"
    +      shortcutStylePatterns.push(
    +          [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
    +           null, '\'"`']);
    +    } else {
    +      // 'single-line-string', "single-line-string"
    +      shortcutStylePatterns.push(
    +          [PR_STRING,
    +           /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
    +           null, '"\'']);
    +    }
    +    if (options['verbatimStrings']) {
    +      // verbatim-string-literal production from the C# grammar.  See issue 93.
    +      fallthroughStylePatterns.push(
    +          [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
    +    }
    +    if (options['hashComments']) {
    +      if (options['cStyleComments']) {
    +        // Stop C preprocessor declarations at an unclosed open comment
    +        shortcutStylePatterns.push(
    +            [PR_COMMENT, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,
    +             null, '#']);
    +        fallthroughStylePatterns.push(
    +            [PR_STRING,
    +             /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,
    +             null]);
    +      } else {
    +        shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
    +      }
    +    }
    +    if (options['cStyleComments']) {
    +      fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
    +      fallthroughStylePatterns.push(
    +          [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
    +    }
    +    if (options['regexLiterals']) {
    +      var REGEX_LITERAL = (
    +          // A regular expression literal starts with a slash that is
    +          // not followed by * or / so that it is not confused with
    +          // comments.
    +          '/(?=[^/*])'
    +          // and then contains any number of raw characters,
    +          + '(?:[^/\\x5B\\x5C]'
    +          // escape sequences (\x5C),
    +          +    '|\\x5C[\\s\\S]'
    +          // or non-nesting character sets (\x5B\x5D);
    +          +    '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+'
    +          // finally closed by a /.
    +          + '/');
    +      fallthroughStylePatterns.push(
    +          ['lang-regex',
    +           new RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
    +           ]);
    +    }
    +
    +    var keywords = options['keywords'].replace(/^\s+|\s+$/g, '');
    +    if (keywords.length) {
    +      fallthroughStylePatterns.push(
    +          [PR_KEYWORD,
    +           new RegExp('^(?:' + keywords.replace(/\s+/g, '|') + ')\\b'), null]);
    +    }
    +
    +    shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
    +    fallthroughStylePatterns.push(
    +        // TODO(mikesamuel): recognize non-latin letters and numerals in idents
    +        [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
    +        [PR_TYPE,        /^@?[A-Z]+[a-z][A-Za-z_$@0-9]*/, null],
    +        [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
    +        [PR_LITERAL,
    +         new RegExp(
    +             '^(?:'
    +             // A hex number
    +             + '0x[a-f0-9]+'
    +             // or an octal or decimal number,
    +             + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
    +             // possibly in scientific notation
    +             + '(?:e[+\\-]?\\d+)?'
    +             + ')'
    +             // with an optional modifier like UL for unsigned long
    +             + '[a-z]*', 'i'),
    +         null, '0123456789'],
    +        [PR_PUNCTUATION, /^.[^\s\w\.$@\'\"\`\/\#]*/, null]);
    +
    +    return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
    +  }
    +
    +  var decorateSource = sourceDecorator({
    +        'keywords': ALL_KEYWORDS,
    +        'hashComments': true,
    +        'cStyleComments': true,
    +        'multiLineStrings': true,
    +        'regexLiterals': true
    +      });
    +
    +  /** Breaks {@code job.source} around style boundaries in
    +    * {@code job.decorations} while re-interleaving {@code job.extractedTags},
    +    * and leaves the result in {@code job.prettyPrintedHtml}.
    +    * @param {Object} job like {
    +    *    source: {string} source as plain text,
    +    *    extractedTags: {Array.<number|string>} extractedTags chunks of raw
    +    *                   html preceded by their position in {@code job.source}
    +    *                   in order
    +    *    decorations: {Array.<number|string} an array of style classes preceded
    +    *                 by the position at which they start in job.source in order
    +    * }
    +    * @private
    +    */
    +  function recombineTagsAndDecorations(job) {
    +    var sourceText = job.source;
    +    var extractedTags = job.extractedTags;
    +    var decorations = job.decorations;
    +
    +    var html = [];
    +    // index past the last char in sourceText written to html
    +    var outputIdx = 0;
    +
    +    var openDecoration = null;
    +    var currentDecoration = null;
    +    var tagPos = 0;  // index into extractedTags
    +    var decPos = 0;  // index into decorations
    +    var tabExpander = makeTabExpander(window['PR_TAB_WIDTH']);
    +
    +    var adjacentSpaceRe = /([\r\n ]) /g;
    +    var startOrSpaceRe = /(^| ) /gm;
    +    var newlineRe = /\r\n?|\n/g;
    +    var trailingSpaceRe = /[ \r\n]$/;
    +    var lastWasSpace = true;  // the last text chunk emitted ended with a space.
    +
    +    // A helper function that is responsible for opening sections of decoration
    +    // and outputing properly escaped chunks of source
    +    function emitTextUpTo(sourceIdx) {
    +      if (sourceIdx > outputIdx) {
    +        if (openDecoration && openDecoration !== currentDecoration) {
    +          // Close the current decoration
    +          html.push('</span>');
    +          openDecoration = null;
    +        }
    +        if (!openDecoration && currentDecoration) {
    +          openDecoration = currentDecoration;
    +          html.push('<span class="', openDecoration, '">');
    +        }
    +        // This interacts badly with some wikis which introduces paragraph tags
    +        // into pre blocks for some strange reason.
    +        // It's necessary for IE though which seems to lose the preformattedness
    +        // of <pre> tags when their innerHTML is assigned.
    +        // http://stud3.tuwien.ac.at/~e0226430/innerHtmlQuirk.html
    +        // and it serves to undo the conversion of <br>s to newlines done in
    +        // chunkify.
    +        var htmlChunk = textToHtml(
    +            tabExpander(sourceText.substring(outputIdx, sourceIdx)))
    +            .replace(lastWasSpace
    +                     ? startOrSpaceRe
    +                     : adjacentSpaceRe, '$1&nbsp;');
    +        // Keep track of whether we need to escape space at the beginning of the
    +        // next chunk.
    +        lastWasSpace = trailingSpaceRe.test(htmlChunk);
    +        // IE collapses multiple adjacient <br>s into 1 line break.
    +        // Prefix every <br> with '&nbsp;' can prevent such IE's behavior.
    +        var lineBreakHtml = window['_pr_isIE6']() ? '&nbsp;<br />' : '<br />';
    +        html.push(htmlChunk.replace(newlineRe, lineBreakHtml));
    +        outputIdx = sourceIdx;
    +      }
    +    }
    +
    +    while (true) {
    +      // Determine if we're going to consume a tag this time around.  Otherwise
    +      // we consume a decoration or exit.
    +      var outputTag;
    +      if (tagPos < extractedTags.length) {
    +        if (decPos < decorations.length) {
    +          // Pick one giving preference to extractedTags since we shouldn't open
    +          // a new style that we're going to have to immediately close in order
    +          // to output a tag.
    +          outputTag = extractedTags[tagPos] <= decorations[decPos];
    +        } else {
    +          outputTag = true;
    +        }
    +      } else {
    +        outputTag = false;
    +      }
    +      // Consume either a decoration or a tag or exit.
    +      if (outputTag) {
    +        emitTextUpTo(extractedTags[tagPos]);
    +        if (openDecoration) {
    +          // Close the current decoration
    +          html.push('</span>');
    +          openDecoration = null;
    +        }
    +        html.push(extractedTags[tagPos + 1]);
    +        tagPos += 2;
    +      } else if (decPos < decorations.length) {
    +        emitTextUpTo(decorations[decPos]);
    +        currentDecoration = decorations[decPos + 1];
    +        decPos += 2;
    +      } else {
    +        break;
    +      }
    +    }
    +    emitTextUpTo(sourceText.length);
    +    if (openDecoration) {
    +      html.push('</span>');
    +    }
    +    job.prettyPrintedHtml = html.join('');
    +  }
    +
    +  /** Maps language-specific file extensions to handlers. */
    +  var langHandlerRegistry = {};
    +  /** Register a language handler for the given file extensions.
    +    * @param {function (Object)} handler a function from source code to a list
    +    *      of decorations.  Takes a single argument job which describes the
    +    *      state of the computation.   The single parameter has the form
    +    *      {@code {
    +    *        source: {string} as plain text.
    +    *        decorations: {Array.<number|string>} an array of style classes
    +    *                     preceded by the position at which they start in
    +    *                     job.source in order.
    +    *                     The language handler should assigned this field.
    +    *        basePos: {int} the position of source in the larger source chunk.
    +    *                 All positions in the output decorations array are relative
    +    *                 to the larger source chunk.
    +    *      } }
    +    * @param {Array.<string>} fileExtensions
    +    */
    +  function registerLangHandler(handler, fileExtensions) {
    +    for (var i = fileExtensions.length; --i >= 0;) {
    +      var ext = fileExtensions[i];
    +      if (!langHandlerRegistry.hasOwnProperty(ext)) {
    +        langHandlerRegistry[ext] = handler;
    +      } else if ('console' in window) {
    +        console.warn('cannot override language handler %s', ext);
    +      }
    +    }
    +  }
    +  function langHandlerForExtension(extension, source) {
    +    if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
    +      // Treat it as markup if the first non whitespace character is a < and
    +      // the last non-whitespace character is a >.
    +      extension = /^\s*</.test(source)
    +          ? 'default-markup'
    +          : 'default-code';
    +    }
    +    return langHandlerRegistry[extension];
    +  }
    +  registerLangHandler(decorateSource, ['default-code']);
    +  registerLangHandler(
    +      createSimpleLexer(
    +          [],
    +          [
    +           [PR_PLAIN,       /^[^<?]+/],
    +           [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
    +           [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
    +           // Unescaped content in an unknown language
    +           ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
    +           ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
    +           [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
    +           ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
    +           // Unescaped content in javascript.  (Or possibly vbscript).
    +           ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
    +           // Contains unescaped stylesheet content
    +           ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
    +           ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
    +          ]),
    +      ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
    +  registerLangHandler(
    +      createSimpleLexer(
    +          [
    +           [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
    +           [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
    +           ],
    +          [
    +           [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
    +           [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
    +           ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
    +           [PR_PUNCTUATION,  /^[=<>\/]+/],
    +           ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
    +           ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
    +           ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
    +           ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
    +           ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
    +           ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
    +           ]),
    +      ['in.tag']);
    +  registerLangHandler(
    +      createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': CPP_KEYWORDS,
    +          'hashComments': true,
    +          'cStyleComments': true
    +        }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': 'null true false'
    +        }), ['json']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': CSHARP_KEYWORDS,
    +          'hashComments': true,
    +          'cStyleComments': true,
    +          'verbatimStrings': true
    +        }), ['cs']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': JAVA_KEYWORDS,
    +          'cStyleComments': true
    +        }), ['java']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': SH_KEYWORDS,
    +          'hashComments': true,
    +          'multiLineStrings': true
    +        }), ['bsh', 'csh', 'sh']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': PYTHON_KEYWORDS,
    +          'hashComments': true,
    +          'multiLineStrings': true,
    +          'tripleQuotedStrings': true
    +        }), ['cv', 'py']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': PERL_KEYWORDS,
    +          'hashComments': true,
    +          'multiLineStrings': true,
    +          'regexLiterals': true
    +        }), ['perl', 'pl', 'pm']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': RUBY_KEYWORDS,
    +          'hashComments': true,
    +          'multiLineStrings': true,
    +          'regexLiterals': true
    +        }), ['rb']);
    +  registerLangHandler(sourceDecorator({
    +          'keywords': JSCRIPT_KEYWORDS,
    +          'cStyleComments': true,
    +          'regexLiterals': true
    +        }), ['js']);
    +  registerLangHandler(
    +      createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
    +
    +  function applyDecorator(job) {
    +    var sourceCodeHtml = job.sourceCodeHtml;
    +    var opt_langExtension = job.langExtension;
    +
    +    // Prepopulate output in case processing fails with an exception.
    +    job.prettyPrintedHtml = sourceCodeHtml;
    +
    +    try {
    +      // Extract tags, and convert the source code to plain text.
    +      var sourceAndExtractedTags = extractTags(sourceCodeHtml);
    +      /** Plain text. @type {string} */
    +      var source = sourceAndExtractedTags.source;
    +      job.source = source;
    +      job.basePos = 0;
    +
    +      /** Even entries are positions in source in ascending order.  Odd entries
    +        * are tags that were extracted at that position.
    +        * @type {Array.<number|string>}
    +        */
    +      job.extractedTags = sourceAndExtractedTags.tags;
    +
    +      // Apply the appropriate language handler
    +      langHandlerForExtension(opt_langExtension, source)(job);
    +      // Integrate the decorations and tags back into the source code to produce
    +      // a decorated html string which is left in job.prettyPrintedHtml.
    +      recombineTagsAndDecorations(job);
    +    } catch (e) {
    +      if ('console' in window) {
    +        console.log(e);
    +        console.trace();
    +      }
    +    }
    +  }
    +
    +  function prettyPrintOne(sourceCodeHtml, opt_langExtension) {
    +    var job = {
    +      sourceCodeHtml: sourceCodeHtml,
    +      langExtension: opt_langExtension
    +    };
    +    applyDecorator(job);
    +    return job.prettyPrintedHtml;
    +  }
    +
    +  function prettyPrint(opt_whenDone) {
    +    var isIE678 = window['_pr_isIE6']();
    +    var ieNewline = isIE678 === 6 ? '\r\n' : '\r';
    +    // See bug 71 and http://stackoverflow.com/questions/136443/why-doesnt-ie7-
    +
    +    // fetch a list of nodes to rewrite
    +    var codeSegments = [
    +        document.getElementsByTagName('pre'),
    +        document.getElementsByTagName('code'),
    +        document.getElementsByTagName('td'),  /* ND Change: Add tables to support prototypes. */
    +        document.getElementsByTagName('xmp') ];
    +    var elements = [];
    +    for (var i = 0; i < codeSegments.length; ++i) {
    +      for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
    +        elements.push(codeSegments[i][j]);
    +      }
    +    }
    +    codeSegments = null;
    +
    +    var clock = Date;
    +    if (!clock['now']) {
    +      clock = { 'now': function () { return (new Date).getTime(); } };
    +    }
    +
    +    // The loop is broken into a series of continuations to make sure that we
    +    // don't make the browser unresponsive when rewriting a large page.
    +    var k = 0;
    +    var prettyPrintingJob;
    +
    +    function doWork() {
    +      var endTime = (window['PR_SHOULD_USE_CONTINUATION'] ?
    +                     clock.now() + 250 /* ms */ :
    +                     Infinity);
    +      for (; k < elements.length && clock.now() < endTime; k++) {
    +        var cs = elements[k];
    +        if (cs.className && cs.className.indexOf('prettyprint') >= 0) {
    +          // If the classes includes a language extensions, use it.
    +          // Language extensions can be specified like
    +          //     <pre class="prettyprint lang-cpp">
    +          // the language extension "cpp" is used to find a language handler as
    +          // passed to PR_registerLangHandler.
    +          var langExtension = cs.className.match(/\blang-(\w+)\b/);
    +          if (langExtension) { langExtension = langExtension[1]; }
    +
    +          // make sure this is not nested in an already prettified element
    +          var nested = false;
    +          for (var p = cs.parentNode; p; p = p.parentNode) {
    +            if ((p.tagName === 'pre' || p.tagName === 'code' ||
    +                 p.tagName === 'xmp' || p.tagName === 'td') &&  /* ND Change: Add tables to support prototypes */
    +                p.className && p.className.indexOf('prettyprint') >= 0) {
    +              nested = true;
    +              break;
    +            }
    +          }
    +          if (!nested) {
    +            // fetch the content as a snippet of properly escaped HTML.
    +            // Firefox adds newlines at the end.
    +            var content = getInnerHtml(cs);
    +            content = content.replace(/(?:\r\n?|\n)$/, '');
    +
    +	  		/* ND Change: we need to preserve &nbsp;s so change them to a special character instead of a space. */
    +			content = content.replace(/&nbsp;/g, '\x11');
    +
    +            // do the pretty printing
    +            prettyPrintingJob = {
    +              sourceCodeHtml: content,
    +              langExtension: langExtension,
    +              sourceNode: cs
    +            };
    +            applyDecorator(prettyPrintingJob);
    +            replaceWithPrettyPrintedHtml();
    +          }
    +        }
    +      }
    +      if (k < elements.length) {
    +        // finish up in a continuation
    +        setTimeout(doWork, 250);
    +      } else if (opt_whenDone) {
    +        opt_whenDone();
    +      }
    +    }
    +
    +    function replaceWithPrettyPrintedHtml() {
    +      var newContent = prettyPrintingJob.prettyPrintedHtml;
    +      if (!newContent) { return; }
    +
    +      /* ND Change: Restore the preserved &nbsp;s.  */
    +	  newContent = newContent.replace(/\x11/g, '&nbsp;');
    +
    +      var cs = prettyPrintingJob.sourceNode;
    +
    +      // push the prettified html back into the tag.
    +      if (!isRawContent(cs)) {
    +        // just replace the old html with the new
    +        cs.innerHTML = newContent;
    +      } else {
    +        // we need to change the tag to a <pre> since <xmp>s do not allow
    +        // embedded tags such as the span tags used to attach styles to
    +        // sections of source code.
    +        var pre = document.createElement('PRE');
    +        for (var i = 0; i < cs.attributes.length; ++i) {
    +          var a = cs.attributes[i];
    +          if (a.specified) {
    +            var aname = a.name.toLowerCase();
    +            if (aname === 'class') {
    +              pre.className = a.value;  // For IE 6
    +            } else {
    +              pre.setAttribute(a.name, a.value);
    +            }
    +          }
    +        }
    +        pre.innerHTML = newContent;
    +
    +        // remove the old
    +        cs.parentNode.replaceChild(pre, cs);
    +        cs = pre;
    +      }
    +
    +      // Replace <br>s with line-feeds so that copying and pasting works
    +      // on IE 6.
    +      // Doing this on other browsers breaks lots of stuff since \r\n is
    +      // treated as two newlines on Firefox, and doing this also slows
    +      // down rendering.
    +      if (isIE678 && cs.tagName === 'PRE') {
    +        var lineBreaks = cs.getElementsByTagName('br');
    +        for (var j = lineBreaks.length; --j >= 0;) {
    +          var lineBreak = lineBreaks[j];
    +          lineBreak.parentNode.replaceChild(
    +              document.createTextNode(ieNewline), lineBreak);
    +        }
    +      }
    +    }
    +
    +    doWork();
    +  }
    +
    +  window['PR_normalizedHtml'] = normalizedHtml;
    +  window['prettyPrintOne'] = prettyPrintOne;
    +  window['prettyPrint'] = prettyPrint;
    +  window['PR'] = {
    +        'combinePrefixPatterns': combinePrefixPatterns,
    +        'createSimpleLexer': createSimpleLexer,
    +        'registerLangHandler': registerLangHandler,
    +        'sourceDecorator': sourceDecorator,
    +        'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
    +        'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
    +        'PR_COMMENT': PR_COMMENT,
    +        'PR_DECLARATION': PR_DECLARATION,
    +        'PR_KEYWORD': PR_KEYWORD,
    +        'PR_LITERAL': PR_LITERAL,
    +        'PR_NOCODE': PR_NOCODE,
    +        'PR_PLAIN': PR_PLAIN,
    +        'PR_PUNCTUATION': PR_PUNCTUATION,
    +        'PR_SOURCE': PR_SOURCE,
    +        'PR_STRING': PR_STRING,
    +        'PR_TAG': PR_TAG,
    +        'PR_TYPE': PR_TYPE
    +      };
    +})();
    +
    +
    +// ____________________________________________________________________________
    +
    +
    +
    +// Lua extension
    +
    +PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0]+/,null,'	\n\r \xa0'],[PR.PR_STRING,/^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])*(?:\'|$))/,null,'\"\'']],[[PR.PR_COMMENT,/^--(?:\[(=*)\[[\s\S]*?(?:\]\1\]|$)|[^\r\n]*)/],[PR.PR_STRING,/^\[(=*)\[[\s\S]*?(?:\]\1\]|$)/],[PR.PR_KEYWORD,/^(?:and|break|do|else|elseif|end|false|for|function|if|in|local|nil|not|or|repeat|return|then|true|until|while)\b/,null],[PR.PR_LITERAL,/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],[PR.PR_PLAIN,/^[a-z_]\w*/i],[PR.PR_PUNCTUATION,/^[^\w\t\n\r \xA0][^\w\t\n\r \xA0\"\'\-\+=]*/]]),['lua'])
    +
    +
    +// Haskell extension
    +
    +PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\x0B\x0C\r ]+/,null,'	\n\r '],[PR.PR_STRING,/^\"(?:[^\"\\\n\x0C\r]|\\[\s\S])*(?:\"|$)/,null,'\"'],[PR.PR_STRING,/^\'(?:[^\'\\\n\x0C\r]|\\[^&])\'?/,null,'\''],[PR.PR_LITERAL,/^(?:0o[0-7]+|0x[\da-f]+|\d+(?:\.\d+)?(?:e[+\-]?\d+)?)/i,null,'0123456789']],[[PR.PR_COMMENT,/^(?:(?:--+(?:[^\r\n\x0C]*)?)|(?:\{-(?:[^-]|-+[^-\}])*-\}))/],[PR.PR_KEYWORD,/^(?:case|class|data|default|deriving|do|else|if|import|in|infix|infixl|infixr|instance|let|module|newtype|of|then|type|where|_)(?=[^a-zA-Z0-9\']|$)/,null],[PR.PR_PLAIN,/^(?:[A-Z][\w\']*\.)*[a-zA-Z][\w\']*/],[PR.PR_PUNCTUATION,/^[^\t\n\x0B\x0C\r a-zA-Z0-9\'\"]+/]]),['hs'])
    +
    +
    +// ML extension
    +
    +PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0]+/,null,'	\n\r \xa0'],[PR.PR_COMMENT,/^#(?:if[\t\n\r \xA0]+(?:[a-z_$][\w\']*|``[^\r\n\t`]*(?:``|$))|else|endif|light)/i,null,'#'],[PR.PR_STRING,/^(?:\"(?:[^\"\\]|\\[\s\S])*(?:\"|$)|\'(?:[^\'\\]|\\[\s\S])*(?:\'|$))/,null,'\"\'']],[[PR.PR_COMMENT,/^(?:\/\/[^\r\n]*|\(\*[\s\S]*?\*\))/],[PR.PR_KEYWORD,/^(?:abstract|and|as|assert|begin|class|default|delegate|do|done|downcast|downto|elif|else|end|exception|extern|false|finally|for|fun|function|if|in|inherit|inline|interface|internal|lazy|let|match|member|module|mutable|namespace|new|null|of|open|or|override|private|public|rec|return|static|struct|then|to|true|try|type|upcast|use|val|void|when|while|with|yield|asr|land|lor|lsl|lsr|lxor|mod|sig|atomic|break|checked|component|const|constraint|constructor|continue|eager|event|external|fixed|functor|global|include|method|mixin|object|parallel|process|protected|pure|sealed|trait|virtual|volatile)\b/],[PR.PR_LITERAL,/^[+\-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],[PR.PR_PLAIN,/^(?:[a-z_]\w*[!?#]?|``[^\r\n\t`]*(?:``|$))/i],[PR.PR_PUNCTUATION,/^[^\t\n\r \xA0\"\'\w]+/]]),['fs','ml'])
    +
    +
    +// SQL extension
    +
    +PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0]+/,null,'	\n\r \xa0'],[PR.PR_STRING,/^(?:"(?:[^\"\\]|\\.)*"|'(?:[^\'\\]|\\.)*')/,null,'\"\'']],[[PR.PR_COMMENT,/^(?:--[^\r\n]*|\/\*[\s\S]*?(?:\*\/|$))/],[PR.PR_KEYWORD,/^(?:ADD|ALL|ALTER|AND|ANY|AS|ASC|AUTHORIZATION|BACKUP|BEGIN|BETWEEN|BREAK|BROWSE|BULK|BY|CASCADE|CASE|CHECK|CHECKPOINT|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMN|COMMIT|COMPUTE|CONSTRAINT|CONTAINS|CONTAINSTABLE|CONTINUE|CONVERT|CREATE|CROSS|CURRENT|CURRENT_DATE|CURRENT_TIME|CURRENT_TIMESTAMP|CURRENT_USER|CURSOR|DATABASE|DBCC|DEALLOCATE|DECLARE|DEFAULT|DELETE|DENY|DESC|DISK|DISTINCT|DISTRIBUTED|DOUBLE|DROP|DUMMY|DUMP|ELSE|END|ERRLVL|ESCAPE|EXCEPT|EXEC|EXECUTE|EXISTS|EXIT|FETCH|FILE|FILLFACTOR|FOR|FOREIGN|FREETEXT|FREETEXTTABLE|FROM|FULL|FUNCTION|GOTO|GRANT|GROUP|HAVING|HOLDLOCK|IDENTITY|IDENTITYCOL|IDENTITY_INSERT|IF|IN|INDEX|INNER|INSERT|INTERSECT|INTO|IS|JOIN|KEY|KILL|LEFT|LIKE|LINENO|LOAD|NATIONAL|NOCHECK|NONCLUSTERED|NOT|NULL|NULLIF|OF|OFF|OFFSETS|ON|OPEN|OPENDATASOURCE|OPENQUERY|OPENROWSET|OPENXML|OPTION|OR|ORDER|OUTER|OVER|PERCENT|PLAN|PRECISION|PRIMARY|PRINT|PROC|PROCEDURE|PUBLIC|RAISERROR|READ|READTEXT|RECONFIGURE|REFERENCES|REPLICATION|RESTORE|RESTRICT|RETURN|REVOKE|RIGHT|ROLLBACK|ROWCOUNT|ROWGUIDCOL|RULE|SAVE|SCHEMA|SELECT|SESSION_USER|SET|SETUSER|SHUTDOWN|SOME|STATISTICS|SYSTEM_USER|TABLE|TEXTSIZE|THEN|TO|TOP|TRAN|TRANSACTION|TRIGGER|TRUNCATE|TSEQUAL|UNION|UNIQUE|UPDATE|UPDATETEXT|USE|USER|VALUES|VARYING|VIEW|WAITFOR|WHEN|WHERE|WHILE|WITH|WRITETEXT)(?=[^\w-]|$)/i,null],[PR.PR_LITERAL,/^[+-]?(?:0x[\da-f]+|(?:(?:\.\d+|\d+(?:\.\d*)?)(?:e[+\-]?\d+)?))/i],[PR.PR_PLAIN,/^[a-z_][\w-]*/i],[PR.PR_PUNCTUATION,/^[^\w\t\n\r \xA0\"\'][^\w\t\n\r \xA0+\-\"\']*/]]),['sql'])
    +
    +
    +// VB extension
    +
    +PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[\t\n\r \xA0\u2028\u2029]+/,null,'	\n\r \xa0\u2028\u2029'],[PR.PR_STRING,/^(?:[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})(?:[\"\u201C\u201D]c|$)|[\"\u201C\u201D](?:[^\"\u201C\u201D]|[\"\u201C\u201D]{2})*(?:[\"\u201C\u201D]|$))/i,null,'\"\u201c\u201d'],[PR.PR_COMMENT,/^[\'\u2018\u2019][^\r\n\u2028\u2029]*/,null,'\'\u2018\u2019']],[[PR.PR_KEYWORD,/^(?:AddHandler|AddressOf|Alias|And|AndAlso|Ansi|As|Assembly|Auto|Boolean|ByRef|Byte|ByVal|Call|Case|Catch|CBool|CByte|CChar|CDate|CDbl|CDec|Char|CInt|Class|CLng|CObj|Const|CShort|CSng|CStr|CType|Date|Decimal|Declare|Default|Delegate|Dim|DirectCast|Do|Double|Each|Else|ElseIf|End|EndIf|Enum|Erase|Error|Event|Exit|Finally|For|Friend|Function|Get|GetType|GoSub|GoTo|Handles|If|Implements|Imports|In|Inherits|Integer|Interface|Is|Let|Lib|Like|Long|Loop|Me|Mod|Module|MustInherit|MustOverride|MyBase|MyClass|Namespace|New|Next|Not|NotInheritable|NotOverridable|Object|On|Option|Optional|Or|OrElse|Overloads|Overridable|Overrides|ParamArray|Preserve|Private|Property|Protected|Public|RaiseEvent|ReadOnly|ReDim|RemoveHandler|Resume|Return|Select|Set|Shadows|Shared|Short|Single|Static|Step|Stop|String|Structure|Sub|SyncLock|Then|Throw|To|Try|TypeOf|Unicode|Until|Variant|Wend|When|While|With|WithEvents|WriteOnly|Xor|EndIf|GoSub|Let|Variant|Wend)\b/i,null],[PR.PR_COMMENT,/^REM[^\r\n\u2028\u2029]*/i],[PR.PR_LITERAL,/^(?:True\b|False\b|Nothing\b|\d+(?:E[+\-]?\d+[FRD]?|[FRDSIL])?|(?:&H[0-9A-F]+|&O[0-7]+)[SIL]?|\d*\.\d+(?:E[+\-]?\d+)?[FRD]?|#\s+(?:\d+[\-\/]\d+[\-\/]\d+(?:\s+\d+:\d+(?::\d+)?(\s*(?:AM|PM))?)?|\d+:\d+(?::\d+)?(\s*(?:AM|PM))?)\s+#)/i],[PR.PR_PLAIN,/^(?:(?:[a-z]|_\w)\w*|\[(?:[a-z]|_\w)\w*\])/i],[PR.PR_PUNCTUATION,/^[^\w\t\n\r \"\'\[\]\xA0\u2018\u2019\u201C\u201D\u2028\u2029]+/],[PR.PR_PUNCTUATION,/^(?:\[|\])/]]),['vb','vbs'])
    diff --git a/docu/nd/search/ClassesC.html b/docu/nd/search/ClassesC.html
    index c74a031..fe907c1 100644
    --- a/docu/nd/search/ClassesC.html
    +++ b/docu/nd/search/ClassesC.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/ClassesF.html b/docu/nd/search/ClassesF.html
    index b328661..74cd0a2 100644
    --- a/docu/nd/search/ClassesF.html
    +++ b/docu/nd/search/ClassesF.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/ClassesR.html b/docu/nd/search/ClassesR.html
    index 07d231b..5ff17c7 100644
    --- a/docu/nd/search/ClassesR.html
    +++ b/docu/nd/search/ClassesR.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/ClassesS.html b/docu/nd/search/ClassesS.html
    index 15e616d..180f91e 100644
    --- a/docu/nd/search/ClassesS.html
    +++ b/docu/nd/search/ClassesS.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/ConstantsM.html b/docu/nd/search/ConstantsM.html
    index 64fb4fb..d64a419 100644
    --- a/docu/nd/search/ConstantsM.html
    +++ b/docu/nd/search/ConstantsM.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/ConstantsT.html b/docu/nd/search/ConstantsT.html
    index 99ecbdf..2bf8702 100644
    --- a/docu/nd/search/ConstantsT.html
    +++ b/docu/nd/search/ConstantsT.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/FilesS.html b/docu/nd/search/FilesS.html
    index b33f2d3..c1222ec 100644
    --- a/docu/nd/search/FilesS.html
    +++ b/docu/nd/search/FilesS.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/FunctionsC.html b/docu/nd/search/FunctionsC.html
    index c5d0804..befa28d 100644
    --- a/docu/nd/search/FunctionsC.html
    +++ b/docu/nd/search/FunctionsC.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/FunctionsE.html b/docu/nd/search/FunctionsE.html
    index 053e88f..748c789 100644
    --- a/docu/nd/search/FunctionsE.html
    +++ b/docu/nd/search/FunctionsE.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/FunctionsG.html b/docu/nd/search/FunctionsG.html
    index 1dd94fa..5985a01 100644
    --- a/docu/nd/search/FunctionsG.html
    +++ b/docu/nd/search/FunctionsG.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/FunctionsL.html b/docu/nd/search/FunctionsL.html
    index 6dd84af..75195a3 100644
    --- a/docu/nd/search/FunctionsL.html
    +++ b/docu/nd/search/FunctionsL.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/FunctionsP.html b/docu/nd/search/FunctionsP.html
    index 53cabdf..f8480d5 100644
    --- a/docu/nd/search/FunctionsP.html
    +++ b/docu/nd/search/FunctionsP.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/FunctionsR.html b/docu/nd/search/FunctionsR.html
    index 5a8fa29..5bb2037 100644
    --- a/docu/nd/search/FunctionsR.html
    +++ b/docu/nd/search/FunctionsR.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/FunctionsS.html b/docu/nd/search/FunctionsS.html
    index 34da684..65493ff 100644
    --- a/docu/nd/search/FunctionsS.html
    +++ b/docu/nd/search/FunctionsS.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/FunctionsSymbols.html b/docu/nd/search/FunctionsSymbols.html
    index 06ae917..7141ab5 100644
    --- a/docu/nd/search/FunctionsSymbols.html
    +++ b/docu/nd/search/FunctionsSymbols.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/FunctionsT.html b/docu/nd/search/FunctionsT.html
    index d0fbe06..f32a673 100644
    --- a/docu/nd/search/FunctionsT.html
    +++ b/docu/nd/search/FunctionsT.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/GeneralB.html b/docu/nd/search/GeneralB.html
    index 2c27dd5..716b2c6 100644
    --- a/docu/nd/search/GeneralB.html
    +++ b/docu/nd/search/GeneralB.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/GeneralC.html b/docu/nd/search/GeneralC.html
    index 649ac7c..4151558 100644
    --- a/docu/nd/search/GeneralC.html
    +++ b/docu/nd/search/GeneralC.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/GeneralE.html b/docu/nd/search/GeneralE.html
    index 053e88f..748c789 100644
    --- a/docu/nd/search/GeneralE.html
    +++ b/docu/nd/search/GeneralE.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/GeneralF.html b/docu/nd/search/GeneralF.html
    index bb01ea5..3457db3 100644
    --- a/docu/nd/search/GeneralF.html
    +++ b/docu/nd/search/GeneralF.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/GeneralG.html b/docu/nd/search/GeneralG.html
    index 1dd94fa..5985a01 100644
    --- a/docu/nd/search/GeneralG.html
    +++ b/docu/nd/search/GeneralG.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/GeneralL.html b/docu/nd/search/GeneralL.html
    index 6638fd5..9dc4581 100644
    --- a/docu/nd/search/GeneralL.html
    +++ b/docu/nd/search/GeneralL.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/GeneralM.html b/docu/nd/search/GeneralM.html
    index 9f08ee4..01256f5 100644
    --- a/docu/nd/search/GeneralM.html
    +++ b/docu/nd/search/GeneralM.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/GeneralP.html b/docu/nd/search/GeneralP.html
    index 3412103..013d51b 100644
    --- a/docu/nd/search/GeneralP.html
    +++ b/docu/nd/search/GeneralP.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/GeneralR.html b/docu/nd/search/GeneralR.html
    index 9545219..92e7ea5 100644
    --- a/docu/nd/search/GeneralR.html
    +++ b/docu/nd/search/GeneralR.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/GeneralS.html b/docu/nd/search/GeneralS.html
    index ea5fd6d..1e1a9f4 100644
    --- a/docu/nd/search/GeneralS.html
    +++ b/docu/nd/search/GeneralS.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/GeneralSymbols.html b/docu/nd/search/GeneralSymbols.html
    index 06ae917..7141ab5 100644
    --- a/docu/nd/search/GeneralSymbols.html
    +++ b/docu/nd/search/GeneralSymbols.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/GeneralT.html b/docu/nd/search/GeneralT.html
    index b8ab323..648dbb2 100644
    --- a/docu/nd/search/GeneralT.html
    +++ b/docu/nd/search/GeneralT.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/GeneralV.html b/docu/nd/search/GeneralV.html
    index 1610bac..a9fc3a5 100644
    --- a/docu/nd/search/GeneralV.html
    +++ b/docu/nd/search/GeneralV.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/NoResults.html b/docu/nd/search/NoResults.html
    index 02ce888..8c72496 100644
    --- a/docu/nd/search/NoResults.html
    +++ b/docu/nd/search/NoResults.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/VariablesB.html b/docu/nd/search/VariablesB.html
    index 2c27dd5..716b2c6 100644
    --- a/docu/nd/search/VariablesB.html
    +++ b/docu/nd/search/VariablesB.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/VariablesF.html b/docu/nd/search/VariablesF.html
    index 042f7ba..b57f104 100644
    --- a/docu/nd/search/VariablesF.html
    +++ b/docu/nd/search/VariablesF.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/VariablesM.html b/docu/nd/search/VariablesM.html
    index 42f88b4..d22a4fb 100644
    --- a/docu/nd/search/VariablesM.html
    +++ b/docu/nd/search/VariablesM.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/VariablesP.html b/docu/nd/search/VariablesP.html
    index 63d4304..114a154 100644
    --- a/docu/nd/search/VariablesP.html
    +++ b/docu/nd/search/VariablesP.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/search/VariablesV.html b/docu/nd/search/VariablesV.html
    index 5461292..412b742 100644
    --- a/docu/nd/search/VariablesV.html
    +++ b/docu/nd/search/VariablesV.html
    @@ -1,9 +1,9 @@
     <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
     
    -<html><head><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
    +<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="../styles/main.css"><script language=JavaScript src="../javascript/main.js"></script></head><body class="PopupSearchResultsPage" onLoad="NDOnLoad()"><script language=JavaScript><!--
     if (browserType) {document.write("<div class=" + browserType + ">");if (browserVer) {document.write("<div class=" + browserVer + ">"); }}// --></script>
     
    -<!--  Generated by Natural Docs, version 1.4 -->
    +<!--  Generated by Natural Docs, version 1.52 -->
     <!--  http://www.naturaldocs.org  -->
     
     <!-- saved from url=(0026)http://www.naturaldocs.org -->
    diff --git a/docu/nd/styles/main.css b/docu/nd/styles/main.css
    index 134199a..511703f 100644
    --- a/docu/nd/styles/main.css
    +++ b/docu/nd/styles/main.css
    @@ -1,767 +1,828 @@
    -/*
    -   IMPORTANT: If you're editing this file in the output directory of one of
    -   your projects, your changes will be overwritten the next time you run
    -   Natural Docs.  Instead, copy this file to your project directory, make your
    -   changes, and you can use it with -s.  Even better would be to make a CSS
    -   file in your project directory with only your changes, which you can then
    -   use with -s [original style] [your changes].
    -
    -   On the other hand, if you're editing this file in the Natural Docs styles
    -   directory, the changes will automatically be applied to all your projects
    -   that use this style the next time Natural Docs is run on them.
    -
    -   This file is part of Natural Docs, which is Copyright (C) 2003-2008 Greg Valure
    -   Natural Docs is licensed under the GPL
    -*/
    -
    -body {
    -    font: 10pt Verdana, Arial, sans-serif;
    -    color: #000000;
    -    margin: 0; padding: 0;
    -    }
    -
    -.ContentPage,
    -.IndexPage,
    -.FramedMenuPage {
    -    background-color: #E8E8E8;
    -    }
    -.FramedContentPage,
    -.FramedIndexPage,
    -.FramedSearchResultsPage,
    -.PopupSearchResultsPage {
    -    background-color: #FFFFFF;
    -    }
    -
    -
    -a:link,
    -a:visited { color: #900000; text-decoration: none }
    -a:hover { color: #900000; text-decoration: underline }
    -a:active { color: #FF0000; text-decoration: underline }
    -
    -td {
    -    vertical-align: top }
    -
    -img { border: 0;  }
    -
    -
    -/*
    -    Comment out this line to use web-style paragraphs (blank line between
    -    paragraphs, no indent) instead of print-style paragraphs (no blank line,
    -    indented.)
    -*/
    -p {
    -    text-indent: 5ex; margin: 0 }
    -
    -
    -/*  Opera doesn't break with just wbr, but will if you add this.  */
    -.Opera wbr:after {
    -	content: "\00200B";
    -	}
    -
    -
    -/*  Blockquotes are used as containers for things that may need to scroll.  */
    -blockquote {
    -    padding: 0;
    -    margin: 0;
    -    overflow: auto;
    -    }
    -
    -
    -.Firefox1 blockquote {
    -    padding-bottom: .5em;
    -    }
    -
    -/*  Turn off scrolling when printing.  */
    -@media print {
    -    blockquote {
    -        overflow: visible;
    -        }
    -    .IE blockquote {
    -        width: auto;
    -        }
    -    }
    -
    -
    -
    -#Menu {
    -    font-size: 9pt;
    -    padding: 10px 0 0 0;
    -    }
    -.ContentPage #Menu,
    -.IndexPage #Menu {
    -    position: absolute;
    -    top: 0;
    -    left: 0;
    -    width: 31ex;
    -    overflow: hidden;
    -    }
    -.ContentPage .Firefox #Menu,
    -.IndexPage .Firefox #Menu {
    -    width: 27ex;
    -    }
    -
    -
    -    .MTitle {
    -        font-size: 16pt; font-weight: bold; font-variant: small-caps;
    -        text-align: center;
    -        padding: 5px 10px 15px 10px;
    -        border-bottom: 1px dotted #000000;
    -        margin-bottom: 15px }
    -
    -    .MSubTitle {
    -        font-size: 9pt; font-weight: normal; font-variant: normal;
    -        margin-top: 1ex; margin-bottom: 5px }
    -
    -
    -    .MEntry a:link,
    -    .MEntry a:hover,
    -    .MEntry a:visited { color: #606060; margin-right: 0 }
    -    .MEntry a:active { color: #A00000; margin-right: 0 }
    -
    -
    -    .MGroup {
    -        font-variant: small-caps; font-weight: bold;
    -        margin: 1em 0 1em 10px;
    -        }
    -
    -    .MGroupContent {
    -        font-variant: normal; font-weight: normal }
    -
    -    .MGroup a:link,
    -    .MGroup a:hover,
    -    .MGroup a:visited { color: #545454; margin-right: 10px }
    -    .MGroup a:active { color: #A00000; margin-right: 10px }
    -
    -
    -    .MFile,
    -    .MText,
    -    .MLink,
    -    .MIndex {
    -        padding: 1px 17px 2px 10px;
    -        margin: .25em 0 .25em 0;
    -        }
    -
    -    .MText {
    -        font-size: 8pt; font-style: italic }
    -
    -    .MLink {
    -        font-style: italic }
    -
    -    #MSelected {
    -        color: #000000; background-color: #FFFFFF;
    -        /*  Replace padding with border.  */
    -        padding: 0 10px 0 10px;
    -        border-width: 1px 2px 2px 0; border-style: solid; border-color: #000000;
    -        margin-right: 5px;
    -        }
    -
    -    /*  Close off the left side when its in a group.  */
    -    .MGroup #MSelected {
    -        padding-left: 9px; border-left-width: 1px }
    -
    -    /*  A treat for Mozilla users.  Blatantly non-standard.  Will be replaced with CSS 3 attributes when finalized/supported.  */
    -    .Firefox #MSelected {
    -        -moz-border-radius-topright: 10px;
    -        -moz-border-radius-bottomright: 10px }
    -    .Firefox .MGroup #MSelected {
    -        -moz-border-radius-topleft: 10px;
    -        -moz-border-radius-bottomleft: 10px }
    -
    -
    -    #MSearchPanel {
    -        padding: 0px 6px;
    -        margin: .25em 0;
    -        }
    -
    -
    -    #MSearchField {
    -        font: italic 9pt Verdana, sans-serif;
    -        color: #606060;
    -        background-color: #E8E8E8;
    -        border: none;
    -        padding: 2px 4px;
    -        width: 100%;
    -        }
    -    /* Only Opera gets it right. */
    -    .Firefox #MSearchField,
    -    .IE #MSearchField,
    -    .Safari #MSearchField {
    -        width: 94%;
    -        }
    -    .Opera9 #MSearchField,
    -    .Konqueror #MSearchField {
    -        width: 97%;
    -        }
    -    .FramedMenuPage .Firefox #MSearchField,
    -    .FramedMenuPage .Safari #MSearchField,
    -    .FramedMenuPage .Konqueror #MSearchField {
    -        width: 98%;
    -        }
    -
    -    /* Firefox doesn't do this right in frames without #MSearchPanel added on.
    -        It's presence doesn't hurt anything other browsers. */
    -    #MSearchPanel.MSearchPanelInactive:hover #MSearchField {
    -        background-color: #FFFFFF;
    -        border: 1px solid #C0C0C0;
    -        padding: 1px 3px;
    -        }
    -    .MSearchPanelActive #MSearchField {
    -        background-color: #FFFFFF;
    -        border: 1px solid #C0C0C0;
    -        font-style: normal;
    -        padding: 1px 3px;
    -        }
    -
    -    #MSearchType {
    -        visibility: hidden;
    -        font: 8pt Verdana, sans-serif;
    -        width: 98%;
    -        padding: 0;
    -        border: 1px solid #C0C0C0;
    -        }
    -    .MSearchPanelActive #MSearchType,
    -    /*  As mentioned above, Firefox doesn't do this right in frames without #MSearchPanel added on. */
    -    #MSearchPanel.MSearchPanelInactive:hover #MSearchType,
    -    #MSearchType:focus {
    -        visibility: visible;
    -        color: #606060;
    -        }
    -    #MSearchType option#MSearchEverything {
    -        font-weight: bold;
    -        }
    -
    -    .Opera8 .MSearchPanelInactive:hover,
    -    .Opera8 .MSearchPanelActive {
    -        margin-left: -1px;
    -        }
    -
    -
    -    iframe#MSearchResults {
    -        width: 60ex;
    -        height: 15em;
    -        }
    -    #MSearchResultsWindow {
    -        display: none;
    -        position: absolute;
    -        left: 0; top: 0;
    -        border: 1px solid #000000;
    -        background-color: #E8E8E8;
    -        }
    -    #MSearchResultsWindowClose {
    -        font-weight: bold;
    -        font-size: 8pt;
    -        display: block;
    -        padding: 2px 5px;
    -        }
    -    #MSearchResultsWindowClose:link,
    -    #MSearchResultsWindowClose:visited {
    -        color: #000000;
    -        text-decoration: none;
    -        }
    -    #MSearchResultsWindowClose:active,
    -    #MSearchResultsWindowClose:hover {
    -        color: #800000;
    -        text-decoration: none;
    -        background-color: #F4F4F4;
    -        }
    -
    -
    -
    -
    -#Content {
    -    padding-bottom: 15px;
    -    }
    -
    -.ContentPage #Content {
    -    border-width: 0 0 1px 1px;
    -    border-style: solid;
    -    border-color: #000000;
    -    background-color: #FFFFFF;
    -    font-size: 9pt;  /* To make 31ex match the menu's 31ex. */
    -    margin-left: 31ex;
    -    }
    -.ContentPage .Firefox #Content {
    -    margin-left: 27ex;
    -    }
    -
    -
    -
    -    .CTopic {
    -        font-size: 10pt;
    -        margin-bottom: 3em;
    -        }
    -
    -
    -    .CTitle {
    -        font-size: 12pt; font-weight: bold;
    -        border-width: 0 0 1px 0; border-style: solid; border-color: #A0A0A0;
    -        margin: 0 15px .5em 15px }
    -
    -    .CGroup .CTitle {
    -        font-size: 16pt; font-variant: small-caps;
    -        padding-left: 15px; padding-right: 15px;
    -        border-width: 0 0 2px 0; border-color: #000000;
    -        margin-left: 0; margin-right: 0 }
    -
    -    .CClass .CTitle,
    -    .CInterface .CTitle,
    -    .CDatabase .CTitle,
    -    .CDatabaseTable .CTitle,
    -    .CSection .CTitle {
    -        font-size: 18pt;
    -        color: #FFFFFF; background-color: #A0A0A0;
    -        padding: 10px 15px 10px 15px;
    -        border-width: 2px 0; border-color: #000000;
    -        margin-left: 0; margin-right: 0 }
    -
    -    #MainTopic .CTitle {
    -        font-size: 20pt;
    -        color: #FFFFFF; background-color: #7070C0;
    -        padding: 10px 15px 10px 15px;
    -        border-width: 0 0 3px 0; border-color: #000000;
    -        margin-left: 0; margin-right: 0 }
    -
    -    .CBody {
    -        margin-left: 15px; margin-right: 15px }
    -
    -
    -    .CToolTip {
    -        position: absolute; visibility: hidden;
    -        left: 0; top: 0;
    -        background-color: #FFFFE0;
    -        padding: 5px;
    -        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #000000;
    -        font-size: 8pt;
    -        }
    -
    -    .Opera .CToolTip {
    -        max-width: 98%;
    -        }
    -
    -    /*  Scrollbars would be useless.  */
    -    .CToolTip blockquote {
    -        overflow: hidden;
    -        }
    -    .IE6 .CToolTip blockquote {
    -        overflow: visible;
    -        }
    -
    -    .CHeading {
    -        font-weight: bold; font-size: 10pt;
    -        margin: 1.5em 0 .5em 0;
    -        }
    -
    -    .CBody pre {
    -        font: 10pt "Courier New", Courier, monospace;
    -        margin: 1em 0;
    -        }
    -
    -    .CBody ul {
    -        /*  I don't know why CBody's margin doesn't apply, but it's consistent across browsers so whatever.
    -             Reapply it here as padding.  */
    -        padding-left: 15px; padding-right: 15px;
    -        margin: .5em 5ex .5em 5ex;
    -        }
    -
    -    .CDescriptionList {
    -        margin: .5em 5ex 0 5ex }
    -
    -        .CDLEntry {
    -            font: 10pt "Courier New", Courier, monospace; color: #808080;
    -            padding-bottom: .25em;
    -            white-space: nowrap }
    -
    -        .CDLDescription {
    -            font-size: 10pt;  /*  For browsers that don't inherit correctly, like Opera 5.  */
    -            padding-bottom: .5em; padding-left: 5ex }
    -
    -
    -    .CTopic img {
    -        text-align: center;
    -        display: block;
    -        margin: 1em auto;
    -        }
    -    .CImageCaption {
    -        font-variant: small-caps;
    -        font-size: 8pt;
    -        color: #808080;
    -        text-align: center;
    -        position: relative;
    -        top: 1em;
    -        }
    -
    -    .CImageLink {
    -        color: #808080;
    -        font-style: italic;
    -        }
    -    a.CImageLink:link,
    -    a.CImageLink:visited,
    -    a.CImageLink:hover { color: #808080 }
    -
    -
    -
    -
    -
    -.Prototype {
    -    font: 10pt "Courier New", Courier, monospace;
    -    padding: 5px 3ex;
    -    border-width: 1px; border-style: solid;
    -    margin: 0 5ex 1.5em 5ex;
    -    }
    -
    -    .Prototype td {
    -        font-size: 10pt;
    -        }
    -
    -    .PDefaultValue,
    -    .PDefaultValuePrefix,
    -    .PTypePrefix {
    -        color: #8F8F8F;
    -        }
    -    .PTypePrefix {
    -        text-align: right;
    -        }
    -    .PAfterParameters {
    -        vertical-align: bottom;
    -        }
    -
    -    .IE .Prototype table {
    -        padding: 0;
    -        }
    -
    -    .CFunction .Prototype {
    -        background-color: #F4F4F4; border-color: #D0D0D0 }
    -    .CProperty .Prototype {
    -        background-color: #F4F4FF; border-color: #C0C0E8 }
    -    .CVariable .Prototype {
    -        background-color: #FFFFF0; border-color: #E0E0A0 }
    -
    -    .CClass .Prototype {
    -        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0;
    -        background-color: #F4F4F4;
    -        }
    -    .CInterface .Prototype {
    -        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0D0;
    -        background-color: #F4F4FF;
    -        }
    -
    -    .CDatabaseIndex .Prototype,
    -    .CConstant .Prototype {
    -        background-color: #D0D0D0; border-color: #000000 }
    -    .CType .Prototype,
    -    .CEnumeration .Prototype {
    -        background-color: #FAF0F0; border-color: #E0B0B0;
    -        }
    -    .CDatabaseTrigger .Prototype,
    -    .CEvent .Prototype,
    -    .CDelegate .Prototype {
    -        background-color: #F0FCF0; border-color: #B8E4B8 }
    -
    -    .CToolTip .Prototype {
    -        margin: 0 0 .5em 0;
    -        white-space: nowrap;
    -        }
    -
    -
    -
    -
    -
    -.Summary {
    -    margin: 1.5em 5ex 0 5ex }
    -
    -    .STitle {
    -        font-size: 12pt; font-weight: bold;
    -        margin-bottom: .5em }
    -
    -
    -    .SBorder {
    -        background-color: #FFFFF0;
    -        padding: 15px;
    -        border: 1px solid #C0C060 }
    -
    -    /* In a frame IE 6 will make them too long unless you set the width to 100%.  Without frames it will be correct without a width
    -        or slightly too long (but not enough to scroll) with a width.  This arbitrary weirdness simply astounds me.  IE 7 has the same
    -        problem with frames, haven't tested it without.  */
    -    .FramedContentPage .IE .SBorder {
    -        width: 100% }
    -
    -    /*  A treat for Mozilla users.  Blatantly non-standard.  Will be replaced with CSS 3 attributes when finalized/supported.  */
    -    .Firefox .SBorder {
    -        -moz-border-radius: 20px }
    -
    -
    -    .STable {
    -        font-size: 9pt; width: 100% }
    -
    -    .SEntry {
    -        width: 30% }
    -    .SDescription {
    -        width: 70% }
    -
    -
    -    .SMarked {
    -        background-color: #F8F8D8 }
    -
    -    .SDescription { padding-left: 2ex }
    -    .SIndent1 .SEntry { padding-left: 1.5ex }   .SIndent1 .SDescription { padding-left: 3.5ex }
    -    .SIndent2 .SEntry { padding-left: 3.0ex }   .SIndent2 .SDescription { padding-left: 5.0ex }
    -    .SIndent3 .SEntry { padding-left: 4.5ex }   .SIndent3 .SDescription { padding-left: 6.5ex }
    -    .SIndent4 .SEntry { padding-left: 6.0ex }   .SIndent4 .SDescription { padding-left: 8.0ex }
    -    .SIndent5 .SEntry { padding-left: 7.5ex }   .SIndent5 .SDescription { padding-left: 9.5ex }
    -
    -    .SDescription a { color: #800000}
    -    .SDescription a:active { color: #A00000 }
    -
    -    .SGroup td {
    -        padding-top: .5em; padding-bottom: .25em }
    -
    -    .SGroup .SEntry {
    -        font-weight: bold; font-variant: small-caps }
    -
    -    .SGroup .SEntry a { color: #800000 }
    -    .SGroup .SEntry a:active { color: #F00000 }
    -
    -
    -    .SMain td,
    -    .SClass td,
    -    .SDatabase td,
    -    .SDatabaseTable td,
    -    .SSection td {
    -        font-size: 10pt;
    -        padding-bottom: .25em }
    -
    -    .SClass td,
    -    .SDatabase td,
    -    .SDatabaseTable td,
    -    .SSection td {
    -        padding-top: 1em }
    -
    -    .SMain .SEntry,
    -    .SClass .SEntry,
    -    .SDatabase .SEntry,
    -    .SDatabaseTable .SEntry,
    -    .SSection .SEntry {
    -        font-weight: bold;
    -        }
    -
    -    .SMain .SEntry a,
    -    .SClass .SEntry a,
    -    .SDatabase .SEntry a,
    -    .SDatabaseTable .SEntry a,
    -    .SSection .SEntry a { color: #000000 }
    -
    -    .SMain .SEntry a:active,
    -    .SClass .SEntry a:active,
    -    .SDatabase .SEntry a:active,
    -    .SDatabaseTable .SEntry a:active,
    -    .SSection .SEntry a:active { color: #A00000 }
    -
    -
    -
    -
    -
    -.ClassHierarchy {
    -    margin: 0 15px 1em 15px }
    -
    -    .CHEntry {
    -        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0;
    -        margin-bottom: 3px;
    -        padding: 2px 2ex;
    -        font-size: 10pt;
    -        background-color: #F4F4F4; color: #606060;
    -        }
    -
    -    .Firefox .CHEntry {
    -        -moz-border-radius: 4px;
    -        }
    -
    -    .CHCurrent .CHEntry {
    -        font-weight: bold;
    -        border-color: #000000;
    -        color: #000000;
    -        }
    -
    -    .CHChildNote .CHEntry {
    -        font-style: italic;
    -        font-size: 8pt;
    -        }
    -
    -    .CHIndent {
    -        margin-left: 3ex;
    -        }
    -
    -    .CHEntry a:link,
    -    .CHEntry a:visited,
    -    .CHEntry a:hover {
    -        color: #606060;
    -        }
    -    .CHEntry a:active {
    -        color: #800000;
    -        }
    -
    -
    -
    -
    -
    -#Index {
    -    background-color: #FFFFFF;
    -    }
    -
    -/*  As opposed to .PopupSearchResultsPage #Index  */
    -.IndexPage #Index,
    -.FramedIndexPage #Index,
    -.FramedSearchResultsPage #Index {
    -    padding: 15px;
    -    }
    -
    -.IndexPage #Index {
    -    border-width: 0 0 1px 1px;
    -    border-style: solid;
    -    border-color: #000000;
    -    font-size: 9pt;  /* To make 27ex match the menu's 27ex. */
    -    margin-left: 27ex;
    -    }
    -
    -
    -    .IPageTitle {
    -        font-size: 20pt; font-weight: bold;
    -        color: #FFFFFF; background-color: #7070C0;
    -        padding: 10px 15px 10px 15px;
    -        border-width: 0 0 3px 0; border-color: #000000; border-style: solid;
    -        margin: -15px -15px 0 -15px }
    -
    -    .FramedSearchResultsPage .IPageTitle {
    -        margin-bottom: 15px;
    -        }
    -
    -    .INavigationBar {
    -        font-size: 10pt;
    -        text-align: center;
    -        background-color: #FFFFF0;
    -        padding: 5px;
    -        border-bottom: solid 1px black;
    -        margin: 0 -15px 15px -15px;
    -        }
    -
    -    .INavigationBar a {
    -        font-weight: bold }
    -
    -    .IHeading {
    -        font-size: 16pt; font-weight: bold;
    -        padding: 2.5em 0 .5em 0;
    -        text-align: center;
    -        width: 3.5ex;
    -        }
    -    #IFirstHeading {
    -        padding-top: 0;
    -        }
    -
    -    .IEntry {
    -        font-size: 10pt;
    -        padding-left: 1ex;
    -        }
    -    .PopupSearchResultsPage .IEntry {
    -        font-size: 8pt;
    -        padding: 1px 5px;
    -        }
    -    .PopupSearchResultsPage .Opera9 .IEntry,
    -    .FramedSearchResultsPage .Opera9 .IEntry {
    -        text-align: left;
    -        }
    -    .FramedSearchResultsPage .IEntry {
    -        padding: 0;
    -        }
    -
    -    .ISubIndex {
    -        padding-left: 3ex; padding-bottom: .5em }
    -    .PopupSearchResultsPage .ISubIndex {
    -        display: none;
    -        }
    -
    -    /*  While it may cause some entries to look like links when they aren't, I found it's much easier to read the
    -         index if everything's the same color.  */
    -    .ISymbol {
    -        font-weight: bold; color: #900000  }
    -
    -    .IndexPage .ISymbolPrefix,
    -    .FramedIndexPage .ISymbolPrefix {
    -        font-size: 10pt;
    -        text-align: right;
    -        color: #C47C7C;
    -        background-color: #F8F8F8;
    -        border-right: 3px solid #E0E0E0;
    -        border-left: 1px solid #E0E0E0;
    -        padding: 0 1px 0 2px;
    -        }
    -    .PopupSearchResultsPage .ISymbolPrefix,
    -    .FramedSearchResultsPage .ISymbolPrefix {
    -        color: #900000;
    -        }
    -    .PopupSearchResultsPage .ISymbolPrefix {
    -        font-size: 8pt;
    -        }
    -
    -    .IndexPage #IFirstSymbolPrefix,
    -    .FramedIndexPage #IFirstSymbolPrefix {
    -        border-top: 1px solid #E0E0E0;
    -        }
    -    .IndexPage #ILastSymbolPrefix,
    -    .FramedIndexPage #ILastSymbolPrefix {
    -        border-bottom: 1px solid #E0E0E0;
    -        }
    -    .IndexPage #IOnlySymbolPrefix,
    -    .FramedIndexPage #IOnlySymbolPrefix {
    -        border-top: 1px solid #E0E0E0;
    -        border-bottom: 1px solid #E0E0E0;
    -        }
    -
    -    a.IParent,
    -    a.IFile {
    -        display: block;
    -        }
    -
    -    .PopupSearchResultsPage .SRStatus {
    -        padding: 2px 5px;
    -        font-size: 8pt;
    -        font-style: italic;
    -        }
    -    .FramedSearchResultsPage .SRStatus {
    -        font-size: 10pt;
    -        font-style: italic;
    -        }
    -
    -    .SRResult {
    -        display: none;
    -        }
    -
    -
    -
    -#Footer {
    -    font-size: 8pt;
    -    color: #989898;
    -    text-align: right;
    -    }
    -
    -#Footer p {
    -    text-indent: 0;
    -    margin-bottom: .5em;
    -    }
    -
    -.ContentPage #Footer,
    -.IndexPage #Footer {
    -    text-align: right;
    -    margin: 2px;
    -    }
    -
    -.FramedMenuPage #Footer {
    -    text-align: center;
    -    margin: 5em 10px 10px 10px;
    -    padding-top: 1em;
    -    border-top: 1px solid #C8C8C8;
    -    }
    -
    -    #Footer a:link,
    -    #Footer a:hover,
    -    #Footer a:visited { color: #989898 }
    -    #Footer a:active { color: #A00000 }
    -
    +/*
    +   IMPORTANT: If you're editing this file in the output directory of one of
    +   your projects, your changes will be overwritten the next time you run
    +   Natural Docs.  Instead, copy this file to your project directory, make your
    +   changes, and you can use it with -s.  Even better would be to make a CSS
    +   file in your project directory with only your changes, which you can then
    +   use with -s [original style] [your changes].
    +
    +   On the other hand, if you're editing this file in the Natural Docs styles
    +   directory, the changes will automatically be applied to all your projects
    +   that use this style the next time Natural Docs is run on them.
    +
    +   This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure.
    +   Natural Docs is licensed under version 3 of the GNU Affero General Public
    +   License (AGPL).  Refer to License.txt for the complete details.
    +
    +   This file may be distributed with documentation files generated by Natural Docs.
    +   Such documentation is not covered by Natural Docs' copyright and licensing,
    +   and may have its own copyright and distribution terms as decided by its author.
    +*/
    +
    +body {
    +    font: 10pt Verdana, Arial, sans-serif;
    +    color: #000000;
    +    margin: 0; padding: 0;
    +    }
    +
    +.ContentPage,
    +.IndexPage,
    +.FramedMenuPage {
    +    background-color: #E8E8E8;
    +    }
    +.FramedContentPage,
    +.FramedIndexPage,
    +.FramedSearchResultsPage,
    +.PopupSearchResultsPage {
    +    background-color: #FFFFFF;
    +    }
    +
    +
    +a:link,
    +a:visited { color: #900000; text-decoration: none }
    +a:hover { color: #900000; text-decoration: underline }
    +a:active { color: #FF0000; text-decoration: underline }
    +
    +td {
    +    vertical-align: top }
    +
    +img { border: 0;  }
    +
    +
    +/*
    +    Comment out this line to use web-style paragraphs (blank line between
    +    paragraphs, no indent) instead of print-style paragraphs (no blank line,
    +    indented.)
    +*/
    +p {
    +    text-indent: 5ex; margin: 0 }
    +
    +
    +/*  Opera doesn't break with just wbr, but will if you add this.  */
    +.Opera wbr:after {
    +	content: "\00200B";
    +	}
    +
    +
    +/*  Blockquotes are used as containers for things that may need to scroll.  */
    +blockquote {
    +    padding: 0;
    +    margin: 0;
    +    overflow: auto;
    +    }
    +
    +
    +.Firefox1 blockquote {
    +    padding-bottom: .5em;
    +    }
    +
    +/*  Turn off scrolling when printing.  */
    +@media print {
    +    blockquote {
    +        overflow: visible;
    +        }
    +    .IE blockquote {
    +        width: auto;
    +        }
    +    }
    +
    +
    +
    +#Menu {
    +    font-size: 9pt;
    +    padding: 10px 0 0 0;
    +    }
    +.ContentPage #Menu,
    +.IndexPage #Menu {
    +    position: absolute;
    +    top: 0;
    +    left: 0;
    +    width: 31ex;
    +    overflow: hidden;
    +    }
    +.ContentPage .Firefox #Menu,
    +.IndexPage .Firefox #Menu {
    +    width: 27ex;
    +    }
    +
    +
    +    .MTitle {
    +        font-size: 16pt; font-weight: bold; font-variant: small-caps;
    +        text-align: center;
    +        padding: 5px 10px 15px 10px;
    +        border-bottom: 1px dotted #000000;
    +        margin-bottom: 15px }
    +
    +    .MSubTitle {
    +        font-size: 9pt; font-weight: normal; font-variant: normal;
    +        margin-top: 1ex; margin-bottom: 5px }
    +
    +
    +    .MEntry a:link,
    +    .MEntry a:hover,
    +    .MEntry a:visited { color: #606060; margin-right: 0 }
    +    .MEntry a:active { color: #A00000; margin-right: 0 }
    +
    +
    +    .MGroup {
    +        font-variant: small-caps; font-weight: bold;
    +        margin: 1em 0 1em 10px;
    +        }
    +
    +    .MGroupContent {
    +        font-variant: normal; font-weight: normal }
    +
    +    .MGroup a:link,
    +    .MGroup a:hover,
    +    .MGroup a:visited { color: #545454; margin-right: 10px }
    +    .MGroup a:active { color: #A00000; margin-right: 10px }
    +
    +
    +    .MFile,
    +    .MText,
    +    .MLink,
    +    .MIndex {
    +        padding: 1px 17px 2px 10px;
    +        margin: .25em 0 .25em 0;
    +        }
    +
    +    .MText {
    +        font-size: 8pt; font-style: italic }
    +
    +    .MLink {
    +        font-style: italic }
    +
    +    #MSelected {
    +        color: #000000; background-color: #FFFFFF;
    +        /*  Replace padding with border.  */
    +        padding: 0 10px 0 10px;
    +        border-width: 1px 2px 2px 0; border-style: solid; border-color: #000000;
    +        margin-right: 5px;
    +        }
    +
    +    /*  Close off the left side when its in a group.  */
    +    .MGroup #MSelected {
    +        padding-left: 9px; border-left-width: 1px }
    +
    +    /*  A treat for Mozilla users.  Blatantly non-standard.  Will be replaced with CSS 3 attributes when finalized/supported.  */
    +    .Firefox #MSelected {
    +        -moz-border-radius-topright: 10px;
    +        -moz-border-radius-bottomright: 10px }
    +    .Firefox .MGroup #MSelected {
    +        -moz-border-radius-topleft: 10px;
    +        -moz-border-radius-bottomleft: 10px }
    +
    +
    +    #MSearchPanel {
    +        padding: 0px 6px;
    +        margin: .25em 0;
    +        }
    +
    +
    +    #MSearchField {
    +        font: italic 9pt Verdana, sans-serif;
    +        color: #606060;
    +        background-color: #E8E8E8;
    +        border: none;
    +        padding: 2px 4px;
    +        width: 100%;
    +        }
    +    /* Only Opera gets it right. */
    +    .Firefox #MSearchField,
    +    .IE #MSearchField,
    +    .Safari #MSearchField {
    +        width: 94%;
    +        }
    +    .Opera9 #MSearchField,
    +    .Konqueror #MSearchField {
    +        width: 97%;
    +        }
    +    .FramedMenuPage .Firefox #MSearchField,
    +    .FramedMenuPage .Safari #MSearchField,
    +    .FramedMenuPage .Konqueror #MSearchField {
    +        width: 98%;
    +        }
    +
    +    /* Firefox doesn't do this right in frames without #MSearchPanel added on.
    +        It's presence doesn't hurt anything other browsers. */
    +    #MSearchPanel.MSearchPanelInactive:hover #MSearchField {
    +        background-color: #FFFFFF;
    +        border: 1px solid #C0C0C0;
    +        padding: 1px 3px;
    +        }
    +    .MSearchPanelActive #MSearchField {
    +        background-color: #FFFFFF;
    +        border: 1px solid #C0C0C0;
    +        font-style: normal;
    +        padding: 1px 3px;
    +        }
    +
    +    #MSearchType {
    +        visibility: hidden;
    +        font: 8pt Verdana, sans-serif;
    +        width: 98%;
    +        padding: 0;
    +        border: 1px solid #C0C0C0;
    +        }
    +    .MSearchPanelActive #MSearchType,
    +    /*  As mentioned above, Firefox doesn't do this right in frames without #MSearchPanel added on. */
    +    #MSearchPanel.MSearchPanelInactive:hover #MSearchType,
    +    #MSearchType:focus {
    +        visibility: visible;
    +        color: #606060;
    +        }
    +    #MSearchType option#MSearchEverything {
    +        font-weight: bold;
    +        }
    +
    +    .Opera8 .MSearchPanelInactive:hover,
    +    .Opera8 .MSearchPanelActive {
    +        margin-left: -1px;
    +        }
    +
    +
    +    iframe#MSearchResults {
    +        width: 60ex;
    +        height: 15em;
    +        }
    +    #MSearchResultsWindow {
    +        display: none;
    +        position: absolute;
    +        left: 0; top: 0;
    +        border: 1px solid #000000;
    +        background-color: #E8E8E8;
    +        }
    +    #MSearchResultsWindowClose {
    +        font-weight: bold;
    +        font-size: 8pt;
    +        display: block;
    +        padding: 2px 5px;
    +        }
    +    #MSearchResultsWindowClose:link,
    +    #MSearchResultsWindowClose:visited {
    +        color: #000000;
    +        text-decoration: none;
    +        }
    +    #MSearchResultsWindowClose:active,
    +    #MSearchResultsWindowClose:hover {
    +        color: #800000;
    +        text-decoration: none;
    +        background-color: #F4F4F4;
    +        }
    +
    +
    +
    +
    +#Content {
    +    padding-bottom: 15px;
    +    }
    +
    +.ContentPage #Content {
    +    border-width: 0 0 1px 1px;
    +    border-style: solid;
    +    border-color: #000000;
    +    background-color: #FFFFFF;
    +    font-size: 9pt;  /* To make 31ex match the menu's 31ex. */
    +    margin-left: 31ex;
    +    }
    +.ContentPage .Firefox #Content {
    +    margin-left: 27ex;
    +    }
    +
    +
    +
    +    .CTopic {
    +        font-size: 10pt;
    +        margin-bottom: 3em;
    +        }
    +
    +
    +    .CTitle {
    +        font-size: 12pt; font-weight: bold;
    +        border-width: 0 0 1px 0; border-style: solid; border-color: #A0A0A0;
    +        margin: 0 15px .5em 15px }
    +
    +    .CGroup .CTitle {
    +        font-size: 16pt; font-variant: small-caps;
    +        padding-left: 15px; padding-right: 15px;
    +        border-width: 0 0 2px 0; border-color: #000000;
    +        margin-left: 0; margin-right: 0 }
    +
    +    .CClass .CTitle,
    +    .CInterface .CTitle,
    +    .CDatabase .CTitle,
    +    .CDatabaseTable .CTitle,
    +    .CSection .CTitle {
    +        font-size: 18pt;
    +        color: #FFFFFF; background-color: #A0A0A0;
    +        padding: 10px 15px 10px 15px;
    +        border-width: 2px 0; border-color: #000000;
    +        margin-left: 0; margin-right: 0 }
    +
    +    #MainTopic .CTitle {
    +        font-size: 20pt;
    +        color: #FFFFFF; background-color: #7070C0;
    +        padding: 10px 15px 10px 15px;
    +        border-width: 0 0 3px 0; border-color: #000000;
    +        margin-left: 0; margin-right: 0 }
    +
    +    .CBody {
    +        margin-left: 15px; margin-right: 15px }
    +
    +
    +    .CToolTip {
    +        position: absolute; visibility: hidden;
    +        left: 0; top: 0;
    +        background-color: #FFFFE0;
    +        padding: 5px;
    +        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #000000;
    +        font-size: 8pt;
    +        }
    +
    +    .Opera .CToolTip {
    +        max-width: 98%;
    +        }
    +
    +    /*  Scrollbars would be useless.  */
    +    .CToolTip blockquote {
    +        overflow: hidden;
    +        }
    +    .IE6 .CToolTip blockquote {
    +        overflow: visible;
    +        }
    +
    +    .CHeading {
    +        font-weight: bold; font-size: 10pt;
    +        margin: 1.5em 0 .5em 0;
    +        }
    +
    +    .CBody pre {
    +        font: 10pt "Courier New", Courier, monospace;
    +	    background-color: #FCFCFC;
    +	    margin: 1em 35px;
    +	    padding: 10px 15px 10px 10px;
    +	    border-color: #E0E0E0 #E0E0E0 #E0E0E0 #E4E4E4;
    +	    border-width: 1px 1px 1px 6px;
    +	    border-style: dashed dashed dashed solid;
    +        }
    +
    +    .CBody ul {
    +        /*  I don't know why CBody's margin doesn't apply, but it's consistent across browsers so whatever.
    +             Reapply it here as padding.  */
    +        padding-left: 15px; padding-right: 15px;
    +        margin: .5em 5ex .5em 5ex;
    +        }
    +
    +    .CDescriptionList {
    +        margin: .5em 5ex 0 5ex }
    +
    +        .CDLEntry {
    +            font: 10pt "Courier New", Courier, monospace; color: #808080;
    +            padding-bottom: .25em;
    +            white-space: nowrap }
    +
    +        .CDLDescription {
    +            font-size: 10pt;  /*  For browsers that don't inherit correctly, like Opera 5.  */
    +            padding-bottom: .5em; padding-left: 5ex }
    +
    +
    +    .CTopic img {
    +        text-align: center;
    +        display: block;
    +        margin: 1em auto;
    +        }
    +    .CImageCaption {
    +        font-variant: small-caps;
    +        font-size: 8pt;
    +        color: #808080;
    +        text-align: center;
    +        position: relative;
    +        top: 1em;
    +        }
    +
    +    .CImageLink {
    +        color: #808080;
    +        font-style: italic;
    +        }
    +    a.CImageLink:link,
    +    a.CImageLink:visited,
    +    a.CImageLink:hover { color: #808080 }
    +
    +
    +
    +
    +
    +.Prototype {
    +    font: 10pt "Courier New", Courier, monospace;
    +    padding: 5px 3ex;
    +    border-width: 1px; border-style: solid;
    +    margin: 0 5ex 1.5em 5ex;
    +    }
    +
    +    .Prototype td {
    +        font-size: 10pt;
    +        }
    +
    +    .PDefaultValue,
    +    .PDefaultValuePrefix,
    +    .PTypePrefix {
    +        color: #8F8F8F;
    +        }
    +    .PTypePrefix {
    +        text-align: right;
    +        }
    +    .PAfterParameters {
    +        vertical-align: bottom;
    +        }
    +
    +    .IE .Prototype table {
    +        padding: 0;
    +        }
    +
    +    .CFunction .Prototype {
    +        background-color: #F4F4F4; border-color: #D0D0D0 }
    +    .CProperty .Prototype {
    +        background-color: #F4F4FF; border-color: #C0C0E8 }
    +    .CVariable .Prototype {
    +        background-color: #FFFFF0; border-color: #E0E0A0 }
    +
    +    .CClass .Prototype {
    +        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0;
    +        background-color: #F4F4F4;
    +        }
    +    .CInterface .Prototype {
    +        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0D0;
    +        background-color: #F4F4FF;
    +        }
    +
    +    .CDatabaseIndex .Prototype,
    +    .CConstant .Prototype {
    +        background-color: #D0D0D0; border-color: #000000 }
    +    .CType .Prototype,
    +    .CEnumeration .Prototype {
    +        background-color: #FAF0F0; border-color: #E0B0B0;
    +        }
    +    .CDatabaseTrigger .Prototype,
    +    .CEvent .Prototype,
    +    .CDelegate .Prototype {
    +        background-color: #F0FCF0; border-color: #B8E4B8 }
    +
    +    .CToolTip .Prototype {
    +        margin: 0 0 .5em 0;
    +        white-space: nowrap;
    +        }
    +
    +
    +
    +
    +
    +.Summary {
    +    margin: 1.5em 5ex 0 5ex }
    +
    +    .STitle {
    +        font-size: 12pt; font-weight: bold;
    +        margin-bottom: .5em }
    +
    +
    +    .SBorder {
    +        background-color: #FFFFF0;
    +        padding: 15px;
    +        border: 1px solid #C0C060 }
    +
    +    /* In a frame IE 6 will make them too long unless you set the width to 100%.  Without frames it will be correct without a width
    +        or slightly too long (but not enough to scroll) with a width.  This arbitrary weirdness simply astounds me.  IE 7 has the same
    +        problem with frames, haven't tested it without.  */
    +    .FramedContentPage .IE .SBorder {
    +        width: 100% }
    +
    +    /*  A treat for Mozilla users.  Blatantly non-standard.  Will be replaced with CSS 3 attributes when finalized/supported.  */
    +    .Firefox .SBorder {
    +        -moz-border-radius: 20px }
    +
    +
    +    .STable {
    +        font-size: 9pt; width: 100% }
    +
    +    .SEntry {
    +        width: 30% }
    +    .SDescription {
    +        width: 70% }
    +
    +
    +    .SMarked {
    +        background-color: #F8F8D8 }
    +
    +    .SDescription { padding-left: 2ex }
    +    .SIndent1 .SEntry { padding-left: 1.5ex }   .SIndent1 .SDescription { padding-left: 3.5ex }
    +    .SIndent2 .SEntry { padding-left: 3.0ex }   .SIndent2 .SDescription { padding-left: 5.0ex }
    +    .SIndent3 .SEntry { padding-left: 4.5ex }   .SIndent3 .SDescription { padding-left: 6.5ex }
    +    .SIndent4 .SEntry { padding-left: 6.0ex }   .SIndent4 .SDescription { padding-left: 8.0ex }
    +    .SIndent5 .SEntry { padding-left: 7.5ex }   .SIndent5 .SDescription { padding-left: 9.5ex }
    +
    +    .SDescription a { color: #800000}
    +    .SDescription a:active { color: #A00000 }
    +
    +    .SGroup td {
    +        padding-top: .5em; padding-bottom: .25em }
    +
    +    .SGroup .SEntry {
    +        font-weight: bold; font-variant: small-caps }
    +
    +    .SGroup .SEntry a { color: #800000 }
    +    .SGroup .SEntry a:active { color: #F00000 }
    +
    +
    +    .SMain td,
    +    .SClass td,
    +    .SDatabase td,
    +    .SDatabaseTable td,
    +    .SSection td {
    +        font-size: 10pt;
    +        padding-bottom: .25em }
    +
    +    .SClass td,
    +    .SDatabase td,
    +    .SDatabaseTable td,
    +    .SSection td {
    +        padding-top: 1em }
    +
    +    .SMain .SEntry,
    +    .SClass .SEntry,
    +    .SDatabase .SEntry,
    +    .SDatabaseTable .SEntry,
    +    .SSection .SEntry {
    +        font-weight: bold;
    +        }
    +
    +    .SMain .SEntry a,
    +    .SClass .SEntry a,
    +    .SDatabase .SEntry a,
    +    .SDatabaseTable .SEntry a,
    +    .SSection .SEntry a { color: #000000 }
    +
    +    .SMain .SEntry a:active,
    +    .SClass .SEntry a:active,
    +    .SDatabase .SEntry a:active,
    +    .SDatabaseTable .SEntry a:active,
    +    .SSection .SEntry a:active { color: #A00000 }
    +
    +
    +
    +
    +
    +.ClassHierarchy {
    +    margin: 0 15px 1em 15px }
    +
    +    .CHEntry {
    +        border-width: 1px 2px 2px 1px; border-style: solid; border-color: #A0A0A0;
    +        margin-bottom: 3px;
    +        padding: 2px 2ex;
    +        font-size: 10pt;
    +        background-color: #F4F4F4; color: #606060;
    +        }
    +
    +    .Firefox .CHEntry {
    +        -moz-border-radius: 4px;
    +        }
    +
    +    .CHCurrent .CHEntry {
    +        font-weight: bold;
    +        border-color: #000000;
    +        color: #000000;
    +        }
    +
    +    .CHChildNote .CHEntry {
    +        font-style: italic;
    +        font-size: 8pt;
    +        }
    +
    +    .CHIndent {
    +        margin-left: 3ex;
    +        }
    +
    +    .CHEntry a:link,
    +    .CHEntry a:visited,
    +    .CHEntry a:hover {
    +        color: #606060;
    +        }
    +    .CHEntry a:active {
    +        color: #800000;
    +        }
    +
    +
    +
    +
    +
    +#Index {
    +    background-color: #FFFFFF;
    +    }
    +
    +/*  As opposed to .PopupSearchResultsPage #Index  */
    +.IndexPage #Index,
    +.FramedIndexPage #Index,
    +.FramedSearchResultsPage #Index {
    +    padding: 15px;
    +    }
    +
    +.IndexPage #Index {
    +    border-width: 0 0 1px 1px;
    +    border-style: solid;
    +    border-color: #000000;
    +    font-size: 9pt;  /* To make 27ex match the menu's 27ex. */
    +    margin-left: 27ex;
    +    }
    +
    +
    +    .IPageTitle {
    +        font-size: 20pt; font-weight: bold;
    +        color: #FFFFFF; background-color: #7070C0;
    +        padding: 10px 15px 10px 15px;
    +        border-width: 0 0 3px 0; border-color: #000000; border-style: solid;
    +        margin: -15px -15px 0 -15px }
    +
    +    .FramedSearchResultsPage .IPageTitle {
    +        margin-bottom: 15px;
    +        }
    +
    +    .INavigationBar {
    +        font-size: 10pt;
    +        text-align: center;
    +        background-color: #FFFFF0;
    +        padding: 5px;
    +        border-bottom: solid 1px black;
    +        margin: 0 -15px 15px -15px;
    +        }
    +
    +    .INavigationBar a {
    +        font-weight: bold }
    +
    +    .IHeading {
    +        font-size: 16pt; font-weight: bold;
    +        padding: 2.5em 0 .5em 0;
    +        text-align: center;
    +        width: 3.5ex;
    +        }
    +    #IFirstHeading {
    +        padding-top: 0;
    +        }
    +
    +    .IEntry {
    +        font-size: 10pt;
    +        padding-left: 1ex;
    +        }
    +    .PopupSearchResultsPage .IEntry {
    +        font-size: 8pt;
    +        padding: 1px 5px;
    +        }
    +    .PopupSearchResultsPage .Opera9 .IEntry,
    +    .FramedSearchResultsPage .Opera9 .IEntry {
    +        text-align: left;
    +        }
    +    .FramedSearchResultsPage .IEntry {
    +        padding: 0;
    +        }
    +
    +    .ISubIndex {
    +        padding-left: 3ex; padding-bottom: .5em }
    +    .PopupSearchResultsPage .ISubIndex {
    +        display: none;
    +        }
    +
    +    /*  While it may cause some entries to look like links when they aren't, I found it's much easier to read the
    +         index if everything's the same color.  */
    +    .ISymbol {
    +        font-weight: bold; color: #900000  }
    +
    +    .IndexPage .ISymbolPrefix,
    +    .FramedIndexPage .ISymbolPrefix {
    +        font-size: 10pt;
    +        text-align: right;
    +        color: #C47C7C;
    +        background-color: #F8F8F8;
    +        border-right: 3px solid #E0E0E0;
    +        border-left: 1px solid #E0E0E0;
    +        padding: 0 1px 0 2px;
    +        }
    +    .PopupSearchResultsPage .ISymbolPrefix,
    +    .FramedSearchResultsPage .ISymbolPrefix {
    +        color: #900000;
    +        }
    +    .PopupSearchResultsPage .ISymbolPrefix {
    +        font-size: 8pt;
    +        }
    +
    +    .IndexPage #IFirstSymbolPrefix,
    +    .FramedIndexPage #IFirstSymbolPrefix {
    +        border-top: 1px solid #E0E0E0;
    +        }
    +    .IndexPage #ILastSymbolPrefix,
    +    .FramedIndexPage #ILastSymbolPrefix {
    +        border-bottom: 1px solid #E0E0E0;
    +        }
    +    .IndexPage #IOnlySymbolPrefix,
    +    .FramedIndexPage #IOnlySymbolPrefix {
    +        border-top: 1px solid #E0E0E0;
    +        border-bottom: 1px solid #E0E0E0;
    +        }
    +
    +    a.IParent,
    +    a.IFile {
    +        display: block;
    +        }
    +
    +    .PopupSearchResultsPage .SRStatus {
    +        padding: 2px 5px;
    +        font-size: 8pt;
    +        font-style: italic;
    +        }
    +    .FramedSearchResultsPage .SRStatus {
    +        font-size: 10pt;
    +        font-style: italic;
    +        }
    +
    +    .SRResult {
    +        display: none;
    +        }
    +
    +
    +
    +#Footer {
    +    font-size: 8pt;
    +    color: #989898;
    +    text-align: right;
    +    }
    +
    +#Footer p {
    +    text-indent: 0;
    +    margin-bottom: .5em;
    +    }
    +
    +.ContentPage #Footer,
    +.IndexPage #Footer {
    +    text-align: right;
    +    margin: 2px;
    +    }
    +
    +.FramedMenuPage #Footer {
    +    text-align: center;
    +    margin: 5em 10px 10px 10px;
    +    padding-top: 1em;
    +    border-top: 1px solid #C8C8C8;
    +    }
    +
    +    #Footer a:link,
    +    #Footer a:hover,
    +    #Footer a:visited { color: #989898 }
    +    #Footer a:active { color: #A00000 }
    +
    +
    +
    +.prettyprint .kwd { color: #800000; }  /* keywords */
    +
    +    .prettyprint.PDefaultValue .kwd,
    +    .prettyprint.PDefaultValuePrefix .kwd,
    +    .prettyprint.PTypePrefix .kwd {
    +        color: #C88F8F;
    +        }
    +
    +.prettyprint .com { color: #008000; }  /* comments */
    +
    +    .prettyprint.PDefaultValue .com,
    +    .prettyprint.PDefaultValuePrefix .com,
    +    .prettyprint.PTypePrefix .com {
    +        color: #8FC88F;
    +        }
    +
    +.prettyprint .str { color: #0000B0; }  /* strings */
    +.prettyprint .lit { color: #0000B0; }  /* literals */
    +
    +    .prettyprint.PDefaultValue .str,
    +    .prettyprint.PDefaultValuePrefix .str,
    +    .prettyprint.PTypePrefix .str,
    +    .prettyprint.PDefaultValue .lit,
    +    .prettyprint.PDefaultValuePrefix .lit,
    +    .prettyprint.PTypePrefix .lit {
    +        color: #8F8FC0;
    +        }
    +
    +.prettyprint .typ { color: #000000; }  /* types */
    +.prettyprint .pun { color: #000000; }  /* punctuation */
    +.prettyprint .pln { color: #000000; }  /* punctuation */
    +
    +    .prettyprint.PDefaultValue .typ,
    +    .prettyprint.PDefaultValuePrefix .typ,
    +    .prettyprint.PTypePrefix .typ,
    +    .prettyprint.PDefaultValue .pun,
    +    .prettyprint.PDefaultValuePrefix .pun,
    +    .prettyprint.PTypePrefix .pun,
    +    .prettyprint.PDefaultValue .pln,
    +    .prettyprint.PDefaultValuePrefix .pln,
    +    .prettyprint.PTypePrefix .pln {
    +        color: #8F8F8F;
    +        }
    +
    +.prettyprint .tag { color: #008; }
    +.prettyprint .atn { color: #606; }
    +.prettyprint .atv { color: #080; }
    +.prettyprint .dec { color: #606; }
    +
    diff --git a/mkdocu.sh b/mkdocu.sh
    index 3f06062..bc38261 100755
    --- a/mkdocu.sh
    +++ b/mkdocu.sh
    @@ -1,5 +1,12 @@
     #!/usr/bin/env bash
     
    +if ! ndpath=$(which NaturalDocs 2>/dev/null); then
    +if ! ndpath=$(which naturaldocs 2>/dev/null); then
    +echo "NaturalDocs could not be found!" >/dev/stderr
    +exit 1
    +fi; fi
    +
    +
     if [ ! -d docu/nd ]; then mkdir docu/nd; fi
     if [ ! -d docu/nd_project_dir ]; then mkdir docu/nd_project_dir; fi
    -NaturalDocs -i . -o html docu/nd -p docu/nd_project_dir
    +$ndpath -i . -o html docu/nd -p docu/nd_project_dir
    -- 
    cgit v1.2.3-70-g09d2