/
ColdCore-3.0a7/
object $root;

var $root manager = $root;
var $root trusted = [];
var $root child_index = 21;
var $root fertile = 1;
var $root inited = 0;
var $root quota = 75000;
var $root managed = 0;
var $root writers = [$root];
var $root created_on = 0;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root quota_exempt = 0;
var $root writes = 0;
var $root trusted_by = 0;
var $root help_node = 0;
var $root settings = 0;
var $root defined_settings = #[];

root method .init_root(): nooverride {
    .change_manager(this());
    flags = ['variables, 'methods, 'code];
    created_on = time();
};

root method .uninit_root(): nooverride {
    var obj;
    
    (| manager.del_managed_obj() |);
    catch any {
        for obj in (.managed())
            obj.change_manager($reaper);
    }
    catch any {
        for obj in (.writers('literal))
            .del_writer(obj);
    }
    catch any {
        for obj in (.writes())
            obj.del_writer(this());
    }
    catch any {
        for obj in (.trusted('literal))
            .del_trusted(obj);
    }
    catch any {
        for obj in (.trusted_by())
            obj.del_trusted(this());
    }
    
    // tell $sys we are going away
    $sys.sender_going_away();
};

public method .initialize(): nooverride {
    var ancestors, pos, len, method, a, def;
    
    if ((caller() != $sys) && (sender() != this()))
        throw(~perm, "Caller is not $sys and sender is not this.");
    if (inited)
        throw(~perm, "Already initialized.");
    ancestors = ancestors();
    len = ancestors.length();
    for pos in [0 .. len - 1] {
        refresh();
        a = ancestors[len - pos];
        if (!(method = (| tosym("init_" + tostr(a.objname())) |)))
            continue;
        if ((def = (| find_method(method) |))) {
            if (def != a) {
                (| (def.manager()).tell(((("Uninitialization method for " + a) + " in wrong place (") + find_method(method)) + ")") |);
            } else {
                catch any {
                    .(method)();
                } with {
                    if (def) {
                        (| (def.manager()).tell(((("UNINIT ERROR " + this()) + "<") + def) + ">:") |);
                        (| (def.manager()).tell_traceback(traceback()) |);
                    }
                }
            }
        }
    }
    inited = 1;
};

public method .uninitialize(): nooverride {
    var a, v, d, def, method, objs;
    
    (> .perms(caller(), $root, $sys) <);
    objs = (.descendants()) + [this()];
    for a in (ancestors()) {
        pause();
        if (!(method = tosym("uninit_" + tostr(a.objname()))))
            continue;
        if ((def = (| find_method(method) |))) {
            if (def != a) {
                (| (def.manager()).tell(((("Uninitialization method for " + a) + " in wrong place (") + find_method(method)) + ")") |);
                continue;
            }
            for d in (objs) {
                pause();
                catch any {
                    d.(method)();
                } with {
                    if (def) {
                        (| (def.manager()).tell(((("UNINIT ERROR " + this()) + "<") + def) + ">:") |);
                        (| (def.manager()).tell_traceback(traceback()) |);
                        (| sender().tell_traceback(traceback()) |);
                    }
                }
            }
            $sys.clear_definer_vars(a, objs);
        }
    }
};

public method .perms(): nooverride {
    arg what, @args;
    var flag;
    
    if (!args)
        args = ['writer];
    if (type(args[1]) == 'symbol) {
        switch (args[1]) {
            case 'system:
                if (!($sys.is_system(what)))
                    throw(~perm, ("Permission Denied: " + what) + " is not of the system.", what);
            case 'manager:
                if (((.manager()) != what) && (!($sys.is_system(what))))
                    throw(~perm, ("Permission Denied: " + what) + " is not the manager.", what);
            case 'trusts:
                if (!(.trusts(what)))
                    throw(~perm, ("Permission Denied: " + what) + " is not a trustee.", what);
            case 'command:
                if ((what != $user) && (what != $body))
                    throw(~perm, what + " is not a valid command invoking object.");
            default:
                if (!(.is_writable_by(what)))
                    throw(~perm, ("Permission Denied: " + what) + " is not a writer.", what);
        }
    } else if (type(what) == 'objnum) {
        if (!(what in args))
            throw(~perm, (what + " is not one of: ") + ((args.mmap('namef, 'ref)).to_english()), what);
    }
};

public method .chparents() {
    arg @parents;
    var parent, cur;
    
    if (!(| .perms(sender(), 'manager) |))
        (> .perms(caller(), $root, $sys) <);
    if (!parents)
        throw(~noparents, "There must be at least 1 parent for each object.");
    
    // Notify new parents of impending change.
    cur = parents();
    for parent in (parents) {
        if (!(parent in cur))
            (> parent.will_inherit(sender()) <);
    }
    
    // Everything's okay, go ahead and try it.
    .change_parents(parents);
};

public method .will_inherit(): nooverride {
    arg who;
    
    if (this() in (sender().parents()))
        throw(~perm, ((sender() + " already has ") + this()) + " as a parent.");
    if ((!(.has_flag('fertile, sender()))) && (!(.trusts(who))))
        throw(~perm, ((this() + " refuses to be parent of ") + sender()) + ".");
};

public method .manager(): nooverride {
    return manager || $reaper;
};

public method .writers(): nooverride {
    arg @literal;
    
    if (literal)
        return writers || [];
    
    // for speed, just add rather than setadd, use .compress() later if necessary
    return (writers || []) + [.manager(), this()];
};

public method .trusted(): nooverride {
    arg @literal;
    
    if (literal)
        return trusted || [];
    return (trusted || []) + (.writers());
};

public method .is_writable_by(): nooverride {
    arg obj;
    
    return (| obj in (.writers()) |) || ($sys.is_system(obj));
};

public method .trusts(): nooverride {
    arg obj;
    
    return (| obj in (.trusted()) |) || ((obj == $scheduler) || ($sys.is_system(obj)));
};

public method .change_manager(): nooverride {
    arg new;
    var old;
    
    if ((caller() != definer()) && (!($sys.is_system(sender()))))
        throw(~perm, "You must have system privileges to change the manager.");
    if (type(new) != 'objnum)
        throw(~invarg, "Managers must be given as a single dbref.");
    old = .manager();
    manager = new;
    old.del_managed_obj();
    new.add_managed_obj();
};

public method .add_writer(): nooverride {
    arg obj;
    
    (> .perms(sender(), 'manager) <);
    writers = (writers || []).setadd(obj);
    obj.add_writable_obj();
};

public method .del_writer(): nooverride {
    arg obj;
    
    (caller() == definer()) || (> .perms(sender(), 'manager) <);
    writers = (writers || []).setremove(obj);
    if (!writers)
        (| clear_var('writers) |);
    obj.del_writable_obj();
};

public method .add_trusted(): nooverride {
    arg obj;
    
    (caller() == definer()) || (> .perms(sender(), 'manager) <);
    trusted = (trusted || []).setadd(obj);
    obj.add_trusted_obj();
};

public method .del_trusted(): nooverride {
    arg obj;
    
    (> .perms(sender(), 'manager) <);
    trusted = (trusted || []).setremove(obj);
    if (!trusted)
        clear_var('trusted);
    obj.del_trusted_obj();
};

public method .as_this_run() {
    arg obj, method, args;
    
    if (caller() != $scheduler)
        throw(~perm, "Sender not allowed to gain access to object perms.");
    return (> obj.(method)(@args) <);
};

public method .add_parent() {
    arg parent;
    
    (> .perms(sender(), 'manager) <);
    (> parent.will_inherit(sender()) <);
    if (.has_ancestor(parent))
        throw(~perm, ((sender() + " already has ") + this()) + " as an ancestor.");
    .change_parents(parents() + [parent]);
};

public method .del_parent() {
    arg parent;
    var parents;
    
    (> .perms(sender(), 'manager) <);
    if (!valid(parent))
        throw(~type, "Not a valid parent, must send a valid object.");
    parents = .parents();
    if (!(parent in parents))
        throw(~parentnf, ((parent + " is not a parent of ") + this()) + ".");
    parents = parents.setremove(parent);
    (> .change_parents(parents) <);
};

public method .spawn(): nooverride {
    arg @suffix;
    var obj, tmp, objname, mngr, na;
    
    (> .will_spawn(sender()) <);
    suffix = (> .get_obj_suffix(@suffix) <);
    return $sys.spawn_sender(suffix, sender());
};

public method .destroy(): nooverride {
    // This doesn't actually destroy us immediately, but we will go away when
    // nothing is holding onto us any more.
    (> .perms(sender(), 'manager) <);
    if (.has_flag('core))
        throw(~perm, "This object is a core object, and cannot be destroyed!");
    (> .uninitialize() <);
    destroy();
};

public method .add_var() {
    arg name, @args;
    var tmp, kid;
    
    (> .perms(sender()) <);
    if (!(tostr(name).valid_ident()))
        throw(~invident, name + " is not a valid ident.");
    (> add_var(name) <);
    
    // The following code is a kludge as we can't send a default value to the
    // primitive.
    if (args) {
        tmp = tosym((("__set_" + tostr(name)) + "_") + time());
        catch any {
            add_method([((tostr(name) + " = ") + toliteral(args[1])) + ";"], tmp);
            .(tmp)();
            if (((args.length()) > 1) && ((args[2]) == 'inherit)) {
                for kid in (.descendants())
                    kid.(tmp)();
            }
            del_method(tmp);
        } with {
            del_method(tmp);
            rethrow(error());
        }
    }
    
    // $#Edited: 08 Jan 96 09:34 Lynx ($lynx)
};

public method .variables(): nooverride {
    return variables();
};

public method .del_var(): nooverride {
    arg name;
    var n, obj;
    
    (caller() == definer()) || (> .perms(sender()) <);
    
    // try and clear the variable on all of the descendants, before deleting
    // the variable...
    (> .clear_variable(name) <);
    
    // now delete the variable
    (> del_var(name) <);
};

public method .del_method() {
    arg name;
    
    (> .perms(sender()) <);
    (> del_method(name) <);
};

public method .methods(): nooverride {
    if (!(.has_flag('methods, sender())))
        throw(~perm, (sender() + " doesn't have permission to find methods on ") + this());
    return methods();
};

public method .parents(): nooverride {
    return parents();
};

public method .children(): nooverride {
    return children();
};

public method .ancestors(): nooverride {
    return ancestors();
};

public method .find_method(): nooverride {
    arg name;
    
    if (!(.has_flag('methods, sender())))
        throw(~perm, (sender() + " doesn't have permission to find methods on ") + this());
    return (> find_method(name) <);
};

public method .find_next_method(): nooverride {
    arg name, after;
    
    if (!(.has_flag('methods, sender())))
        throw(~perm, (sender() + " doesn't have permission to find methods on ") + this());
    return (> find_next_method(name, after) <);
};

private method .corify_descendants_of(): nooverride {
    arg obj;
    var d, name, l;
    
    name = (| tosym("core_" + (obj.objname())) |);
    catch ~methodnf {
        if ((> obj.find_method(name) <) != obj) {
            $sys.log(((("** Coremethod for " + obj) + " in wrong place (on ") + (obj.find_method(name))) + ") **");
            return;
        }
    } with {
        return;
    }
    (| obj.(name)() |);
    for d in (obj.descendants()) {
        catch any {
            (> d.(name)() <);
        } with {
            $sys.log(((("ERROR encountered in " + d) + ".") + name) + "():");
            for l in ($parse_lib.traceback(traceback()))
                $sys.log(l);
        }
        refresh();
    }
};

public method .add_method() {
    arg code, name;
    var l, m, line;
    
    (> .perms(sender()) <);
    (| $sys.touch() |);
    
    // check for a few things only admins can do
    if (!(sender().is($admin))) {
        for l in [1 .. listlen(code)] {
            line = code[l];
            if ((m = line.match_regexp("[^a-z0-9_.]anticipate_assignment\("))) {
                (> sender().tell($code_lib.point_to_line("ERROR: call to anticipate_assignment()", ((m[1])[1]) + 2, ((m[1])[2]) - 2, l, line)) <);
                throw(~perm, "anticipate_assignment() may only be used by an administrator.");
            }
        }
    }
    return (> add_method(code, name) <);
};

public method .has_ancestor(): nooverride {
    arg obj;
    
    return (> has_ancestor(obj) <);
};

public method .eval(): nooverride {
    arg code, @dest;
    var errors, result, method;
    
    dest = dest ? dest[1] : this();
    if (!(sender() in [$scheduler, $root]))
        (> .perms(sender()) <);
    
    // Compile the code.
    method = tosym("tmp_eval_" + tostr(time()));
    errors = .add_method(code, method);
    if (errors)
        return ['errors, errors, 0, 0];
    
    // Evaluate the expression.  Be sure to remove it afterwards, so that no
    // one else can call it.
    catch any {
        result = (> dest.(method)() <);
    } with {
        (| del_method(method) |);
        rethrow(error());
    }
    (| del_method(method) |);
    return ['result, result];
    
    // $#Edited: 06 Jan 96 14:58 Lynx ($lynx)
};

public method .method_info(): nooverride {
    arg @args;
    
    return (> method_info(@args) <);
};

public method .data(): nooverride {
    arg @parent;
    var par, data, out;
    
    if (!(.has_flag('variables, sender())))
        throw(~perm, ((sender().namef('ref)) + " is not allowed to read variables on ") + (.namef('ref)));
    if (parent) {
        if (type(parent[1]) != 'objnum)
            throw(~type, (parent[1]) + " is not an object.");
        return (> data(parent[1]) <);
    } else {
        data = (> data() <);
        out = #[];
        for par in (data) {
            // if the parent doesn't exist anymore, just let them see the data.
            if ((!valid(par[1])) || ((par[1]).has_flag('variables, sender())))
                out = out.add(par[1], par[2]);
            else
                out = out.add(par[1], ["*** Permission Denied ***"]);
        }
        return out;
    }
};

public method .size(): nooverride {
    arg @args;
    
    [(args ?= 'int)] = args;
    switch (args) {
        case 'string:
            return tostr(size());
        case 'english:
            return size().to_english();
        default:
            return size();
    }
};

public method .descendants(): nooverride {
    var kids, i, c, child, d;
    
    d = #[];
    for child in (children())
        d = dict_add(d, child, 1);
    while ((| (c = dict_keys(d)[++i]) |)) {
        for child in (c.children()) {
            pause();
            d = dict_add(d, child, 1);
        }
        pause();
    }
    return dict_keys(d);
};

public method .get_quota(): nooverride {
    return quota;
};

public method .quota_valid(): nooverride {
    if (quota_exempt)
        return 1;
    if (!(.is($user)))
        return 0;
    return (.quota_byte_usage()) < (.quota());
};

public method .match_children() {
    arg string;
    var children, child_names, c;
    
    children = .children();
    child_names = children.mmap('name);
    
    // direct matches first.
    for c in (child_names) {
        if (c == string)
            return children[c in child_names];
    }
    
    // ok, try partial matches
    for c in (child_names) {
        if ($string.match_begin(c, string))
            return children[c in child_names];
    }
    return 0;
};

public method .del_flag(): nooverride {
    arg flag;
    
    (> .perms(sender(), 'manager) <);
    
    // let them add any flag they want
    flags = (flags || []).setremove(flag);
};

public method ._display_descendants() {
    arg space, checked, levels, maxlev;
    var c, anc, list, id, perms;
    
    id = ((space + this()) + " ") + ($object_lib.see_perms(this()));
    for anc in (dict_keys(checked)) {
        if (.has_ancestor(anc))
            return [];
    
        // [id + "  (above)"];
    }
    if (((.parents()).length()) > 1)
        id += " (MI)";
    list = [id];
    space += "  ";
    levels++;
    
    // check children
    if ((!maxlev) || (maxlev != levels)) {
        for c in (.children()) {
            list += c._display_descendants(space, checked, levels, maxlev);
            checked = dict_add(checked, c, 1);
            pause();
        }
    }
    return list;
};

public method ._get_method_info(): nooverride {
    arg anc, method;
    var code, lines, dis_flag, meth_args, flags, first_comment;
    
    code = anc.list_method(method);
    lines = code.length();
    if (lines > 5)
        code = code.subrange(1, 5);
    flags = anc.method_flags(method);
    if (code) {
        meth_args = regexp(code[1], "arg ([^;]);");
        if (meth_args) {
            meth_args = meth_args[1];
            code = code.delete(1);
        } else {
            meth_args = "";
        }
        if (code && ((!(code[1])) || (((code[1])[1]) == "v")))
            code = code.delete(1);
        if (code && ((!(code[1])) || (((code[1])[1]) == "v")))
            code = code.delete(1);
        first_comment = code ? (code[1]) + " " : " ";
        first_comment = (((first_comment[1]) == "/") || ((first_comment[1]) == "r")) ? first_comment : "";
    } else {
        meth_args = "";
        first_comment = "";
    }
    return [anc, method, meth_args, flags, lines, first_comment];
};

public method .namef() {
    arg type;
    
    return tostr(this());
    
    // $# Edited 28 Oct 1995 21:06 Lynx ($lynx)
};

public method .match_descendants() {
    arg string;
    var match, child;
    
    match = .match_children(string);
    if (match)
        return match;
    for child in (.children()) {
        match = child.match_descendants(string);
        if (match)
            return match;
    }
    return 0;
};

public method .debug() {
    arg @stuff;
    var x, line, mngr, meth;
    
    meth = (| (stack()[2])[3] |);
    if (meth)
        line = ((("DEBUG " + sender()) + ".") + meth) + "(): ";
    else
        line = ("DEBUG " + sender()) + ": ";
    for x in (stuff)
        line = (line + " ") + toliteral(x);
    (| (.manager()).tell(line) |);
    
    // $#Edited: 13 Jun 96 01:13 $levi
};

public method .set_quota(): nooverride {
    arg value;
    
    (> .perms(caller(), $user, @$sys.system(), $root) <);
    quota = value;
};

public method .name() {
    arg @args;
    
    return tostr(this());
};

public method .quota(): nooverride {
    return quota;
};

public method .quota_byte_usage(): nooverride {
    var total, obj;
    
    for obj in (.managed()) {
        if (!valid(obj))
            continue;
        total += obj.size();
    }
    return total;
};

public method .corify(): nooverride {
    var d;
    
    if (sender() != $sys)
        throw(~sysonly, "This should only be called by $sys.make_core().");
    
    // reverse engineer it--if coreify_<object> exists,
    // call it on this object and all of its descendants.
    for d in (.descendants()) {
        .corify_descendants_of(d);
        refresh();
    }
};

root method .change_parents(): nooverride {
    arg parents;
    var old_a, old_p, p, o, a, new_a, m, def, objs, d;
    
    // NOTE: add a system at some point for queing messages to a
    // user when they aren't connected (so the tell's below will be seen)
    if (!parents)
        throw(~noparents, "Objects must have at least 1 parent");
    
    // remember the old ancestors and parents
    old_a = ancestors();
    old_p = .parents();
    
    // build the new ancestors list by hand, so we can uninit befor changing
    new_a = [this(), @parents];
    for p in (parents)
        new_a = new_a.union(p.ancestors());
    
    // uninit any old parents
    objs = (.descendants()) + [this()];
    for a in (old_a.set_difference(new_a)) {
        pause();
        if (!(m = tosym("uninit_" + tostr(a.objname()))))
            continue;
        if ((def = (| find_method(m) |))) {
            if (def != a) {
                (| (def.manager()).tell(((("Uninitialization method for " + a) + " in wrong place (") + find_method(m)) + ")") |);
                continue;
            }
            for d in (objs) {
                pause();
                catch any {
                    d.(m)();
                } with {
                    if (def) {
                        (| (def.manager()).tell(((("UNINIT ERROR " + this()) + "<") + def) + ">:") |);
                        (| (def.manager()).tell_traceback(traceback()) |);
                    }
                }
            }
            $sys.clear_definer_vars(a, objs);
        }
    }
    
    // do the change
    (> chparents(parents) <);
    
    // init new
    for a in (ancestors().set_difference(old_a)) {
        if (!(m = tosym("init_" + tostr(a.objname()))))
            continue;
        if ((def = (| find_method(m) |))) {
            if (def != a) {
                (| (def.manager()).tell(((("Initialization method for " + a) + " in wrong place (") + find_method(m)) + ")") |);
                continue;
            }
            for d in (objs) {
                pause();
                catch any {
                    d.(m)();
                } with {
                    if (def) {
                        (| (def.manager()).tell(((("INIT ERROR " + this()) + "<") + def) + ">:") |);
                        (| (def.manager()).tell_traceback(traceback()) |);
                    }
                }
            }
        }
    }
};

public method .objname(): nooverride {
    return (> objname() <);
};

public method .set_objname() {
    arg objname;
    
    (> .perms(sender()) <);
    if (.has_flag('core))
        throw(~perm, this() + " is a core object; you cannot change its object name!");
    
    // Make sure first argument is a symbol.
    if (type(objname) != 'symbol)
        throw(~type, "New objname is not a symbol.");
    
    // Make sure everything is lowercase.
    objname = tosym(tostr(objname).lowercase());
    
    // Do nothing if objname isn't different.
    if (objname == (| objname() |))
        return;
    return (> set_objname(objname) <);
};

public method .created_on(): nooverride {
    return created_on;
};

public method .is_of(): nooverride {
    arg obj;
    
    return obj in ancestors();
};

public method .is(): nooverride {
    arg @args;
    
    if (!args)
        throw(~invarg, "Must have one argument.");
    if (type(args[1]) == 'dictionary)
        return has_ancestor(args[2]);
    return has_ancestor(args[1]);
};

public method .hname() {
    arg @args;
    
    return ((("<a href=\"/bin/display?" + this()) + "\">") + this()) + "</a>";
};

public method .add_flag(): nooverride {
    arg flag;
    
    (> .perms(sender(), 'manager) <);
    if ((flag == 'core) && (!($sys.is_system(sender()))))
        throw(~perm, "Only system objects can set the 'core flag.");
    (flag == 'fertile) && (> .perms(sender(), 'manager) <);
    
    // let them add any flag they want
    flags = (flags || []).setadd(flag);
};

public method .build_name() {
    arg @args;
    var output, type, part, rval;
    
    output = "";
    for part in (args) {
        type = type(part);
        if (type == 'list)
            output += (| .(part[1])(@part.subrange(2)) |) || "";
        else if (type == 'string)
            output += part;
    }
    return output;
    
    // $#Edited: 30 Nov 96 20:00 $miro
};

public method .clear_variable(): nooverride {
    arg name;
    var n, obj;
    
    (> .perms(sender()) <);
    n = tosym("_clear_var_" + tostr(time()));
    catch any {
        .add_method([("clear_var(" + toliteral(name)) + ");"], n);
        for obj in (.descendants()) {
            (| obj.(n)() |);
            pause();
        }
        (| del_method(n) |);
    } with {
        (| del_method(n) |);
    }
};

public method .ancestors_to(): nooverride {
    arg checked, levels, maxlev;
    var c, list;
    
    list = [this()];
    levels++;
    
    // check parents
    if ((!maxlev) || (maxlev != levels)) {
        for c in (.parents()) {
            list += [c.ancestors_to(checked, levels, maxlev)];
            checked = checked.setadd(c);
        }
    }
    return list;
};

public method .descendants_to(): nooverride {
    arg checked, levels, maxlev;
    var c, list;
    
    list = [this()];
    levels++;
    
    // check parents
    if ((!maxlev) || (maxlev != levels)) {
        for c in (.children()) {
            list += [c.descendants_to(checked, levels, maxlev)];
            checked = checked.setadd(c);
        }
    }
    return list;
};

public method .ancestry(): nooverride {
    arg gen;
    var i, out;
    
    out = [];
    if (type(gen) == 'objnum) {
        for i in (.ancestors()) {
            if (i.has_ancestor(gen))
                out += [i];
        }
        return out;
    }
    if (gen != 0) {
        for i in (.parents())
            out = out.union(i.ancestry(gen - 1));
    }
    return out;
    
    // $#Edited: 22 Nov 96 17:42 $miro
};

public method .generations(): nooverride {
    arg gen;
    var p, out;
    
    out = [this()];
    if (gen != 0) {
        for p in (.parents())
            out = out.union(p.generations(gen - 1));
    }
    return out;
};

public method .variable_info() {
    arg gen, def, fltr, match;
    var ancs, data, pp, p;
    
    if (!(.has_flag('variables, sender())))
        throw(~perm, (sender() + " cannot read variables on ") + this());
    if (def)
        ancs = [def];
    else
        ancs = .(gen[1])(gen[2]) || [this()];
    data = [];
    for pp in ((data().to_list()).reverse()) {
        if (valid(pp[1]) && ((pp[1]) in ancs)) {
            for p in (pp[2]) {
                if (tostr(p[1]).(match)(fltr) != 0)
                    data += [[pp[1], @p]];
            }
        }
    }
    return data;
    
    // $#Edited: 22 Nov 96 17:42 $miro
};

public method .method_flags(): nooverride {
    arg method;
    
    if (!(.has_flag('methods, sender())))
        throw(~perm, (sender() + " doesn't have permission to find methods on ") + this());
    return (> method_flags(method) <);
};

public method .method_access(): nooverride {
    arg method;
    
    if (!(.has_flag('methods, sender())))
        throw(~perm, (sender() + " doesn't have permission to find methods on ") + this());
    return (> method_access(method) <);
};

public method .set_method_flags(): nooverride {
    arg method, flags;
    
    if (!(.is_writable_by(sender())))
        throw(~perm, (sender() + " cannot write to ") + this());
    if (('locked in flags) && (!($sys.is_system(sender()))))
        throw(~perm, "Only administrators can set the locked method flag.");
    return (> set_method_flags(method, flags) <);
};

public method .set_method_access(): nooverride {
    arg method, state;
    
    if (!(.is_writable_by(sender())))
        throw(~perm, (sender() + " cannot write to ") + this());
    return (> set_method_access(method, state) <);
};

public method .set_flags(): nooverride {
    arg new_flags;
    
    (> .perms(sender(), 'manager) <);
    if (type(new_flags) != 'list)
        throw(~invflags, "Flags must be submitted as a list of symbols.");
    if ((!new_flags) && flags)
        return clear_var('flags);
    if (('core in new_flags) && (!($sys.is_system(sender()))))
        throw(~perm, "Only system objects can set the 'core flag.");
    ('fertile in new_flags) && (> .perms(sender(), 'manager) <);
    flags = new_flags;
};

public method .managed(): nooverride {
    return managed || [];
};

root method .add_managed_obj(): nooverride {
    managed = (managed || []).setadd(sender());
};

root method .del_managed_obj(): nooverride {
    managed = (managed || []).setremove(sender());
    if (!managed)
        clear_var('managed);
};

public method .writes(): nooverride {
    (> .perms(sender(), 'trusts) <);
    return writes || [];
};

root method .add_writable_obj(): nooverride {
    writes = (writes || []).setadd(sender());
};

root method .del_writable_obj(): nooverride {
    writes = (writes || []).setremove(sender());
    if (!writes)
        clear_var('writes);
};

public method .trusted_by(): nooverride {
    return trusted_by || [];
};

root method .add_trusted_obj(): nooverride {
    trusted_by = (trusted_by || []).setadd(sender());
};

root method .del_trusted_obj(): nooverride {
    trusted_by = (trusted_by || []).setremove(sender());
    if (!trusted_by)
        clear_var('trusted_by);
};

public method .has_flag(): nooverride {
    arg flag, @sender;
    
    [(sender ?= sender())] = sender;
    if (flag == 'core)
        return flag in (.flags());
    return (flag in (.flags())) || (.trusts(sender));
};

public method .flags(): nooverride {
    return flags || [];
};

public method .quota_exempt(): nooverride {
    return quota_exempt;
};

public method .clean_root() {
    var obj;
    
    // Called by $sys.clean_database()
    (> .perms(caller(), $sys) <);
    (| ._clean_root('trusted, 'trusted_by) |);
    (| ._clean_root('trusted_by, 'trusted) |);
    (| ._clean_root('writers, 'writes) |);
    (| ._clean_root('writes, 'writers) |);
    if (!manager) {
        manager = this();
        .change_manager($reaper);
    }
    if (managed) {
        managed = managed.valid_objects();
        for obj in (managed) {
            refresh();
            if ((obj.manager()) != this())
                managed = setremove(managed, obj);
        }
        if (!managed)
            clear_var('managed);
    }
};

public method .objnum(): nooverride {
    return objnum();
    
    // $#Edited: 06 Jan 96 13:28 Lynx ($lynx)
};

public method .list_methods() {
    arg gen, def, fltr, match;
    var ancs, a, m, i, methods;
    
    if (!(.has_flag('methods, sender())))
        throw(~perm, (sender() + " cannot view methods on ") + this());
    if (def)
        ancs = [def];
    else
        ancs = .(gen[1])(gen[2]) || [this()];
    methods = #[];
    for a in (ancs) {
        for m in (a.methods()) {
            if (tostr(m).(match)(fltr) != 0) {
                i = a.method_info(m);
                methods = methods.add_elem(i[5], [a, m, @i]);
            }
        }
    }
    return methods;
};

public method .method_bytecode() {
    arg method;
    
    throw(~wait, "this is broken right now.");
    return (> method_bytecode(method) <);
};

public method .rename_method() {
    arg now, new;
    
    (> .perms(sender()) <);
    (| $sys.touch() |);
    return (> rename_method(now, new) <);
};

public method .examine() {
    return [];
};

public method .new_descendants() {
    var kid, kids;
    
    kids = #[];
    for kid in (children()) {
        kids = kids.add(kid, 1);
        kids = kids.union(kid.new_descendants());
        pause();
    }
    return kids.keys();
    
    // $#Edited: 30 Jun 96 23:06 $jenner
};

private method ._clean_root() {
    arg v, m;
    var obj, value;
    
    if ((value = get_var(v))) {
        value = value.valid_objects();
        for obj in (value) {
            if (!(this() in obj.(m)()))
                value = value.setremove(obj);
            refresh();
        }
        if (value)
            set_var(v, value);
        else
            clear_var(v);
    }
};

private method .set_quota_exempt(): nooverride {
    arg bool;
    
    if (bool)
        quota_exempt = 1;
    else
        (| clear_var('quota_exempt) |);
};

public method .help_node() {
    return help_node;
    
    // $#Edited: 30 Jul 96 16:45 $jenner
};

public method .set_hnode() {
    arg node;
    
    (> .perms(sender(), 'manager) <);
    help_node = node;
    
    // $#Edited: 30 Jul 96 16:46 $jenner
};

public method .list_method() {
    arg @args;
    
    if (!(.has_flag('code, sender())))
        throw(~perm, (("Method code on " + (.namef('ref))) + " is not readable by ") + (sender().namef('ref)));
    return (> list_method(@args) <);
};

public method .new() {
    arg @suffix;
    var obj, tmp, objname, mngr, na;
    
    // this difference between this and .spawn() is that you
    // can override this method to return a frob instead.
    (> .will_spawn(sender()) <);
    suffix = (> .get_obj_suffix(@suffix) <);
    return $sys.spawn_sender(suffix, sender());
};

public method .will_spawn(): nooverride {
    arg who;
    
    if (!(.has_flag('fertile, who)))
        throw(~perm, "Not fertile or readable.");
    
    // available quota?
    if (!(who.quota_valid()))
        throw(~quota, "Sender does not have the available quota");
};

public method .get_obj_suffix() {
    arg @suffix;
    var objname, tmp;
    
    // Figure out the suffix from the arguments and child index.
    [(suffix ?= 0)] = suffix;
    if (suffix) {
        // so they dont confuse child_index:
        if (suffix.is_numeric())
            throw(~perm, "You cannot specify a numeric suffix.");
    
        // so we get correct symbols & it is always lowercase:
        suffix = lowercase(strsed(suffix, "[^a-z0-9_]+", "", "g"));
    } else {
        // get the next valid objname
        objname = tostr((| .objname() |) || "unknown");
        tmp = tosym(objname);
        while ((| lookup(tmp) |)) {
            child_index++;
            tmp = tosym((objname + "_") + tostr(child_index));
        }
        suffix = tostr(child_index);
    }
    return suffix;
};

public method ._display_ancestors() {
    arg space, checked, levels, maxlev;
    var c, anc, list, id, perms;
    
    id = ((space + this()) + " ") + ($object_lib.see_perms(this()));
    for anc in (dict_keys(checked)) {
        if (.has_ancestor(anc))
            return [];
    
        // [id + "  (above)"];
    }
    if (((.parents()).length()) > 1)
        id += " (MI)";
    list = [id];
    space += "  ";
    levels++;
    
    // check parents
    if ((!maxlev) || (maxlev != levels)) {
        for c in (.parents()) {
            list += c._display_ancestors(space, checked, levels, maxlev);
            checked = dict_add(checked, c, 1);
            pause();
        }
    }
    return list;
};

public method .format_descendants() {
    arg ind, done, depth, max, yes, no, above;
    var c, anc, list, id, perms, f, show;
    
    show = 1;
    for f in (.flags()) {
        if (yes && (!(f in yes))) {
            show = 0;
            break;
        }
        if (no && (f in no)) {
            show = 0;
            break;
        }
    }
    if (show) {
        id = ((ind + this()) + " ") + ($object_lib.see_perms(this()));
        for anc in (dict_keys(done)) {
            if (has_ancestor(anc))
                return above ? [id + " (ABOVE)"] : [];
        }
        if (listlen(parents()) > 1)
            id += " (MI)";
        list = [id];
    } else {
        list = [];
    }
    ind += "  ";
    depth++;
    
    // check children
    if ((!max) || (max != depth)) {
        for c in (children()) {
            list += c.format_descendants(ind, done, depth, max, yes, no, above);
            done = dict_add(done, c, 1);
            pause();
        }
    }
    return list;
};

public method .undefine_setting(): nooverride {
    arg name;
    var d;
    
    (> .perms(sender()) <);
    if (!((.defined_settings()).contains(name)))
        throw(~setnf, (("Setting \"" + name) + "\" is not defined by ") + this());
    
    // clear it on all descendants, then us
    for d in ((.descendants()) + [this()]) {
        d._clear_setting(name);
        pause();
    }
    
    // bye bye
    defined_settings = dict_del(defined_settings, name);
    if (!defined_settings)
        clear_var('defined_settings);
};

public method .define_setting(): nooverride {
    arg name, @info;
    var i;
    
    (> .perms(sender()) <);
    if (info) {
        info = info[1];
        for i in (info) {
            if (!(> .valid_setting_attr(@i) <))
                info = dict_del(info, i[1]);
        }
    } else {
        info = #[];
    }
    if ((.all_defined_settings()).contains(name))
        throw(~setexists, ("Setting \"" + name) + "\" is already defined.");
    if (!($code_lib.valid_setting_id(name)))
        throw(~setbad, ("Setting name \"" + name) + "\" is unacceptable.");
    defined_settings = (.defined_settings()).add(name, info);
    return defined_settings[name];
};

public method .all_defined_settings(): nooverride {
    var a, all, d;
    
    (> .perms(sender()) <);
    all = #[];
    for a in (ancestors()) {
        catch any {
            for d in (dict_keys(a.defined_settings()))
                all = dict_add(all, d, a);
        }
    }
    return all;
};

public method .defined_settings(): nooverride {
    return defined_settings || #[];
};

public method .settings(): nooverride {
    (> .perms(sender()) <);
    return settings || #[];
};

public method .setting_info(): nooverride {
    arg setting;
    
    return defined_settings[setting];
    
    // $#Edited: 05 Mar 97 20:50 $brandon
};

public method .get_setting(): nooverride {
    arg name, definer;
    var i;
    
    i = definer.setting_info(name);
    if (dict_contains(i, 'access))
        (> .((i['access])[1])(name, sender(), caller(), @sublist(i['access], 2)) <);
    if (dict_contains(i, 'get))
        return (> .((i['get])[1])(name, definer, @sublist(i['get], 2)) <);
    catch any
        return settings[name];
    with
        return (> definer.get_default_setting(name) <);
};

public method .get_default_setting(): nooverride {
    arg name;
    
    return settings[name];
};

public method .clear_setting(): nooverride {
    arg name, definer;
    var info, args;
    
    (caller() == definer()) || (> .perms(sender()) <);
    info = (> definer.setting_info(name) <);
    if (dict_contains(info, 'clear)) {
        args = sublist(info['clear], 2);
        (> .((info['clear])[1])(name) <);
    } else if (settings && dict_contains(settings, name)) {
        settings = dict_del(settings, name);
        if (!settings)
            clear_var('settings);
    }
};

public method .format_setting(): nooverride {
    arg name, definer, value;
    var i, args;
    
    i = definer.setting_info(name);
    if (dict_contains(i, 'format)) {
        args = sublist(i['format], 2);
        catch ~methodnf
            return (> .((i['format])[1])(value, @args) <);
        with
            return (> $settings.((i['format])[1])(value, @args) <);
    }
    if (type(value) == 'objnum)
        return value.namef('ref);
    else
        return "" + value;
};

public method .set_setting_attr(): nooverride {
    arg name, attr, value;
    var info;
    
    (> .perms(sender()) <);
    if ((!defined_settings) || (!dict_contains(defined_settings, name)))
        throw(~setnf, (("Setting \"" + name) + "\" is not defined on ") + this());
    if (value && (!(> .valid_setting_attr(attr, value) <)))
        return;
    info = defined_settings[name];
    if (!value)
        info = dict_del(info, attr);
    else
        info = dict_add(info, attr, value);
    defined_settings = dict_add(defined_settings, name, info);
};

public method .get_setting_attr(): nooverride {
    arg name, attr;
    
    return (defined_settings[name])[attr];
};

public method .setting_definer(): nooverride {
    arg name;
    var a;
    
    for a in (ancestors()) {
        if (dict_contains(a.defined_settings(), name))
            return a;
    }
    throw(~setnf, ("Setting \"" + name) + "\" is not defined.");
};

public method .set_setting(): nooverride {
    arg name, definer, value;
    var i, args;
    
    (> .perms(sender()) <);
    i = (> definer.setting_info(name) <);
    if (dict_contains(i, 'parse)) {
        args = sublist(i['parse], 2);
        catch ~methodnf
            value = (> .((i['parse])[1])(value, @args) <);
        with
            value = (> $settings.((i['parse])[1])(value, @args) <);
    }
    if (dict_contains(i, 'set))
        (> .((i['set])[1])(name, definer, value, @sublist(i['set], 2)) <);
    else
        settings = dict_add(settings || #[], name, value);
};

public method .valid_setting_attr(): nooverride {
    arg name, value;
    
    if (!(name in ['get, 'set, 'parse, 'clear, 'format, 'access]))
        throw(~setattr, "Invalid setting attribute '" + name);
    if (!value)
        return 0;
    else if (type(value) != 'list)
        throw(~setattr, "Setting attribute must be a list");
    else if (type(value[1]) != 'symbol)
        throw(~setattr, "Setting attribute[1] is not a symbol");
    return 1;
};

private method ._clear_setting(): nooverride {
    arg name;
    
    if (settings && dict_contains(settings, name)) {
        settings = dict_del(settings, name);
        if (!settings)
            clear_var('settings);
    }
};

public method .get_local_setting(): nooverride {
    arg name, definer;
    var i;
    
    i = definer.setting_info(name);
    if (dict_contains(i, 'access))
        (> .((i['access])[1])(name, sender(), caller(), @sublist(i['access], 2)) <);
    return (| settings[name] |) || (> definer.get_default_setting(name) <);
};


object $sys: $root;

var $sys admins = [];
var $sys agents = [$root, $daemon];
var $sys startup = #[['time, 859065084], ['objects, [$login_daemon, $lag_watcher, $http_daemon, $smtp_daemon, $world]], ['heartbeat_interval, 2]];
var $sys starting = #[['quota, 75000], ['new_user_class, $admin], ['anonymous_user_class, $guest]];
var $sys server_address = ["129.123.4.76", "ice.cold.org"];
var $sys system_email_addresses = #[['default, "nobody@need.to.set.this.address"]];
var $sys core_version = "3.0a7";
var $sys validate_email_addresses = 1;
var $sys backup = #[['interval, 3600], ['last, 859064901], ['next, 859068684], ['started, 859064901]];
var $sys system = [$sys, $root];
var $sys touched = 859065152;
var $sys loggers = [$http_interface, $daemon, $user, $connection];
var $root created_on = 796268969;
var $root inited = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root quota_exempt = 1;
var $root manager = $sys;
var $sys bindings = #[['atomic, $sys], ['create, $sys], ['backup, $sys], ['shutdown, $sys], ['set_heartbeat, $sys], ['cancel, $scheduler], ['task_info, $scheduler], ['execute, $sys], ['bind_function, $sys], ['unbind_function, $sys], ['bind_port, $daemon], ['unbind_port, $daemon], ['open_connection, $connection], ['reassign_connection, $daemon], ['fopen, $file], ['fstat, $file], ['fchmod, $file], ['fmkdir, $file], ['frmdir, $file], ['files, $file], ['fremove, $file], ['frename, $file], ['fclose, $file], ['fseek, $file], ['feof, $file], ['fwrite, $file], ['fread, $file], ['fflush, $file], ['chparents, $root], ['destroy, $root], ['dblog, $sys], ['add_var, $root], ['del_var, $root], ['variables, $root], ['list_method, $root], ['add_method, $root], ['del_method, $root], ['method_bytecode, $root], ['methods, $root], ['rename_method, $root], ['set_method_access, $root], ['set_method_flags, $root], ['data, $root], ['del_objname, $root], ['set_objname, $root], ['suspend, $scheduler], ['resume, $scheduler], ['set_user, $user], ['config, $sys]];
var $sys blacklist = [];
var $root managed = [$sys];
var $root owned = [$sys];

public method .next_objnum(): native;

public method .version(): native;

driver method .startup() {
    arg args;
    var opt, str, obj, f;
    
    if (args && ("-clean" in args)) {
        catch any
            (> .clean_database() <);
        with
            .log($parse_lib.traceback(traceback()));
        shutdown();
        return;
    }
    catch any {
        // Bind functions for security
        for f in (bindings) {
            catch any
                bind_function(@f);
            with
                dblog((("** Unable to bind function " + (f[1])) + "() to ") + (f[2]));
        }
    
        // Set up five-second heartbeat.
        set_heartbeat(startup['heartbeat_interval]);
    
        // set the startup time, reset backup time.
        startup = startup.add('time, time());
        backup = backup.add('next, time() + (backup['interval]));
    
        // tell objects who should know, that we are up.
        if (type(args) != 'list)
            args = [];
        for obj in (startup['objects]) {
            .log(("Calling " + obj) + ".startup()");
            catch any
                (> obj.startup(@args) <);
            with
                .log($parse_lib.traceback(traceback()));
        }
    } with {
        .log(("Startup ERROR at " + ctime()) + ":");
        .log(toliteral(traceback()));
        .log($parse_lib.traceback(traceback(), -1, ""));
    }
};

public method .server_info() {
    arg what, @long;
    var tmp;
    
    switch (what) {
        case 'up_time:
            return time() - (startup['time]);
        case 'startup_time:
            return startup['time];
        case 'server_hostname:
            return $network.hostname();
        case 'server_ip:
            return $network.ip();
        case 'last_backup:
            return backup['last];
        case 'driver_version:
            tmp = .version();
            return (((((long ? "Cold Genesis " : "") + (tmp[1])) + ".") + (tmp[2])) + "p") + (tmp[3]);
        case 'core_version:
            return (long ? "ColdCore " : "") + core_version;
        default:
            throw(~unknown, "Unknown flag.");
    }
};

public method .create_user() {
    arg name, password, email, @type;
    var user;
    
    if ((!(| .perms(caller(), $login_interface) |)) && (!(| .perms(sender(), 'system) |)))
        throw(~perm, "Caller and Sender are not allowed to call this method.");
    [(type ?= 'new_user_class)] = type;
    catch any {
        user = (starting[type]).spawn(name);
        user.set_name(name);
        if (type == 'new_user_class)
            user.set_password(password);
        user.change_manager(user);
        user.set_user_info("rl-email", $user_info, email);
    } with {
        // Failed to initialize the child; destroy it.
        (| user.destroy() |);
        rethrow(error());
    }
    return user;
};

public method .admins() {
    return admins;
};

public method .is_admin() {
    arg obj;
    
    return (obj == $sys) || (obj in admins);
};

public method .shutdown() {
    var opt, str, obj;
    
    (> .perms(sender(), $sys) <);
    
    // tell startup objects that we are closing shop
    for obj in (startup['objects]) {
        .log(("Calling " + obj) + ".shutdown()");
        catch any
            (> obj.shutdown() <);
        with
            .log($parse_lib.traceback(traceback()));
    }
    return shutdown();
};

public method .spawn_sender() {
    arg suffix, manager;
    var namestr;
    
    (> .perms(caller(), $root, $sys) <);
    namestr = (tostr(sender().objname()) + "_") + suffix;
    return .create([sender()], tosym(namestr), manager);
};

public method .is_system() {
    arg obj;
    
    return obj in system;
};

public method .log() {
    arg text;
    var l;
    
    if ((!sender()) in loggers) {
        if ((!(| .perms(sender(), 'system) |)) && (!(| .perms(caller(), 'system) |)))
            throw(~perm, "Only system objects can log.");
    }
    if (type(text) == 'list) {
        for l in (text)
            .log(l);
    } else {
        dblog((("[" + ($time.format("%d %h %y %H:%M"))) + "] ") + text);
    }
};

driver method .heartbeat() {
    if (sender() != 0)
        throw(~perm, "Sender is not the server.");
    (| $scheduler.pulse() |);
    if (time() > (backup['next]))
        .do_backup(this(), 'interval);
};

public method .do_backup() {
    arg @args;
    var line, who, how, name, dirty;
    
    (> .perms(sender(), 'system) <);
    dirty = .dirty();
    [(who ?= sender()), (how ?= 'request)] = args;
    if (!valid(who))
        who = sender();
    backup = backup.add('next, time() + (backup['interval]));
    backup = backup.add('last, time());
    if ((how == 'interval) && (!dirty))
        return;
    catch any {
        name = who.namef('ref);
        .log(("BACKUP (" + name) + ") ");
        line = (("Backup started at " + ($time.format("%r"))) + " by ") + name;
        $channel_ui._broadcast('System, line);
    }
    
    // double pause will hopefully let people know about it before it happens
    pause();
    pause();
    backup = backup.add('started, time());
    (> backup() <);
};

public method .set_startup() {
    arg what, value;
    var valid;
    
    (> .perms(sender(), 'system) <);
    valid = startup.keys();
    if ((!what) in valid)
        throw(~type, "Key must be one of " + toliteral(valid));
    startup = startup.add(what, value);
};

public method .get_system_email() {
    arg what;
    var email;
    
    // email directory for system services, such as arch admins.
    email = (| system_email_addresses[what] |) || ((| system_email_addresses['default] |) || "<no email set>");
    return email;
    
    // $#Edited: 30 Nov 96 20:00 $miro
};

public method .new_admin() {
    if (caller() != $admin)
        throw(~perm, "Caller is not $admin.");
    admins = setadd(admins, sender());
};

public method .agents() {
    return agents;
};

public method .get_startup() {
    arg what;
    
    return startup[what];
};

public method .set_starting() {
    arg what, value;
    var valid;
    
    (> .perms(sender(), 'system) <);
    valid = starting.keys();
    if ((!what) in valid)
        throw(~type, "Key must be one of " + toliteral(valid));
    starting = starting.add(what, value);
};

public method .execute() {
    arg script, args, @background;
    
    (> .perms(sender(), 'system) <);
    (> execute(script, args, @background) <);
};

public method .get_starting() {
    arg what;
    
    return starting[what];
};

private method .create() {
    arg parents, name, manager;
    var new;
    
    new = create(parents);
    catch any {
        new.set_objname(name);
        new.initialize();
        new.change_manager(manager);
    } with {
        // Failed to initialize the child; destroy it.
        (| new.destroy() |);
        rethrow(error());
    }
    return new;
};

public method .system() {
    return system;
};

public method .del_system_email() {
    arg key;
    
    (> .perms(sender(), 'manager) <);
    system_email_addresses = system_email_addresses.del(key);
};

public method .add_system_email() {
    arg key, email;
    
    (> .perms(sender(), 'manager) <);
    if (type(key) != 'symbol)
        throw(~type, "Key is not a symbol.");
    if (type(email) != 'string)
        throw(~type, "Email address is not a string.");
    system_email_addresses = system_email_addresses.add(key, email);
};

public method .add_method() {
    arg code, name;
    var line;
    
    (> .perms(sender()) <);
    line = ("SYSTEM: ." + tostr(name)) + "() MODIFIED";
    line = (line + " by ") + (sender().namef('ref));
    .log(line);
    return (> pass(code, name) <);
};

public method .atomic() {
    arg @args;
    
    (> .perms(sender(), 'system) <);
    return (> atomic(@args) <);
    
    // $#Edited: 26 Sep 96 11:56 $brandon
};

public method .add_to_blacklist() {
    arg domain, duration;
    
    (> .perms(sender(), 'system) <);
    blacklist = blacklist.setadd(domain);
    if (duration > 0)
        $scheduler.add_task(duration, 'del_from_blacklist, domain);
    
    // $#Edited: 30 Sep 96 10:30 $brandon
};

public method .del_from_blacklist() {
    arg domain;
    
    (> .perms(sender(), 'system) <);
    blacklist = blacklist.setremove(domain);
    
    // $#Edited: 30 Sep 96 10:30 $brandon
};

public method .validate_email_addresses() {
    return validate_email_addresses;
};

public method .blacklist() {
    return blacklist;
    
    // $#Edited: 30 Sep 96 10:30 $brandon
};

driver method .signal() {
    arg signal;
    var line;
    
    // the driver will send the following signals:
    //   HUP  -- driver will drop out of atomic mode and will flush i/o
    //   USR2 -- driver does nothing
    //   USR1 -- driver aborts all currently executing tasks, not suggested
    //   QUIT -- For both of these the driver will shutdown after current
    //   INT     tasks finish their current execution frame.  Note: do not
    //           preempt tasks at this point as they will not resume.
    line = ("** Received Signal: " + signal) + " **";
    (| $channel_ui._broadcast('System, line) |);
    if (sig in ['QUIT, 'INT]) {
        (| $channel_ui._broadcast('all, "******************************") |);
        (| $channel_ui._broadcast('all, "** IMMINENT SERVER SHUTDOWN **") |);
        (| $channel_ui._broadcast('all, "******************************") |);
    }
};

root method .sender_going_away() {
    admins = admins.setremove(sender());
    agents = agents.setremove(sender());
    system = system.setremove(sender());
};

public method ._status(): native;

bind_native .status() ._status();

public method .status() {
    return (> ._status() <) + [backup['interval], backup['last], backup['next]];
};

private method ._loop_for_core() {
    arg code;
    var obj;
    
    $root.add_method(code, '___coretmp);
    for obj in ($root.descendants()) {
        obj.___coretmp();
        pause();
    }
    $root.del_method('___coretmp);
};

private method .initialize_core() {
    var obj;
    
    (| .clean_database() |);
    
    // reset child indices
    ._loop_for_core(["child_index = 0;"]);
};

public method .clean_database() {
    var obj, p, c, cmd, other;
    
    (> .perms(caller()) <);
    
    // cleanup some of $root's messiness
    for obj in ($root.descendants()) {
        (| obj.clean_root() |);
        refresh();
    }
    other = (((($command_cache.children()).setremove($user_interfaces)).mmap('descendants)).flatten()).compress();
    
    // purge all command caches
    for obj in ($has_commands.descendants()) {
        (| obj.purge_caches() |);
        refresh();
    }
    
    // get back the 'other' caches
    for obj in (other) {
        obj.rehash_caches();
        refresh();
    }
    
    // create user caches
    for obj in ((| $user_db.connected() |) || []) {
        for p in ((| obj.parents() |) || [])
            (| p.cache_init() |);
        refresh();
    }
    
    // create location caches
    for obj in ((| $location.descendants() |) || []) {
        for p in (obj.contents()) {
            (| obj.add_object_to_remote_cache(p) |);
            refresh();
        }
        refresh();
    }
    
    // check user info (move'em home etc)
    for obj in ($user.descendants()) {
        if ((| (obj.home()) != (obj.location()) |))
            (| obj.move_to(obj.home()) |);
        refresh();
    }
    
    // validate all locations and location content's
    for obj in ($physical.descendants()) {
        (| obj.validate_contents() |);
        if (obj.has_ancestor($located)) {
            if ((!valid(obj.location())) || (!(obj in ((obj.location()).contents()))))
                obj.move_to((| obj.home() |) || $lost_and_found);
        }
        refresh();
    }
};

public method .blacklisted() {
    arg remote;
    var t;
    
    for t in (blacklist) {
        if (match_pattern(remote, t))
            return 1;
    }
    return 0;
};

public method .add_to_system() {
    arg obj;
    
    if (!(.is_admin(sender())))
        throw(~perm, "Sender is not an admin.");
    if (!((obj in admins) || (obj in agents)))
        throw(~perm, "Object is not an agent or admin.");
    system = system.union([obj]);
};

public method .del_from_system() {
    arg obj;
    
    if (!(.is_admin(sender())))
        throw(~perm, "Sender is not an admin.");
    if (!((obj in admins) || (obj in agents)))
        throw(~perm, "Object is not an agent or admin.");
    system = system.setremove(obj);
};

public method .touch() {
    touched = time();
};

public method .touched() {
    return touched;
};

public method .backup() {
    return backup;
};

public method .dirty() {
    return touched > (backup['last]);
};

public method .do_shutdown() {
    arg time, why;
    var increments, line, name, mins;
    
    if ((!($sys.is_admin(sender()))) || (definer() != this()))
        throw(~perm, "Sender is not an admin.");
    increments = [600, 300, 180, 60];
    while (increments && (time < (increments[1])))
        increments = increments.delete(1);
    name = sender().namef('xref);
    .log(("*** SHUTDOWN called by " + name) + " ***");
    if (why) {
        why = ("*** REASON: " + why) + " ***";
        .log(why);
    }
    while (1) {
        if (!increments) {
            $channel_ui._broadcast('all, "*** SYSTEM SHUTDOWN ***");
            if (why)
                $channel_ui._broadcast('all, why);
            break;
        }
        line = "*** SYSTEM SHUTDOWN IN ";
        mins = (increments[1]) / 60;
        line = ((line + tostr(mins)) + " MINUTE") + ((mins == 1) ? "" : "S");
        line = ((line + " CALLED BY ") + name) + " ***";
        $channel_ui._broadcast('all, line);
        if (why)
            $channel_ui._broadcast('all, why);
        $scheduler.sleep(increments[1]);
        increments = increments.delete(1);
    }
    pause();
    pause();
    return .shutdown();
};

public method .loggers() {
    return loggers;
};

root method .core_sys(): nooverride {
    starting = dict_add(starting, 'new_user_class, $admin);
    system_email_addresses = #[['default, "nobody@need.to.set.this.address"]];
};

driver method .backup_done() {
    var elapsed;
    
    elapsed = time() - (backup['started]);
    backup = backup.del('started);
    catch any {
        $channel_ui._broadcast('System, "Backup completed, elapsed time " + ($time.elapsed(elapsed, 'long)));
        $channel_ui._broadcast('System, "Executing filesystem cleanup.. ");
        pause();
        pause();
        .execute("backup", []);
    }
};

private method .make_core() {
    arg ver;
    var obj, d, o, top, x, admin, tmp, name;
    
    // core rooms should be +core, and cant be destroyed
    // traverse the list inverseley, less unseen heirarchial shuffling
    d = $root.descendants();
    top = listlen(d);
    core_version = ver;
    dblog(("** " + top) + " objects, destroying all non-core objects...");
    catch any {
        for x in [1 .. top] {
            obj = d[(top - x) + 1];
            (| obj.destroy() |);
            if (valid(obj)) {
                obj.change_manager(obj);
                for o in (obj.writers('literal)) {
                    obj.del_writer(o);
                    refresh();
                }
            }
            refresh();
        }
    
        // shutdown this task so that references can have
        // a chance to clear out, on destroyed objects.
        dblog("** done, suspending for new task **");
    
        // do this the hard way, to be secure
        .add_var('TMP_HEARTBEAT_CODE, .list_method('heartbeat));
        .add_method([".finish_core();"], 'heartbeat);
    } with {
        dblog("traceback: " + traceback());
    }
};

public method .task_info() {
    arg @args;
    
    (> .perms(sender(), 'system) <);
    return (> task_info(@args) <);
    
    // $#Edited: 19 Sep 96 09:59 $brandon
};

public method .destroy_sender() {
    // potential problem spot, but sometimes its needed
    // add core definer items to the list, if you want them to call it
    (> .perms(caller(), $exit, $connection, $connection_interface) <);
    (> sender().destroy() <);
};

private method .finish_core() {
    // cleanup heartbeat
    .add_method(TMP_HEARTBEAT_CODE, 'heartbeat);
    .del_var('TMP_HEARTBEAT_CODE);
    
    // ok, finish up
    catch any {
        dblog("** corifying remaining objects");
        $root.corify();
        dblog("** cleaning database..");
        .clean_database();
        dblog("** shutting down..");
        shutdown();
    } with {
        dblog("traceback: " + traceback());
    }
};

public method .old_admin() {
    if (caller() != $admin)
        throw(~perm, "Caller is not $admin.");
    admins = setremove(admins, sender());
    system = setremove(system, sender());
};

root method .clear_definer_vars(): nooverride {
    arg definer, objs;
    var code, v, a, meth, errs, d;
    
    code = [];
    for v in (definer.variables())
        code += [("(| clear_var('" + v) + ") |);"];
    meth = tosym("_root_tmp_" + time());
    if (!(definer.add_method(code, meth))) {
        for d in (objs) {
            pause();
            (| d.(meth)() |);
        }
        (| definer.del_method(meth) |);
    }
};

public method .tmp_eval_859065108() {
    var me, here;
    
    me = $brandon;
    here = $the_pit;
    return (> .make_core("3.0a7") <);
};


new object $foundation: $root;

var $root child_index = 9;
var $root fertile = 1;
var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root manager = $foundation;
var $root managed = [$foundation];
var $root owned = [$foundation];
var $foundation edit_types = 0;
var $foundation defined_msgs = 0;
var $foundation msgs = 0;

public method .configure() {
    arg set;
    
    // This is for post-creation configuration of a VR object.  It is used
    // to interactively configure the VR aspects and behaviour of an object.
    // It should be optional, any command hooking into confingure should check
    // for a -conf?igure option first (which would imply skipping configuration).
    //
    // Overriding methods should pass() first, giving priority to their
    // ancestors.  The argument 'set' is a dictionary with symbol keys
    // defining what has been set.  Use the definer's name + "_" + setting
    // as the name of the key ("name" on $has_name would be 'has_name_name).
    // If something is already in the set dictionary, do not re-set it
    // again (for instance, if the command hooking into configure accepted
    // the name of the object on it's command line it would put
    // 'has_name_name in the dictionary and $has_name.configure() would not 
    // prompt for the name).
    //
    // "@skip" should always skip the setting, and not alter it.
    // if .prompt() returns 'aborted, throw ~abort.
    //
    (> .perms(sender()) <);
    return set;
};

public method .environment() {
    return [];
};

public method .match_environment() {
    arg str;
    var obj, env, found, match, target;
    
    if (!str)
        throw(~objnf, "No object specified.", str);
    str = str.strip_article();
    
    // Handle special cases.
    if (str in ["me", "my"])
        return this();
    else if (((str[1]) == "$") || ((str[1]) == "#"))
        return (> $object_lib.to_dbref(str) <);
    else if (str in ["it", "him", "her"])
        return (| .match_context(str) |) || throw(~context, ("I don't see " + str) + " here, do you?");
    
    // Start matching
    found = [];
    env = .environment();
    
    // special case ordinal references
    if ((match = $parse_lib.ordinal_reference(str)))
        return env.match_nth(@match);
    if ((match = $parse_lib.possessive_reference(str))) {
        if ((match[1]) == "me")
            obj = this();
        else
            obj = (> env.match_object(match[1]) <);
        if (!(obj.match_name(str))) {
            catch ~objnf, ~ambig, ~range {
                env = (| obj.contents() |) || [];
                if ((found = $parse_lib.ordinal_reference(match[2])))
                    return (> env.match_nth(@found) <);
                else
                    return (> env.match_object(match[2]) <);
            } with {
                if (error() == ~objnf)
                    throw(~objnf, (((obj.name()) + " does not have ") + ((match[2]).add_indefinite())) + ".");
                else if (error() == ~ambig)
                    throw(~ambig, ((("\"" + str) + "\" can match ") + ((((traceback()[1])[3]).mmap('namef, 'ref)).to_english("", " or "))) + ".");
                else
                    throw(~objnf, (obj.name()) + "'s what?");
            }
        }
    }
    catch ~objnf, ~ambig {
        return (> env.match_object(str) <);
    } with {
        if (error() == ~objnf)
            throw(~objnf, ("You do not see " + (str.add_indefinite())) + " anywhere.");
        throw(~ambig, ((("\"" + str) + "\" can match ") + ((((traceback()[1])[3]).mmap('namef, 'ref)).to_english("", " or "))) + ".");
    }
};

public method .local_to_environment() {
    arg obj;
    
    return obj in (.environment());
};

public method .get_edit_types() {
    return edit_types || [];
    
    // $#Edited: 07 Nov 96 13:56 $brandon
};

public method .set_edit_types(): nooverride {
    arg t;
    
    (> .perms(sender()) <);
    if (t)
        edit_types = t;
};

public method .all_edit_types(): nooverride {
    var i, l, t;
    
    l = [];
    for i in (.ancestors()) {
        if (type((| (t = i.get_edit_types()) |)) == 'list)
            l = l.union(i.get_edit_types());
    }
    return l;
};

public method .defined_msgs(): nooverride {
    return defined_msgs || #[];
};

public method .all_defined_msgs(): nooverride {
    var msgs, m, a;
    
    msgs = #[];
    for a in ([this()] + ancestors()) {
        if (a == definer())
            break;
        catch any
            msgs = dict_union(msgs, a.defined_msgs());
    }
    return msgs;
};

public method .clear_msg(): nooverride {
    arg name, @branches;
    var messages, branch, msg;
    
    (caller() != definer()) && (> .perms(sender()) <);
    messages = msgs || #[];
    if (!dict_contains(messages, name))
        return;
    if (!branches) {
        messages = dict_del(messages, name);
    } else {
        msg = messages[name];
        for branch in (branches) {
            if (dict_contains(msg, branch))
                msg = dict_del(msg, branch);
        }
        if (!msg)
            messages = dict_del(messages, name);
    }
    if (!messages)
        clear_var('msgs);
    else
        msgs = messages;
};

public method .define_msg(): nooverride {
    arg name;
    
    (> .perms(sender()) <);
    if ((.all_defined_msgs()).contains(name))
        throw(~msgexists, ("Message \"" + name) + "\" is already defined.");
    if (!($code_lib.valid_message_id(name)))
        throw(~msgbad, ("Message \"" + name) + "\" contains invalid characters.");
    defined_msgs = (.defined_msgs()).add(name, #[['branches, ["general"]]]);
};

public method .undefine_msg(): nooverride {
    arg name;
    var d;
    
    (> .perms(sender()) <);
    if (!((.defined_msgs()).contains(name)))
        throw(~msgnf, (("Message \"" + name) + "\" is not defined by ") + this());
    
    // clear it on all descendants, then us
    for d in (.descendants()) {
        d.clear_msg(name);
        pause();
    }
    .clear_msg(name);
    
    // bye bye
    defined_msgs = dict_del(defined_msgs, name);
    if (!defined_msgs)
        clear_var('defined_msgs);
};

public method .msgs(): nooverride {
    return msgs || #[];
};

public method .get_default_msg(): nooverride {
    arg name;
    var def, b;
    
    catch any {
        return msgs[name];
    } with {
        def = $compiler.compile_cml(">>NO DEFAULT<<");
        return hash b in (.get_msg_attr(name, 'branches)) to ([b, def]);
    }
};

public method .get_msg(): nooverride {
    arg name, definer;
    
    return dict_union(definer.get_default_msg(name), (| msgs[name] |) || #[]);
};

public method .get_msg_attr(): nooverride {
    arg name, attr;
    
    return (defined_msgs[name])[attr];
};

public method .set_msg_attr(): nooverride {
    arg name, attr, value;
    var attrs, branch;
    
    (> .perms(sender()) <);
    if ((!defined_msgs) || (!dict_contains(defined_msgs, name)))
        throw(~msgnf, (("Message \"" + name) + "\" is not defined on ") + this());
    if (attr == 'branches) {
        if (!value)
            value = ["general"];
        for branch in (value) {
            if (!($code_lib.valid_message_id(branch)))
                throw(~msgbad, ((("Message branch \"" + name) + ".") + branch) + "\" contains invalid characters.");
        }
    }
    if (!value)
        attrs = dict_del(defined_msgs[name], attr);
    else
        attrs = dict_add(defined_msgs[name], attr, value);
    defined_msgs = dict_add(defined_msgs, name, attrs);
};

public method .set_msg(): nooverride {
    arg name, branch, definer, value;
    var compiler, branches, msg, definer;
    
    (> .perms(sender()) <);
    compiler = (| definer.get_msg_attr(name, 'compiler) |) || $compiler;
    value = (> compiler.compile_cml(value) <);
    branch ?= "general";
    if (!(branch in (definer.get_msg_attr(name, 'branches))))
        throw(~badbranch, ((("Message branch \"" + name) + ".") + branch) + "\" is not defined.");
    msgs ?= #[];
    msg = dict_add((| msgs[name] |) || #[], branch, value);
    msgs = dict_add(msgs, name, msg);
};

public method .all_msgs() {
    arg @ms;
    var def, out, m, a, ams, av, v, b;
    
    out = #[];
    if (ms)
        ms = ms[1];
    else
        ms = msgs || #[];
    def = $compiler.compile_cml(">>NO DEFAULT<<");
    for a in ([this()] + ancestors()) {
        if (a == definer())
            break;
        catch any {
            ams = a.msgs();
            for m in (a.defined_msgs()) {
                v = (| ms[m[1]] |);
                av = (| ams[m[1]] |);
                if (v) {
                    if (av)
                        v = dict_union(av, v);
                    else
                        v = dict_union(hash b in (m[2]) to ([b, def]), v);
                } else if (av) {
                    v = av;
                } else {
                    v = #[["general", def]];
                }
                out = dict_add(out, m[1], v);
            }
        }
    }
    return out;
};

public method .msg_definer(): nooverride {
    arg name;
    var a;
    
    for a in (ancestors()) {
        if (a == definer())
            break;
        catch any {
            if ((a.defined_msgs())[name])
                return a;
        }
    }
    throw(~invmsg, ("Message \"" + name) + "\" is not defined.");
};

public method .eval_message() {
    arg name, definer, vars;
    var eval, msg;
    
    eval = (| definer.get_msg_attr(name, 'evaluator) |) || $bs_eval;
    msg = $message_frob.new_with(.get_msg(name, definer));
    vars = dict_add(vars, 'evaluator, eval);
    msg = msg.set_vars(vars);
    vars = dict_add(vars, 'time, 'pre);
    return msg.eval_ctext(vars);
};

public method .gender() {
    return $gender_neuter;
};

public method .gender_context() {
    return "it";
};


new object $has_commands: $foundation;

var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root child_index = 6;
var $has_commands shortcuts = #[];
var $has_commands local = 0;
var $has_commands remote = 0;
var $root manager = $has_commands;
var $root managed = [$has_commands];
var $root owned = [$has_commands];

public method .add_command() {
    arg template, method, @type;
    var cmd, types, count, x;
    
    (> .perms(sender()) <);
    [(type ?= 'local)] = type;
    if ("*" in template)
        throw(~invcmd, "Invalid command, command templates cannot contain \"*\"!.");
    cmd = (> $command_lib.validate_command_template(template) <);
    if (!(type in ['local, 'remote]))
        throw(~type, "Command types can be either 'local or 'remote");
    if ('this in (((cmd[2]).values()).slice(1)))
        type = 'remote;
    if (type == 'remote) {
        for x in (((cmd[2]).values()).slice(1)) {
            if (x == 'this)
                count++;
        }
        if (!count)
            throw(~add_command, "Command type defined as remote with no <this> argument.");
        else if (count > 1)
            throw(~add_command, "More than one <this> argument specified in template.");
    }
    if (!get_var(type))
        set_var(type, #[]);
    set_var(type, get_var(type).setadd_elem((cmd[1])[1], [@cmd[1], template, method, cmd[2]]));
    
    // $#Edited: 22 Nov 96 17:42 $miro
    // $#Edited: 30 Nov 96 20:00 $miro
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .all_local_commands() {
    var cmds, a, acmds;
    
    cmds = #[];
    for a in (ancestors()) {
        if (a == definer())
            break;
        if ((acmds = (| a.local_commands() |)))
            cmds = cmds.add(a, acmds);
    }
    return cmds;
};

public method .local_commands() {
    return local || #[];
};

public method .get_command_info() {
    arg type, cmd;
    var info, a, ainfo;
    
    info = [];
    for a in (ancestors()) {
        if (a == definer())
            break;
        if ((ainfo = (| a.command_info(type, cmd) |)))
            info = info.union(ainfo);
    }
    return info;
};

public method .del_command() {
    arg template, method;
    var cmd, c, d, info, type;
    
    (> .perms(sender()) <);
    cmd = template.explode();
    if (!cmd)
        throw(~type, "Invalid template.");
    cmd = cmd[1];
    info = #[['local, .get_command_info('local, cmd)]];
    info = info.add('remote, .get_command_info('remote, cmd));
    for type in (info) {
        for c in (type[2]) {
            if (((c[3]) == template) && ((c[4]) == method)) {
                set_var(type[1], get_var(type[1]).del_elem(cmd, c));
                d++;
            }
        }
    }
    return d;
};

public method .remote_commands() {
    return remote || #[];
};

root method .init_has_commands() {
    local = (remote = (shortcuts = #[]));
};

root method .uninit_has_commands() {
    .clear_variables(@.variables());
};

public method .add_shortcut() {
    arg shortcut, template, method;
    var relation;
    
    (> .perms(sender()) <);
    if ((type(shortcut) != 'string) || (type(template) != 'string))
        throw(~type, "Both shortcut and template must be strings.");
    if (type(method) != 'symbol)
        throw(~type, "Method must be submitted as a symbol.");
    relation = (> $command_lib.parse_relation(shortcut, template) <);
    shortcut = (relation[1])[1];
    relation = (relation[2])[2];
    if (!shortcuts)
        shortcuts = #[];
    shortcuts = shortcuts.add(shortcut, [method, relation]);
};

public method .del_shortcut() {
    arg shortcut;
    var value;
    
    (> .perms(sender()) <);
    value = (| shortcuts.del(shortcut) |);
    if (type(value) != 'dictionary)
        throw(~shortcutnf, ("Shortcut \"" + shortcut) + "\" is not defined on this object.");
    shortcuts = value;
};

public method .all_shortcuts() {
    var s, a, as;
    
    s = [];
    for a in (ancestors()) {
        if (a == definer())
            break;
        if ((as = (| a.shortcuts() |)))
            s += as.to_list();
    }
    return s;
    
    // $#Edited: 22 Nov 96 17:43 $miro
};

public method .get_shortcut_info() {
    arg shortcut;
    
    return (| shortcuts[shortcut] |) || throw(~shortcutnf, ("Shortcut \"" + shortcut) + "\" is not defined on this object.", shortcut);
};

public method .shortcuts() {
    return shortcuts || #[];
};

public method .command_info() {
    arg type, cmd;
    
    return (| get_var(type)[cmd] |) || throw(~cmdnf, ("Command \"" + cmd) + "\" is not defined on this object.", cmd);
};

public method .all_remote_commands() {
    var cmds, a, acmds;
    
    cmds = #[];
    for a in (ancestors()) {
        if (a == definer())
            break;
        if ((acmds = (| a.remote_commands() |)))
            cmds = cmds.add(a, acmds);
    }
    return cmds;
};


new object $has_name: $foundation;

var $root child_index = 11;
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $has_name name = ['normal, "named object", "a named object"];
var $root manager = $has_name;
var $has_name templates = 0;
var $root owned = [$has_name];
var $root managed = [$has_name];

public method .set_name() {
    arg new_name, @args;
    var type;
    
    (> .perms(sender()) <);
    if (new_name && ((new_name[1]) in ["$", "#"]))
        throw(~invname, "Names cannot begin with \"$\" or \"#\".");
    if (type(new_name) != 'string)
        throw(~type, "New name must be given as a string.");
    
    // this will not catch them all, but we can try.
    if (new_name.match_regexp("^(a|an|the) +"))
        throw(~bad_name, "Do not include articles in name, use +u +n or +pinstead.");
    [(type ?= 'normal)] = args;
    if (!(type in ['prop, 'normal, 'uniq]))
        throw(~invarg, "Type must be one of: 'prop, 'normal or 'uniq");
    switch (type) {
        case 'prop:
            new_name = [new_name, new_name];
        case 'uniq:
            new_name = [new_name, "the " + new_name];
        case 'normal:
            new_name = [new_name, new_name.add_indefinite()];
    }
    name = [type, @new_name];
    
    // $#Edited: 22 Nov 96 17:42 $miro
    // $#Edited: 30 Nov 96 20:00 $miro
};

public method .match_name() {
    arg str;
    var m, t;
    
    if ((m = match_begin(name[2], str)))
        return m;
    for t in (templates || []) {
        if ((m = match_template(str, t)))
            return m;
    }
    return 0;
};

public method .name() {
    arg @args;
    
    if (!name)
        return tostr(this());
    if (!args)
        return name[3];
    switch (args[1]) {
        case 'type:
            return name[1];
        case 'noarticle:
            return name[2];
        default:
            return name;
    }
};

public method .name_templates() {
    return templates || [];
};

public method .namef() {
    arg type;
    
    switch (type) {
        case 'ref:
            return (((.name()) + " (") + this()) + ")";
        case 'xref:
            return ((this() + " (") + (.name())) + ")";
        case 'name:
            return .name();
        default:
            return (> pass(type) <);
    }
    
    // $# Edited 28 Oct 1995 21:06 Lynx ($lynx)
    // $#Edited: 15 Jul 96 22:18 $jenner
};

public method .hname() {
    arg @args;
    
    return ((("<a href=\"/bin/describe?target=" + (.objname())) + "\">") + (.name())) + "</a>";
};

public method .add_name_template() {
    arg template;
    var p;
    
    (> .perms(sender()) <);
    for p in (explode(template, "|")) {
        if (match_begin(name[2], p.strip()))
            throw(~redundant, ("Redundant name template part \"" + p) + "\" already matches name.");
    }
    templates = setadd(templates || [], template);
};

public method .del_name_template() {
    arg template;
    
    (> .perms(sender()) <);
    templates = setremove(templates || [], template);
    if (!templates)
        (| clear_var('templates) |);
};

public method .init_has_name() {
    var objname;
    
    objname = tostr(.objname());
    name = ['prop, tostr(objname), tostr(objname)];
};


new object $described: $has_name, $has_commands;

var $described prose = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['uniq, "Generic Described Object", "the Generic Described Object"];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $root manager = $described;
var $root owned = [$described];
var $foundation edit_types = ["prose"];
var $root child_index = 1;
var $root managed = [$described];

root method .init_described() {
    prose = [];
};

protected method .description() {
    arg flags;
    var out, name;
    
    out = (<$ctext_frob, [[(<$format, ["subj", [], [.name()], 'do_subj]>)], #[]]>);
    if ((| flags['prose] |))
        return [out, .prose()];
    return [out];
};

public method .prose() {
    arg @no_default;
    
    return prose || (no_default ? 0 : "You see nothing special");
    
    // $#Edited: 18 Oct 96 13:13 $miro
};

public method .set_prose() {
    arg new;
    
    (> .perms(sender()) <);
    switch (type(new)) {
        case 'string, 'list:
            new = (> $compiler.compile_cml(new) <);
        case 'frob:
            // we'll let this pass by unharmed
        default:
            throw(~invalid, "Prose can be submitted as CML or Ctext");
    }
    prose = new;
};

root method .uninit_described() {
    prose = 0;
};

public method .get_description(): nooverride {
    arg @dflags;
    var flags, f;
    
    flags = #[['prose, 1], ['actor, sender()]];
    if (dflags && (type(dflags[1]) == 'dictionary)) {
        dflags = dflags[1];
        for f in (dflags.keys())
            flags = dict_add(flags, f, dflags[f]);
    }
    return .description(flags);
};

public method .edit_prose() {
    var p;
    
    (> .perms(sender()) <);
    p = .prose();
    if (type(p) == 'frob)
        p = p.uncompile();
    (> sender().invoke_editor(this(), '_edit_prose_callback, p, []) <);
    
    // $#Edited: 18 Aug 96 21:02 $jenner
};

public method ._edit_prose_callback() {
    arg text, client_data;
    
    (> .perms(sender()) <);
    .set_prose(text);
    return "Description set.";
    
    // $#Edited: 18 Aug 96 20:14 $jenner
};

public method .configure() {
    arg set;
    var p, end, ctext, s, still, type;
    
    set = (> pass(set) <);
    s = sender();
    still = ("Do you still want to describe " + (.name())) + "? [no] ";
    if (!(set.contains('described_prose))) {
        while (!end) {
            if (.is($exit))
                type = "exit ";
            else if (.is($place))
                type = "place ";
            else
                type = "";
            p = s.read((("Describe " + type) + (.name())) + ", Enter \".\" to finish or \"@abort\" to abort description.");
            if (p == 'aborted) {
                end = !(s.prompt_yesno(still, 0));
            } else {
                catch any {
                    ctext = (> $compiler.compile_cml(p) <);
                    s.tell(["You submitted the following description:", ""]);
                    s.tell(ctext);
                    s.tell("");
                    if (!(end = s.prompt_yesno("Keep this description? [yes] ")))
                        ctext = 0;
                } with {
                    s.tell(["The following CML compiler error occurred:", "  ", (traceback()[1])[2]]);
                    end = !(s.prompt_yesno(still, 0));
                }
            }
        }
        if (ctext)
            .set_prose(ctext);
        set = set.add('described_prose, 1);
    }
    return set;
};

public method .get_detail() {
    arg name;
    var details, d, matches;
    
    details = (| (.prose()).get_var('details) |);
    if (!details)
        throw(~nodetail, ("No \"" + name) + "\" in your environment.");
    matches = [];
    for d in (details.keys()) {
        if (match_begin(d, name))
            matches += [d];
    }
    if (!matches)
        throw(~nodetail, ("No \"" + name) + "\" in your environment.");
    if (listlen(matches) != 1)
        throw(~ambig, (("\"" + name) + "\" can match ") + (matches.to_english()));
    return (<$ctext_frob, [details[matches[1]], #[['this, this()]]]>);
};


new object $event_handler: $foundation;

var $root manager = $event_handler;
var $root managed = [$event_handler];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 850790316;
var $root inited = 1;
var $event_handler hooks = 0;
var $event_handler hooked = 0;
var $event_handler events = 0;

root method .uninit_event_handler() {
    var e, o, u;
    
    for u in ((events || #[]).keys())
        (| .unhook_events(u) |);
    for e in ((hooks || #[]).keys())
        (| o.event_hook_removed(e) |);
    (| (.location()).unhook_from_all() |);
};

public method .clear_event_hook() {
    arg event;
    var o;
    
    (> .perms(sender(), 'writer) <);
    if ((!hooks) || (!(hooks.contains(event))))
        return;
    for o in (hooks[event])
        (| o.event_hook_removed(event) |);
    hooks = dict_del(hooks, event);
    if (!hooks) {
        (| clear_var('hooks) |);
        (| clear_var('hooked) |);
    }
};

public method .event_hooks() {
    if (hooks)
        return dict_keys(hooks);
    return [];
};

public method .hook_into_event() {
    arg event;
    
    if (!hooks)
        hooks = #[];
    (> .will_hook(event, sender()) <);
    hooks = dict_add(hooks, event, setadd((| hooks[event] |) || [], sender()));
    hooked = (hooked || #[]).setadd_elem(sender(), event);
    (| .did_hook(event, sender()) |);
};

public method .unhook_from_event() {
    arg event;
    
    if (!hooks)
        return;
    hooks = dict_add(hooks, event, setremove(hooks[event], sender()));
    hooked = hooked.del_elem(sender(), event);
};

public method .unhook_from_all() {
    var e;
    
    if ((!hooked) || (!(hooked.contains(sender()))))
        return;
    for e in (hooked[sender()])
        hooks = dict_add(hooks, e, setremove(hooks[e], sender()));
    hooked = dict_del(hooked, sender());
};

protected method .will_hook() {
    arg event, obj;
    
};

protected method .did_hook() {
    arg event, obj;
    
};

public method .send_event() {
    arg event, @args;
    var o;
    
    // some sort of perms checking..
    if ((!hooks) || (!(hooks.contains(event))))
        return;
    for o in (hooks[event]) {
        if (!valid(o)) {
            hooks = dict_add(hooks, event, setremove(hooks[event], o));
            hooked = hooked.del_elem(o, event);
        }
        (| o.event_notify(event, sender(), @args) |);
    }
};

public method .event_notify() {
    arg event, origin, @args;
    
    if (caller() != $event_handler)
        throw(~perm, caller() + " is not $event_handler.");
};

public method .event_hook_removed() {
    arg event;
    
    (> .perms(caller(), $event_handler) <);
};

public method .deregister_event() {
    arg event, update_on;
    var value;
    
    (> .perms(sender()) <);
    if ((events.contains(update_on)) && ((events[update_on]).contains(event))) {
        value = (events[update_on]).del(event);
        if (value)
            events = events.add(update_on, value);
        else
            events = events.del(update_on);
        if (!events)
            clear_var('events);
    }
    
    // $#Edited: 21 Dec 96 13:04 $brandon
};

public method .hook_events() {
    arg type;
    var status, source, event, l, all;
    
    if (events && (events.contains(type))) {
        all = events[type];
        events = events.del(type);
        l = .location();
        for event in (all) {
            [event, [status, source]] = event;
            switch (source) {
                case 'location:
                    l.hook_into_event(event);
                case 'this:
                    .hook_into_event(event);
                default:
                    source.hook_into_event(event);
            }
            all = all.add(event, [1, source]);
        }
        events = events.add(type, all);
    }
    
    // $#Edited: 21 Dec 96 13:05 $brandon
};

public method .register_event() {
    arg event, update_on, src;
    var value, all;
    
    (> .perms(sender()) <);
    if (!events)
        events = #[];
    if ((update_on != 'move) && (update_on != 'startup))
        throw(~type, "Update on must be either 'move or 'startup");
    if (type(src) == 'symbol) {
        if ((src != 'location) && (src != 'this))
            throw(~type, "Source types must be either 'location or 'this.");
    } else if (type(src) != 'objnum) {
        throw(~type, "Source type must be either a symbol or object.");
    } else if (!(src.is($event_handler))) {
        throw(~type, ("Source " + (src.namef('ref))) + " is not an event handler.");
    }
    if (events.contains(update_on)) {
        all = events[update_on];
        if ((events[update_on]).contains(event)) {
            value = replace(all[event], 2, src);
            events = events.add(update_on, all.add(event, value));
        } else {
            events = events.add(update_on, all.add(event, [0, src]));
        }
    } else {
        events = events.add(update_on, #[[event, [0, src]]]);
    }
    
    // $#Edited: 07 Mar 97 15:45 $miro
};

public method .unhook_events() {
    arg type, @loc;
    var all, event, status, source;
    
    if (events && (events.contains(type))) {
        all = events[type];
        events = events.del(type);
        loc = loc ? loc[1] : (.location());
        for event in (all) {
            [event, [status, source]] = event;
            switch (source) {
                case 'location:
                    (| loc.unhook_from_event(event) |);
                case 'this:
                    (| .unhook_from_event(event) |);
                default:
                    (| source.hook_into_event(event) |);
            }
            all = all.add(event, [0, source]);
        }
        events = events.add(type, all);
    }
};


new object $physical: $described, $event_handler;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $described prose = [];
var $physical visibility = 0;
var $has_name name = ['uniq, "Generic Physical Object", "the Generic Physical Object"];
var $root manager = $physical;
var $root owned = [$physical];
var $root defined_settings = #[["visibility", #[['get, ['visibility]], ['set, ['set_visibility]], ['parse, ['is_type, 'integer]]]]];
var $root managed = [$physical];

public method .set_visibility() {
    arg name, definer, value, @args;
    
    (> .perms(sender()) <);
    visibility = value;
};

public method .visibility() {
    arg @args;
    
    return visibility;
};

public method .is_visible_to() {
    arg whom;
    
    return (.visibility()) >= ((whom.location()).darkness());
};

public method .set_darkness() {
    arg name, definer, value, @args;
    
    (> .perms(sender()) <);
    darkness = value;
};

public method .vr_examine() {
    // $#Edited: 12 Jun 96 22:44 $lynx
};


new object $located: $physical;

var $located inited = 0;
var $located location = $lost_and_found;
var $located obvious = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $described prose = [];
var $has_name name = ['uniq, "Generic Located Object", "the Generic Located Object"];
var $root manager = $located;
var $root child_index = 1;
var $root managed = [$located];
var $root owned = [$located];

root method .init_located() {
    location = $void;
    location.add_sender_to_contents();
    obvious = 1;
};

public method .uninit_guest_guest() {
    if (caller() != $root)
        throw(~perm, "Caller is not root.");
    location.del_sender_from_contents();
    location = 0;
};

public method .environment() {
    return [this()] + ((location.environment()).setremove(this()));
};

public method .match_environment() {
    arg str;
    var thing, matches;
    
    if (str == "here")
        return location;
    return (> pass(str) <);
};

public method .location() {
    return location || $void;
};

public method .will_move() {
    arg mover, place;
    
};

protected method .did_move() {
    arg mover, old_place;
    
    // cleanup events  
    .unhook_events('move, old_place);
    old_place.send_event('movement, 'leave, old_place);
    location.send_event('movement, 'arrive);
    .hook_events('move);
};

public method .realm() {
    return realm;
};

root method .uninit_located() {
    (.location()).del_sender_from_contents();
};

public method .move_to() {
    arg place;
    var old;
    
    // Don't do anything if we're already here.
    if (place == location)
        return;
    if (!(place.has_ancestor($location)))
        throw(~type, "Argument is not a location.");
    
    // Notify involved parties of impending move, allowing them to throw
    // errors.
    if (!valid(location))
        location = $nowhere;
    (> .will_move(sender(), place) <);
    (> location.will_leave(place) <);
    (> place.will_arrive(location) <);
    
    // Set location.
    old = location;
    location = place;
    old.del_sender_from_contents();
    place.add_sender_to_contents();
    
    // Notify involved parties of completed move, in reverse order.
    place.did_arrive(old);
    old.did_leave(place);
    .did_move(sender(), old);
};

public method .match_environment_all() {
    arg s;
    
    if (s == "here")
        return [location, @(> pass(@args) <)];
    else
        return (> pass(s) <);
};

public method .obvious() {
    return obvious;
};

public method .set_obvious() {
    arg obv;
    
    .perms(sender());
    obvious = obv;
};

public method .realm_name() {
    arg @args;
    
    return (.location()).realm_name(@args);
};

public method .is_obvious_to() {
    arg whom;
    
    // will later do something creative here
    return 1;
};


new object $thing: $located;

var $root child_index = 219;
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $located location = $void;
var $located obvious = 1;
var $described prose = [];
var $has_name name = ['normal, "thing", "a thing"];
var $has_commands shortcuts = #[];
var $has_commands remote = #[["@boot", [["@boot", "*", "@boot <this>", 'boot_cmd, #[[1, ['this, []]]]]]]];
var $has_commands local = #[];
var $thing lock = <$true_lock_frob, []>;
var $root settings = #[["home", $lost_and_found]];
var $root manager = $thing;
var $root owned = [$thing];
var $root defined_settings = #[["home", #[['get, ['home]], ['parse, ['parse_home]]]], ["gender", #[['get, ['gender]], ['set, ['set_gender]], ['parse, ['parse_gender_setting]]]], ["lock", #[['get, ['get_lock]], ['set, ['set_lock]], ['parse, ['parse_lock]], ['format, ['format_lock]]]]];
var $thing gender = 0;
var $root managed = [$thing];

public method .boot_cmd() {
    arg cmdstr, cmd, this;
    var loc, dest, exit;
    
    loc = .location();
    if (!(| .perms(sender(), 'manager) |)) {
        .tell((((sender().name()) + " tried to boot you from ") + (loc.name())) + "!");
        loc.announce((((((sender().name()) + " tried to boot ") + (.name())) + " from ") + (loc.name())) + "!", sender(), this());
        return ((("Only " + ((loc.manager()).name())) + " can boot people from ") + (loc.name())) + "!";
    }
    dest = .home();
    catch any {
        sender().tell(("You boot " + (.name())) + ".");
        loc.announce((((((sender().name()) + " boots ") + (.name())) + " from ") + ((.location()).name())) + ".", this(), sender());
        if ((sender().location()) != loc)
            (sender().location()).announce((((((sender().name()) + " boots ") + (.name())) + " from ") + ((.location()).name())) + ".", this(), sender());
        (> .move_to(dest) <);
    } with {
        return (traceback()[1])[2];
    }
    
    // $# Edited 05 Nov 1995 14:10 Lynx ($lynx)
};

public method .lock() {
    return lock;
};

public method .lock_cmd() {
    arg cmdstr, cmd, this;
    
    if (!(| .perms(sender()) |))
        return ((("Only " + ((.manager()).name())) + " can lock ") + (.name())) + "!";
    lock = $false_lock_frob.new();
    return "You lock " + (.name());
};

public method .lock_with_cmd() {
    arg cmdstr, cmd, this, prep, str;
    
    if (!(| .perms(sender()) |))
        return ((("Only " + ((.manager()).name())) + " can lock ") + (.name())) + "!";
    catch ~objnf, ~parse {
        lock = $lock_parser.parse(str, sender());
        return ((((("You lock " + (.name())) + " ") + prep) + " ") + (lock.lock_name('thing))) + ".";
    } with {
        switch (error()) {
            case ~objnf:
                return "Object not found in lock string.";
            case ~parse:
                return "Invalid lock string.";
        }
    }
};

public method .unlock_cmd() {
    arg cmdstr, cmd, this;
    
    if (!(| .perms(sender()) |))
        return ((("Only " + ((.manager()).name())) + " can lock ") + (.name())) + "!";
    lock = $true_lock_frob.new();
    return "You unlock " + (.name());
};

public method .will_move() {
    arg mover, place;
    
    (> pass(mover, place) <);
    if (mover.is($housekeeper))
        return;
    if (lock && ((mover != $exit) && (!(lock.try(mover)))))
        throw(~locked, ((((.name()).capitalize()) + " is locked to ") + (lock.lock_name('thing))) + ".");
    else if (!(.is_writable_by(sender())))
        throw(~move, "You cannot move " + this());
};

public method .home() {
    arg @args;
    var home;
    
    home = .get_local_setting("home", $thing);
    if (home)
        return home;
    if ((.manager()).is($user))
        return .manager();
    return $lost_and_found;
};

public method .try_lock() {
    arg mover;
    
    return lock && ((mover != $exit) && (lock.try(mover)));
};

public method .check_gender() {
    arg definer, value, @args;
    var g, gs;
    
    gs = [$gender_female, $gender_male, $gender_neuter];
    g = value in (gs.mmap('name));
    if (!g)
        throw(~set, "Gender must be one of: " + ((gs.mmap('name)).to_english("", " or ")));
    return gs[g];
};

public method .tell() {
    arg @args;
    
    // $#Edited: 23 Dec 96 15:38 $brandon
};

public method .directed_tell() {
    arg @args;
    
};

public method .parse_home() {
    arg value, @args;
    var home;
    
    home = (> .match_environment(value) <);
    if ((!(home.trusts(sender()))) && (!(home.get_setting("public-home", $place))))
        throw(~perm, ("You do not have permission to make " + (home.name())) + " your home.");
    return home;
};

public method .parse_gender_setting() {
    arg value, @args;
    var g, gs;
    
    gs = [$gender_female, $gender_male, $gender_neuter];
    g = value in (gs.mmap('name));
    if (!g)
        throw(~set, "Gender must be one of: " + ((gs.mmap('name)).to_english("", " or ")));
    return gs[g];
};

protected method .set_gender() {
    arg name, definer, value;
    
    (> .perms(sender(), 'manager) <);
    gender = value;
};

public method .gender() {
    arg @args;
    
    return gender;
};

root method .init_thing() {
    gender = $gender_neuter;
};

public method .gender_context() {
    return gender.pronoun('po);
};

root method .get_lock() {
    arg name, definer;
    
    return lock || (<$true_lock_frob, []>);
};

root method .set_lock() {
    arg name, definer, value;
    
    if (class(value) == $true_lock_frob)
        (| clear_var('lock) |);
    else
        lock = value;
};

root method .parse_lock() {
    arg value;
    
    if (value == "none")
        value = "no";
    else if (value == "self")
        value = "yes";
    return (> $lock_parser.parse(value, this()) <);
};

root method .format_lock() {
    arg value;
    var unparse;
    
    unparse = value.unparse();
    if (unparse == "yes")
        return "self";
    else if (unparse == "no")
        return "none";
    return unparse;
};


new object $command_cache: $has_commands;

var $root child_index = 3;
var $root fertile = 1;
var $root manager = $command_cache;
var $root created_on = 796605573;
var $root inited = 1;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $command_cache shortcut_cache = 0;
var $command_cache remote_cache = 0;
var $command_cache local_cache = 0;
var $has_commands shortcuts = #[];
var $root managed = [$command_cache];
var $root owned = [$command_cache];
var $command_cache interfaces = 0;

root method .uninit_command_cache() {
    var i;
    
    (| .purge_caches() |);
    for i in (interfaces || [])
        i.interface_unlink();
};

public method .rehash_caches() {
    var cmd, obj, part, element;
    
    (> .perms(sender()) <);
    (| .purge_caches() |);
    if (!(.is_command_cache())) {
        // if we are not an official 'cache', just cache commands defined on us
        for cmd in (.local_commands()) {
            for part in (cmd[2])
                .add_to_local_cache(part[1]);
        }
        shortcut_cache = (.shortcuts()).to_list();
    } else {
        // otherwise cache all defined commands
        (> .add_object_to_local_cache(this()) <);
        shortcut_cache = .all_shortcuts();
    }
    
    // remote caches are different, and HAVE to be specific to the user
    if (.is($location)) {
        for obj in ([this()] + (.contents()))
            (> .add_object_to_remote_cache(obj) <);
    }
};

public method .add_object_to_remote_cache() {
    arg obj;
    var info, thing, element, part;
    
    info = (| obj.all_remote_commands() |);
    if (info) {
        for element in (info) {
            for part in (element[2])
                .add_to_remote_cache(part[1], element[1]);
        }
    }
};

public method .purge_caches() {
    (> .perms(sender()) <);
    (| clear_var('shortcut_cache) |);
    (| clear_var('remote_cache) |);
    (| clear_var('local_cache) |);
};

private method .add_object_to_local_cache() {
    arg obj;
    var info, thing, element, part;
    
    info = (| obj.all_local_commands() |);
    if (info) {
        for element in (info) {
            for part in (element[2])
                .add_to_local_cache(part[1]);
        }
    }
    
    // $#Edited: 06 Jan 96 13:18 Lynx ($lynx)
};

protected method .add_to_remote_cache() {
    arg command, definer;
    var part, cmd, value, cmds, defs, refs;
    
    if (type(remote_cache) != 'dictionary)
        remote_cache = #[];
    
    // if this dies, it will also fail on explode_template_word
    cmd = (| (command.explode())[1] |);
    for part in (command.explode_template_word()) {
        if ((value = (| remote_cache[part] |))) {
            cmds = (value[1]).setadd(cmd);
            refs = ((| (value[2])[definer] |) || 0) + 1;
            defs = (value[2]).add(definer, refs);
            remote_cache = remote_cache.add(part, [cmds, defs]);
        } else {
            remote_cache = remote_cache.add(part, [[cmd], #[[definer, 1]]]);
        }
    }
};

protected method .add_to_local_cache() {
    arg command;
    var part, cmd;
    
    if (type(local_cache) != 'dictionary)
        local_cache = #[];
    
    // if this dies, it will also fail on explode_template_word
    cmd = (| (command.explode())[1] |);
    for part in (command.explode_template_word())
        local_cache = local_cache.setadd_elem(part, cmd);
};

public method .match_in_shortcut_cache() {
    arg str, cmd, args;
    var shortcut, match, obj, shorts;
    
    for obj in ([this()] + parents()) {
        if ((shorts = obj.shortcut_cache())) {
            for shortcut in (shorts) {
                match = match_pattern(str, shortcut[1]);
                if (match != 0)
                    return ['shortcut, [(shortcut[2])[1], [str, @$command_lib.handle_shortcut_fields((shortcut[2])[2], match)]]];
            }
        }
    }
    return 0;
};

public method .shortcut_cache() {
    return shortcut_cache;
};

public method .remote_cache() {
    return remote_cache;
};

public method .local_cache() {
    return local_cache;
};

public method .match_in_remote_cache() {
    arg str, cmd, args;
    var cache, definer, command, info, cdef, match, matched, templates;
    
    if (!(cache = (| .find_in_remote_caches(cmd) |)))
        return 0;
    templates = [];
    matched = [];
    for command in (cache[1]) {
        for definer in ((cache[2]).keys()) {
            info = definer.get_command_info('remote, command);
            if (!info)
                continue;
            for cdef in (info) {
                match = args.match_template(cdef[2]);
                if (match != 0)
                    matched += [[match.length(), definer, [str, cmd, @match], @cdef.subrange(3)]];
            }
            templates = templates.union(info.slice(3));
        }
    }
    if (matched) {
        info = [matched[1]];
        matched = matched.delete(1);
        for match in (matched) {
            if ((match[1]) > ((info[1])[1]))
                info = [match];
            else if ((match[1]) == ((info[1])[1]))
                info += [match];
        }
        return ['remote, info];
    }
    return ['partial, templates];
};

public method .match_in_local_cache() {
    arg str, cmd, args;
    var command, match, matched, templates, info, cdef, def;
    
    templates = (matched = []);
    for command in (.find_in_local_caches(cmd)) {
        info = .get_command_info('local, command);
        if (!info)
            continue;
        for cdef in (info) {
            match = match_template(args, cdef[2]);
            if (match != 0)
                matched += [[match.length(), [str, cmd, @match], @cdef.subrange(3)]];
        }
        templates = templates.union(info.slice(3));
    }
    if (matched) {
        info = [matched[1]];
        matched = matched.delete(1);
        for match in (matched) {
            if ((match[1]) > ((info[1])[1]))
                info = [match];
            else if ((match[1]) == ((info[1])[1]))
                info += [match];
        }
        return ['local, info];
    }
    if (!templates)
        return 0;
    return ['partial, templates];
};

public method .find_in_local_cache() {
    arg cmd;
    
    return (> local_cache[cmd] <);
    
    // $#Edited: 08 Jan 96 18:48 Lynx ($lynx)
};

public method .cache_init() {
    if (!(sender().has_ancestor(definer())))
        throw(~nochild, ((sender() + " is not a descendant of ") + definer()) + ".");
    if (.is_command_cache()) {
        if ((!local_cache) || (!remote_cache))
            .rehash_caches();
    }
};

public method .is_command_cache() {
    return 'command_cache in (.flags());
    
    // $#Edited: 06 Jan 96 13:07 Lynx ($lynx)
};

public method .set_as_command_cache() {
    arg makecache;
    
    (> .perms(sender(), 'manager) <);
    if (makecache)
        (> .add_flag('command_cache) <);
    else
        (> .del_flag('command_cache) <);
    
    // $#Edited: 06 Jan 96 13:07 Lynx ($lynx)
};

protected method .find_in_command_cache() {
    arg cmd_word, cache;
    var matches, match, obj, objs;
    
    matches = #[];
    for obj in ([this()] + parents()) {
        match = (| obj.(cache)()[cmd_word] |);
        if (match)
            matches = matches.union(match);
    }
    return matches;
    
    // $#Edited: 08 Jan 96 18:47 Lynx ($lynx)
};

public method .find_in_remote_cache() {
    arg cmd;
    
    return (> remote_cache[cmd] <);
    
    // $#Edited: 08 Jan 96 18:48 Lynx ($lynx)
};

protected method .find_in_local_caches() {
    arg cmd_word;
    var matches, match, obj, objs;
    
    matches = [];
    for obj in (([this()] + parents()) + (interfaces || [])) {
        if ((match = (| obj.find_in_local_cache(cmd_word) |)))
            matches = matches.union(match);
    }
    return matches;
};

public method .find_in_remote_caches() {
    arg cmd_word;
    var matches, match, obj, objs;
    
    matches = [];
    for obj in ([this()] + parents()) {
        if ((match = (| obj.find_in_remote_cache(cmd_word) |)))
            matches = matches.union(match);
    }
    return matches;
    
    // $#Edited: 08 Jan 96 18:51 Lynx ($lynx)
};

public method .cache_uninit() {
    var user;
    
    // if (!.is($user))
    //    throw(~notuser, this() + " is not a user object.");
    if (!(sender().has_ancestor(this())))
        throw(~nochild, ((sender() + " is not a descendant of ") + this) + ".\n");
    if (.is_command_cache()) {
        // see if anybody still needs us, otherwise purge the caches
        for user in ($user_db.connected()) {
            if (user.has_ancestor(this()))
                return;
        }
        .purge_caches();
    }
};

protected method .del_from_remote_cache() {
    arg command, definer;
    var part, cmd, value, cmds, defs, refs;
    
    if (type(remote_cache) != 'dictionary)
        return;
    
    // if this dies, it will also fail on explode_template_word
    cmd = (| (command.explode())[1] |);
    for part in (command.explode_template_word()) {
        if ((value = (| remote_cache[part] |))) {
            refs = ((| (value[2])[definer] |) || 1) - 1;
            if (!refs) {
                remote_cache = remote_cache.del(part);
                if (!remote_cache)
                    (| clear_var('remote_cache) |);
            } else {
                [cmds, defs] = value;
                defs = defs.add(definer, refs);
                remote_cache = remote_cache.add(part, [cmds, defs]);
            }
        }
    }
    
    // $#Edited: 30 Nov 96 20:00 $miro
};

public method .del_object_from_remote_cache() {
    arg obj;
    var info, thing, element, part;
    
    info = (| obj.all_remote_commands() |);
    if (info) {
        for element in (info) {
            for part in (element[2])
                .del_from_remote_cache(part[1], element[1]);
        }
    }
};

public method .interfaces() {
    return interfaces || [];
    
    // $#Edited: 03 Dec 96 12:49 $brandon
};

public method .add_command_interface() {
    arg interface;
    
    if (!(interface.has_flag('command_cache)))
        throw(~perm, ("Command interface " + interface) + " is not setup as a cache.");
    interfaces = setadd(interfaces || [], interface);
    interface.interface_link();
};

public method .del_command_interface() {
    arg interface;
    
    if (!(interface.has_flag('command_cache)))
        throw(~perm, ("Command interface " + interface) + " is not setup as a cache.");
    interfaces = setremove(interfaces || [], interface);
    interface.interface_unlink();
};


new object $user_interfaces: $command_cache;

var $root child_index = 12;
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $has_commands shortcuts = #[];
var $root manager = $user_interfaces;
var $root managed = [$user_interfaces];
var $root owned = [$user_interfaces];
var $user_interfaces links = 0;

public method .interface_link() {
    (> .perms(caller(), $command_cache) <);
    links++;
    if ((!(.local_cache())) || (!(.remote_cache())))
        .rehash_caches();
    
    // $#Edited: 03 Dec 96 13:07 $brandon
};

public method .interface_unlink() {
    (> .perms(caller(), $command_cache) <);
    links--;
    if (links < 1) {
        .purge_caches();
        (| clear_var('links) |);
    }
    
    // $#Edited: 03 Dec 96 13:07 $brandon
};


new object $core: $root;

var $root child_index = 4;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root managed = [$core];
var $root owned = [$core];
var $root manager = $core;


new object $libraries: $core;

var $root child_index = 16;
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root manager = $libraries;
var $root managed = [$libraries];
var $root owned = [$libraries];


new object $dictionary: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $dictionary;
var $root owned = [$dictionary];
var $root managed = [$dictionary];

public method .to_list() {
    arg dict;
    var x;
    
    // merges into an associated list.
    return map x in (dict) to (x);
};

public method .nunion() {
    arg dict1, dict2;
    var key;
    
    // like union() but for dictionaries.  adds any keys from dict2 that don't
    // already exist in dict1 to dict1 and returns the result.  Order of keys in
    // result is not guaranteed.
    if (((dict1.keys()).length()) < ((dict2.keys()).length())) {
        for key in (dict1)
            dict2 = dict_add(dict2, @key);
        return dict2;
    } else {
        for key in (dict2)
            dict1 = dict_add(dict1, @key);
        return dict1;
    }
};

public method .values(): native;

public method .replace() {
    arg dict, key, value;
    
    // GOING AWAY!
    anticipate_assignment();
    return dict_add(dict, key, value);
};

public method .apply() {
    arg tdict, list;
    var x;
    
    // Apply a translation-dict to a list
    for x in [1 .. list.length()] {
        catch ~keynf
            list = list.replace(x, tdict[list[x]]);
    }
    return list;
};

public method .apply_to_keys() {
    arg tdict, dict;
    var x, newdict;
    
    // Apply a t-dict to the keys of a dict
    newdict = #[];
    for x in (dict) {
        catch ~keynf
            x = x.replace(1, tdict[x[1]]);
        newdict = newdict.add(@x);
    }
    return newdict;
};

public method .apply_to_values() {
    arg tdict, dict;
    var x, newdict;
    
    // Apply a t-dict to the values of a dict
    newdict = #[];
    for x in (dict) {
        catch ~keynf
            x = x.replace(2, tdict[x[2]]);
        newdict = newdict.add(@x);
    }
    return newdict;
};

public method .invert() {
    arg dict;
    var x;
    
    // Invert a dict keys and values
    return hash x in (dict) to ([x[2], x[1]]);
};

public method .add_elem() {
    arg dict, key, elem;
    var value;
    
    // Add an element to the list value of a dictionary key
    value = (| dict[key] |);
    if ((type(value) != 'list) && (type(value) != 'error))
        throw(~type, ((("Value for key " + key) + " (") + value) + ") is not a list.");
    anticipate_assignment();
    if (value) {
        // reduce references to 'value'
        dict = dict_add(dict, key, 0);
        value += [elem];
    } else {
        value = [elem];
    }
    return dict_add(dict, key, value);
};

public method .del_elem() {
    arg dict, key, elem;
    var value;
    
    value = (| dict[key] |);
    if ((type(value) != 'list) && (type(value) != 'error))
        throw(~type, ((("Value for key " + key) + " (") + value) + ") is not a list.");
    anticipate_assignment();
    dict = dict_add(dict, key, 0);
    value = setremove(value, elem);
    if (!value)
        return dict_del(dict, key);
    return dict_add(dict, key, value);
};

public method .add(): native;

public method .del(): native;

public method .keys(): native;

public method .contains(): native;

public method .to_trie() {
    arg dict;
    var i, trie;
    
    trie = $trie.new();
    for i in (dict) {
        trie = trie.add(i[1], i[2]);
        refresh();
    }
    return trie;
};

public method .union(): native;

public method .setadd_elem() {
    arg dict, key, elem;
    var value;
    
    value = (| dict[key] |);
    if ((type(value) != 'list) && (type(value) != 'error))
        throw(~type, ((("Value for key " + key) + " (") + value) + ") is not a list.");
    anticipate_assignment();
    if (value) {
        dict = dict_add(dict, key, 0);
        value = setadd(value, elem);
    } else {
        value = [elem];
    }
    return dict_add(dict, key, value);
};


new object $buffer: $libraries;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $buffer;
var $root owned = [$buffer];
var $root managed = [$buffer];

public method .to_list() {
    arg buf;
    var i, list;
    
    return map i in [1 .. buflen(buf)] to (buf[i]);
};

public method .from_list() {
    arg list;
    var buf, i;
    
    // this differs from $list.to_buffer()
    buf = `[];
    for i in (list)
        buf += `[i];
    return buf;
};

public method .length(): native;

public method .to_string(): native;

public method .to_strings(): native;

public method .from_string(): native;

public method .from_strings(): native;

public method .replace(): native;

public method .subrange(): native;

private method .to_veil_pkts(): native;

private method .from_veil_pkts(): native;

public method .break_lines() {
    arg buf;
    var i, sub, out;
    
    // break a buffer by \r or \n but keep its sub contents as buffers
    out = [];
    while ((i = 10 in buf)) {
        sub = subbuf(buf, 1, i - 1);
        buf = subbuf(buf, i + 1);
        while ((i = 13 in sub)) {
            if (buflen(sub) == i)
                sub = subbuf(sub, 1, i - 1);
            else
                sub = subbuf(sub, 1, i - 1) + subbuf(sub, i + 1);
        }
        out += [sub];
    }
    if (buf) {
        while ((i = 13 in buf)) {
            if (buflen(buf) == i)
                buf = subbuf(buf, 1, i - 1);
            else
                buf = subbuf(buf, 1, i - 1) + subbuf(buf, i + 1);
        }
        if (buf)
            out += [buf];
    }
    return out;
};


new object $string: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $string alphabet = "abcdefghijklmnopqrstuvwxyz";
var $string numbers = "0123456789";
var $string non_alphanumeric = "!@#$%^&*()_+-=~`'{}[]|/?\",.<>;: ";
var $root manager = $string;
var $root owned = [$string];
var $string number_names = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];
var $string base64str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
var $root managed = [$string];

public method .left() {
    arg str, width, @fchar;
    
    // will not chop off 'str' if it is longer than width, use pad() for that.
    [(fchar ?= " ")] = fchar;
    if (strlen(str) < width)
        return str + pad("", width - (str.length()), fchar);
    return str;
};

public method .center() {
    arg text, width, @args;
    var fill, sides;
    
    // args[1] <op> == what to fill the left|right side with.
    // args[2] <op> == if exists also fill the right side.
    [(fill ?= " "), (sides ?= 'left)] = args;
    if (sides == 'both)
        return strfmt(("%*{" + fill) + "}c", width, text);
    else
        return pad("", (width - strlen(text)) / 2, fill) + text;
};

public method .trim(): native;

public method .right() {
    arg str, width, @fchar;
    
    // will not chop off 'str' if it is longer than width (unlike pad())
    [(fchar ?= " ")] = fchar;
    if (strlen(str) < width)
        return pad(str, -width, fchar);
    return str;
};

public method .alphabet() {
    return alphabet;
};

public method .numbers() {
    return numbers;
};

public method .capitalize(): native;

public method .is_numeric() {
    arg string;
    
    return toint(string) || (string == "0");
};

public method .a_or_an() {
    arg string;
    
    return $english_lib.indef_article(string);
    if ((string[1]) in "aeiou")
        return "an";
    return "a";
};

public method .strip() {
    arg string, @strip;
    
    anticipate_assignment();
    if (!strip)
        return strsed(string, "[][!@#$%^&*()_+=~`'{}|/?\"\,.<>;: -]", "", "g");
    else
        return strsed(string, ("[" + (strip[1])) + "]", "", "g");
};

public method .non_alphanumeric() {
    return non_alphanumeric;
};

public method .chop() {
    arg str, len, @end;
    
    // chops string off end.length() characters before len and appends len
    [(end ?= "...")] = end;
    if ((strlen(str) < len) || (strlen(str) < strlen(end)))
        return str;
    anticipate_assignment();
    return pad(str, len - strlen(end)) + end;
};

public method .replace(): native;

public method .explode_english_list() {
    arg line, @opts;
    var x, output, tmp;
    
    if (!line)
        return [];
    
    // explodes an english list ("foo, bar and zoo").
    line = line.explode(",");
    output = [];
    for x in (line) {
        x = .trim(x);
        if ((| x.subrange(1, 4) |) == "and ")
            output += [.trim(x.subrange(4))];
        else
            output += [x];
    }
    
    // check the last element, if they didn't specify  'noand
    if (!('noand in opts)) {
        line = (output[output.length()]).explode();
        tmp = "";
        for x in [1 .. line.length()] {
            if ((line[x]) == "and") {
                output = output.delete(output.length());
                if (tmp)
                    output += [tmp];
                tmp = (line.subrange(x + 1)).join();
                if (tmp)
                    output += [tmp];
    
                // only bother with the first "and"
                break;
            }
            tmp = (tmp + (tmp ? " " : "")) + (line[x]);
        }
    }
    return output;
};

public method .explode_delimited() {
    arg str, left, right;
    var pattern, parsed, matched, match_num, match_result;
    
    // parse str looking for anything surrounded by left and right
    // ;$string.explode_delimited("foo<bar>baz", "<", ">")  
    // => [["foo", 1, "baz"], ["bar"]]
    pattern = ((("*" + left) + "*") + right) + "*";
    parsed = [];
    matched = [];
    match_num = 0;
    anticipate_assignment();
    while (str) {
        match_result = match_pattern(str, pattern);
        if (match_result) {
            match_num++;
            parsed += [match_result[1], match_num];
            matched += [match_result[2]];
            str = match_result[3];
        } else {
            parsed += [str];
            str = "";
        }
    }
    return [parsed, matched];
};

public method .wrap_line() {
    arg str, len, @stuff;
    var output, cutoff, firstline, prefix, plen;
    
    // takes string and wraps it by words, compared to length, breaks with \n
    [(prefix ?= ""), (firstline ?= 0)] = stuff;
    output = "";
    if (firstline)
        str = prefix + str;
    plen = strlen(prefix);
    while (strlen(str) > len) {
        cutoff = stridx(substr(str, 1, len), " ", -1);
        if (cutoff <= plen) {
            output += "\n" + substr(str, 1, len);
            str = prefix + substr(str, len + 1);
        } else {
            output += "\n" + substr(str, 1, cutoff - 1);
            str = prefix + substr(str, cutoff + 1);
        }
    }
    return (output ? (output.subrange(3)) + "\n" : "") + str;
};

public method .rindex() {
    arg string, index;
    
    return stridx(string, index, -1);
};

public method .is_boolean() {
    arg str;
    
    if (match_regexp(str, "^(yes|y|true|t|1)$"))
        return 1;
    if (match_regexp(str, "^(no|n|false|f|0)$"))
        return 0;
    return -1;
};

public method .explode(): native;

public method .match_template(): native;

public method .explode_template_word() {
    arg template;
    var t, x, idx, out, new;
    
    // this only explodes single word templates
    template = template.explode("|");
    out = [];
    for t in (template) {
        idx = "?" in t;
        if (idx) {
            t = t.strip("?");
            new = t.subrange(1, idx - 1);
            out += [new];
            for x in [idx .. t.length()] {
                new += t[x];
                out += [new];
            }
        } else {
            out += [t];
        }
    }
    return out;
};

public method .match_pattern(): native;

public method .match_regexp(): native;

public method .to_number() {
    arg str;
    
    if (str.is_numeric())
        return toint(str);
    throw(~nonum, ("\"" + str) + "\" is not a number.");
};

public method .last() {
    arg str;
    
    return str[str.length()];
};

public method .explode_list() {
    arg str;
    
    if (("," in str) || (" and " in str))
        return str.explode_english_list();
    else
        return str.explode();
};

public method .find_escaped() {
    arg str, char;
    var good, start, pos, p;
    
    good = 0;
    start = 0;
    while ((!good) && (start < (str.length()))) {
        pos = (char in (str.subrange(start + 1))) + start;
        good = 1;
        if (pos > start) {
            p = pos - 1;
            while ((p > 0) && ((str[p]) == "\\")) {
                good = good ? 0 : 1;
                p = p - 1;
            }
        }
        if (good)
            return pos;
        else
            start = pos;
    }
};

public method .explode_quoted() {
    arg str;
    var out, result, x, qstr;
    
    out = [];
    
    // HACK: we need to make this a native--its horribly inefficient
    qstr = ("#$#QUOTE-" + time()) + "#$#";
    str = strsub(str, "\\\"", qstr);
    while (str) {
        result = match_pattern(str, "*\"*\"*");
        if (result) {
            out += ((result[1]).explode()) + [(result[2]).trim()];
            str = result[3];
        } else {
            out += str.explode();
            str = "";
        }
    }
    for x in [1 .. listlen(out)]
        out = replace(out, x, strsub(out[x], qstr, "\""));
    return out;
};

public method .strip_article() {
    arg str;
    
    return strsed(str, "^(an|a|the)  *", "", "g");
};

public method .unquote() {
    arg str;
    
    if (str && (((str[1]) == "\"") && ((str[str.length()]) == "\"")))
        return str.subrange(2, (str.length()) - 2);
    return str;
};

public method .to_buffer() {
    arg string;
    
    return (> str_to_buf(string) <);
};

public method .pad(): native;

public method .wrap_lines() {
    arg str, len, @stuff;
    var output, cutoff, firstline, prefix, plen;
    
    // takes string and wraps it by words, compared to length, returns a list. 
    [(prefix ?= ""), (firstline ?= 0)] = stuff;
    output = [];
    if (firstline)
        str = prefix + str;
    plen = strlen(prefix);
    while (strlen(str) > len) {
        cutoff = stridx(substr(str, 1, len), " ", -1);
        if (cutoff <= plen) {
            output += [substr(str, 1, len)];
            str = prefix + substr(str, len + 1);
        } else {
            output += [substr(str, 1, cutoff - 1)];
            str = prefix + substr(str, cutoff + 1);
        }
    }
    return output + [str];
};

public method .length(): native;

public method .subrange(): native;

public method .match_begin(): native;

public method .crypt(): native;

public method .uppercase(): native;

public method .lowercase(): native;

public method .compare(): native;

public method .format(): native;

public method .to_symbol() {
    arg str;
    
    str = lowercase(strsed(str, "[^a-zA-Z0-9_]+", "", "g"));
    return (> tosym(str) <);
};

public method .valid_ident() {
    arg str;
    
    return strsed(str, "[^a-z0-9_]+", "", "g") == str;
};

public method .regexp(): native;

public method .sed(): native;

public method .split(): native;

public method .word(): native;

public method .dbquote_explode(): native;

public method .to_html() {
    arg line;
    
    anticipate_assignment();
    line = strsub(line, "&", "&amp;");
    line = strsub(line, "<", "&lt;");
    line = strsub(line, ">", "&gt;");
    return line;
};

public method .explode_url() {
    arg line;
    var out, args, i;
    
    i = "?" in line;
    if (i) {
        args = substr(line, i + 1);
        line = substr(line, 1, i - 1);
    }
    if (args)
        out = #[['path, explode(line, "/")], ['args, .explode_http_encoding(args)]];
    else
        out = #[['path, explode(line, "/")], ['args, #[]]];
    return out;
};

public method .explode_http_encoding() {
    arg args;
    var fields, field, values;
    
    fields = #[];
    for field in (args.explode("&")) {
        field = field.explode("=");
        if (listlen(field) == 1)
            field = [field[1], ""];
        fields = fields.add(@field);
    }
    return fields;
};

public method .add_indefinite() {
    arg str;
    
    anticipate_assignment();
    return ((str.a_or_an()) + " ") + str;
};

public method .rangeset() {
    arg string, start, len, new;
    
    anticipate_assignment();
    return ((string.subrange(1, start - 1)) + new) + (string.subrange(start + len));
};

public method .decode64() {
    arg enc_chars;
    var i, j, k, ints, out_buf, len;
    
    i = 1;
    out_buf = `[];
    len = enc_chars.length();
    while (i < len) {
        refresh();
        ints = [];
        for j in [1 .. 4] {
            for k in [1 .. 65] {
                if (strcmp(enc_chars[i], base64str[k]) == 0) {
                    ints = [@ints, (k - 1) % 64];
                    break;
                }
            }
            i++;
        }
        out_buf = out_buf + `[(((ints[1]).shleft(2)) % 256) + ((ints[2]).shright(4)), (((ints[2]).shleft(4)) % 256) + ((ints[3]).shright(2)), (((ints[3]).shleft(6)) % 256) + (ints[4])];
    }
    return out_buf.to_string();
    
    // $#Edited: 08 Dec 96 02:12 $user_dizzledorf
    // $#Edited: 08 Dec 96 02:13 $user_dizzledorf
    // $#Edited: 17 Dec 96 13:43 $brad
};

public method .html_escape(): native;

public method .random() {
    arg str;
    
    return str[random(strlen(str))];
    
    // $#Edited: 19 Feb 97 11:22 $brandon
};


new object $command_lib: $libraries;

var $root manager = $command_lib;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $command_lib arg_types = ["this", "any", "any:*", "object", "object:*", "user", "user:*", "descendant of *", "descendant of *:*", "number", "number:*", "objref", "objref:*"];
var $root owned = [$command_lib];
var $root managed = [$command_lib];

public method .get_argument_type() {
    arg type;
    var a, m, opts, o, result, is_list;
    
    o = $object_lib;
    is_list = 0;
    if ((m = type.match_template("list *"))) {
        type = m[2];
        is_list = 1;
    }
    for a in (arg_types) {
        m = match_pattern(type, a);
        if (type(m) == 'list) {
            switch (a) {
                case "descendant of *":
                    result = ['descendant, [(> o.to_dbref(m[1]) <)]];
                case "descendant of *:*":
                    opts = ._parse_option_templates(m[2]);
                    result = ['descendant, [(> o.to_dbref(m[1]) <)] + opts];
                case "number:*", "objref:*", "any:*", "object:*", "user:*":
                    opts = ._parse_option_templates(m[1]);
                    result = [tosym(((a.explode(":"))[1]) + "_opt"), opts];
                default:
                    result = [tosym(a), []];
            }
            return is_list ? ['list, result] : result;
        }
    }
    throw(~command, ("Invalid argument type \"" + type) + "\"");
};

public method .handle_shortcut_fields() {
    arg subs, fields;
    var subbed_list, elem;
    
    subbed_list = [];
    for elem in (subs) {
        if (type(elem) == 'string)
            subbed_list += [elem];
        else if (type(elem) == 'integer)
            subbed_list += [(> fields[elem] <)];
        else
            throw(~type, "Substitution element is of wrong type.");
    }
    return subbed_list;
};

public method .validate_command_template() {
    arg str;
    var cmd, tmp, loc, types, part, relations;
    
    [tmp, types] = str.explode_delimited("<", ">");
    loc = [];
    cmd = [];
    relations = #[];
    for part in (tmp) {
        if (type(part) == 'string)
            cmd += part.explode();
        else
            cmd += [part];
    }
    
    // clean
    for part in [1 .. cmd.length()] {
        if (type(cmd[part]) == 'string) {
            cmd = cmd.replace(part, (cmd[part]).trim());
        } else {
            relations = relations.add(part - 1, (> .get_argument_type(types[cmd[part]]) <));
            cmd = cmd.replace(part, "*");
        }
    }
    cmd = [cmd[1], (cmd.subrange(2)).join()];
    return [cmd, relations];
};

public method .parse_relation() {
    arg left, right;
    var x, str, out;
    
    left = .break_cards(left);
    right = .break_cards(right);
    if ((((left[2]).length()) != ((right[2]).length())) || (!((left[2]).set_equal(right[2]))))
        throw(~invrel, "Left side cards are not equal to the right side.");
    str = "";
    for x in (left[1]) {
        if (type(x) == 'string)
            str += x;
        else if (str && ((str[strlen(str)]) == "*"))
            str += " *";
        else
            str += "*";
    }
    out = [str, @left];
    str = "";
    for x in (right[1]) {
        if (type(x) == 'string)
            str += x;
        else
            str += "*";
    }
    return [out, [str, @right]];
};

public method .unparse_shortcut() {
    arg s;
    var part, line, short, method, args;
    
    line = "";
    [short, [method, args]] = s;
    for part in (args) {
        if (type(part) == 'string)
            line += part;
        else
            line += "%" + part;
    }
    return ((((("\"" + (s[1])) + "\"").left(10)) + " => \"") + line) + "\"";
};

public method .format_commands_long() {
    arg cmds, type, clen;
    var def, name, c, cdef, line, o, cs, dname;
    
    o = [];
    for def in (cmds.keys()) {
        o += [((type + " commands on ") + (def.name())) + ":"];
        for cdef in (cmds[def]) {
            for c in (cdef[2])
                o += [((("  " + (toliteral(c[3]).left(clen))) + ".") + tostr(c[4])) + "()"];
        }
    }
    return o;
};

public method .format_commands_short() {
    arg cmds, type, len;
    var def, name, c, cdef, line, o, cs, dname;
    
    o = [];
    for def in (cmds.keys()) {
        o += [((type + " commands on ") + (def.name())) + ":"];
        cs = [];
        for cdef in (cmds[def]) {
            for c in (cdef[2])
                cs += [("\"" + (c[3])) + "\""];
        }
        o += ((cs.sort()).lcolumnize(len - 2, " ")).prefix("  ");
    }
    return o;
};

public method .break_cards() {
    arg str;
    var card, reg, i, x, cards, out, s;
    
    out = (cards = []);
    while ((reg = match_regexp(str, "(%[0-9]+)"))) {
        if (((reg[2])[1]) != 1)
            out += [@.break_wildcards(str.subrange(1, ((reg[2])[1]) - 1))];
        card = substr(str, @reg[2]);
        str = substr(str, (reg[2]).sum());
        if (!((card[2]).is_numeric()))
            throw(~invcard, "Argument cards must be numeric.");
        card = toint(substr(card, 2));
        cards += [card];
        out += [card];
    }
    if (str)
        out += [str];
    return [out, cards];
};

public method .format_relation() {
    arg relation;
    var x, str;
    
    str = "";
    for x in (relation) {
        if (type(x) == 'integer)
            str = (str + "%") + tostr(x);
        else
            str += x;
    }
    return str;
};

public method .break_wildcards() {
    arg str;
    var out, i, s;
    
    out = [];
    while ((i = "*" in str)) {
        out += [substr(str, 1, i - 1), ""];
        str = str.subrange(i + 1);
    }
    if (str)
        out += [str];
    return out;
};

public method ._parse_option_templates() {
    arg opt;
    var reg, out;
    
    out = [];
    opt = strsed(opt, "^ *", "");
    while (opt) {
        if ((reg = regexp(opt, "^[\+-]([^= ]*)=([^ ]+) *(.*)"))) {
            opt = reg[3];
            out += [delete(reg, 3)];
        } else if ((reg = regexp(opt, "^[\+-]([^ ]+) *(.*)"))) {
            opt = reg[2];
            out += [[reg[1]]];
        } else {
            throw(~invopt, "Option templates must begin with '+' or '-'");
        }
        opt = strsed(opt, "^ *", "");
    }
    return out;
};

public method .arg_types() {
    return arg_types;
};

public method .unparse_shortcut_full() {
    arg s;
    var part, out, short, method, args;
    
    [short, [method, args]] = s;
    out = "";
    for part in (args) {
        if (type(part) == 'string)
            out += ((out ? ", \"" : "\"") + part) + "\"";
        else
            out += ((out ? ", " : "") + "%") + part;
    }
    out = ((("." + method) + "(") + out) + ")";
    return (((("\"" + short) + "\"").left(10)) + " => ") + out;
};


new object $http: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $http errors = #[[400, ["<head><title>400 Bad Request</title></head>", "<body>", "<center><h1>400 Bad Request</h1></center>", "%s", "</body>"]], [403, ["<head><title>403 Permission Denied</title></head>", "<body>", "<center><h1>403 Permission Denied</h1></center>", "%s", "</body>"]], [404, ["<head><title>404 Not Found</title></head>", "<center><h1>404 Not Found</h1></center>", "%s", "</body>"]]];
var $http gateways = #[["describe", "describe?target=the_pit"], ["see", "see?target=the_pit"], ["who", "who"], ["display", "display?target=http"], ["list_method", "list_method?target=%24http.list_method"], ["help", "help?node=help_coldcore"], ["object", "object?target=http"]];
var $http http_methods = ["GET"];
var $http codes = #[[200, "Ok"], [201, "Created"], [202, "Accepted"], [203, "Provisional Information"], [204, "No Content"], [300, "Multiple Choices"], [301, "Moved Permanently"], [302, "Moved Temporarily"], [303, "See Other"], [304, "Not Modified"], [400, "Bad Request"], [401, "Unauthorized"], [402, "Payment Required"], [403, "Forbidden"], [404, "Not Found"], [405, "Method Not Allowed"], [406, "None Acceptable"], [407, "Proxy Authentication Required"], [408, "Request Timeout"], [409, "Conflict"], [410, "Gone"], [500, "Internal Server Error"], [501, "Not Implemented"], [502, "Bad Gateway"], [503, "Service Unavailable"], [504, "Gateway Timeout"]];
var $http html_version = "text/html";
var $root manager = $http;
var $http page_head = [];
var $root owned = [$http];
var $http page_body = "<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#130191\" vlink=\"#100040\" alink=\"#4000bf\">";
var $root managed = [$http];

public method .make_obj_show_href() {
    arg obj, @name;
    var line, oname;
    
    name = name ? name : (("<code>" + obj) + "</code>");
    return ((("<a href=\"/bin/show?target=" + (obj.objname())) + "\">") + name) + "</a>";
};

public method .make_method_href() {
    arg m;
    
    return ((((((("<a href=\"/bin/list_method?target=%%24" + ((m[1]).objname())) + ".") + (m[2])) + "()\">.") + (m[2])) + "(") + (m[3])) + ")</a>";
};

public method .make_object_href() {
    arg obj;
    
    return ((("<code><a href=\"/bin/object?target=" + (obj.objname())) + "\">") + (obj.namef('xref))) + "</a></code>";
};

public method .bin_list_method() {
    arg path, info, header;
    var ref, str_ref, name, obj, code, anc, out, line, x;
    
    ref = (| (info['args])["target"] |);
    if (!ref)
        return [400, .response(400, "Must specify a target method reference")];
    catch any {
        ref = $parse_lib.ref($http.decode(ref), $foundation);
        name = (> tosym(ref[4]) <);
        obj = ref[3];
        anc = obj.find_method(name);
        code = map x in (anc.list_method(name)) to (x.html_escape());
        str_ref = ((obj + ".") + name) + "()";
        out = [("<head><title>" + str_ref) + "</title></head>", page_body, ("<center><h1>" + str_ref) + "</h1></center>", "<hr size=1 noshade><pre>", @code, "</pre>"];
    } with {
        switch (error()) {
            case ~type:
                return [400, ((("Invalid method reference " + obj) + ".") + name) + "()"];
            case ~methodnf:
                line = ((obj + ".") + name) + "()";
                return [400, .response(400, line + " not found.")];
            default:
                return [400, .response(400, (traceback()[1])[2])];
        }
    }
    return [200, out];
};

public method .bin_who() {
    arg @args;
    var who, namel, names, times, idle, realm, x, cols, out, output, line;
    
    out = [("<head><title>Connected users to " + ($motd.server_name())) + "</title></head>", page_body, ("<center><h2>Connected users to <i>" + ($motd.server_name())) + "</i></h2></center></head><body><pre>"];
    who = $user_db.connected();
    names = who.mmap('hname);
    namel = [];
    for x in (who.mmap('name))
        namel += [x.length()];
    cols = (namel.max()) + 1;
    if (cols < 5)
        cols = 5;
    times = who.mmap('connected_time);
    cols = [cols, (times.element_maxlength()) + 1];
    if ((cols[2]) < 7)
        cols = [cols[1], 7];
    idle = who.mmap('idle_time);
    cols += [(idle.element_maxlength()) + 1];
    if ((cols[3]) < 5)
        cols = cols.replace(3, 5);
    realm = who.mmap('realm_name, "text/html");
    out += [((((("<hr size=1 noshade><b>" + ("Name".pad(cols[1]))) + " ") + ("On for".pad(cols[2]))) + " ") + ("Idle".pad(cols[3]))) + " Location", ((((("----".pad(cols[1])) + " ") + ("------".pad(cols[2]))) + " ") + ("----".pad(cols[3]))) + " --------</b>"];
    for x in [1 .. who.length()] {
        line = ((("<b>" + (names[x])) + "</b>") + ("".pad((cols[1]) - (namel[x])))) + " ";
        line = (((line + "<i>") + (times[x])) + ("".pad((cols[2]) - ((times[x]).length())))) + " ";
        line = (((line + (idle[x])) + "</i>") + ("".pad((cols[3]) - ((idle[x]).length())))) + " ";
        line += realm[x];
        out += [line];
    }
    return [200, out];
};

public method .page_head() {
    return page_head;
};

public method .gateways() {
    return gateways;
};

public method .bin_display() {
    arg path, info, header;
    var out, obj, what, args;
    
    args = info['args];
    obj = (| args["target"] |);
    if (!obj)
        return [400, .response(400, "Must specify a target object")];
    obj = (| $object_lib.to_dbref(obj) |);
    if (!obj)
        return [404, .response(404, ("Unable to find object \"" + (args["target"])) + "\"")];
    what = [];
    if ((| args["vars"] |))
        what = setadd(what, 'vars);
    if ((| args["methods"] |))
        what = setadd(what, 'methods);
    return [200, .show_object(obj, what)];
};

public method .page_tail() {
    arg @args;
    var tail;
    
    tail = ("<hr size=1 noshade><a href=\"/\"><b>" + ($motd.server_name())) + "</b></a>";
    if (args)
        return str_to_buf(tail);
    return [tail];
};

public method .http_methods() {
    return http_methods;
};

public method .page_body() {
    return page_body;
};

public method .list_gateways() {
    var out, line, gate;
    
    out = ["<ul>"];
    for gate in (gateways) {
        line = ((("<li><b><a href=\"/bin/" + (gate[2])) + "\">") + (gate[1])) + "</a></b>";
        out += [line];
    }
    return out + ["</ul>"];
};

public method .make_href() {
    arg obj, @args;
    var line, oname, method, name;
    
    oname = obj.objname();
    if (listlen(args))
        name = args[1];
    else
        name = ("<code>$" + oname) + "</code>";
    if (listlen(args) > 1)
        method = args[2];
    else
        method = "/bin/show?target=" + oname;
    return ((("<a href=\"" + method) + "\">") + name) + "</a>";
};

public method .process_bin_request() {
    arg @path;
    var gate, who;
    
    if (!path) {
        return ["text/html", .list_gateways()];
    } else {
        gate = path[1];
        path = path.subrange(2);
        if ("?" in gate) {
            path = [gate.subrange(("?" in gate) + 1), @path];
            gate = gate.subrange(1, ("?" in gate) - 1);
        }
        if (!(gate in (gateways.keys())))
            return ["text/html", .get_error(400, ("Unknown gateway \"" + gate) + "\".")];
        return ["text/html", .(tosym("bin_" + gate))(@path)];
    }
};

public method .bin_describe() {
    arg path, info, header;
    var obj, desc, flags, detail, page, body, name;
    
    obj = (| (info['args])["target"] |);
    if (!obj)
        return [400, .response(400, "Must specify a target object")];
    obj = (| $object_lib.to_dbref(obj) |) || (| $user_db.search(obj) |);
    if (!obj)
        return [404, .response(404, ("Unable to find object \"" + (path[1])) + "\"")];
    detail = (| (info['args])["detail"] |);
    if (detail) {
        detail = $http.decode(detail);
        name = ((obj.name()) + ": ") + detail;
        catch any
            body = (<$ctext_frob, [[(<$format, ["subj", [["level", "2"]], [detail.capitalize()], 'do_subj]>)], #[['this, obj]]]>).append(obj.get_detail(detail));
        with
            body = $http.response(404, ("No such detail '" + detail) + "'");
    } else {
        name = obj.name();
        body = obj.get_description(#[['actor, $no_one]]);
    }
    return [200, .build_page(body, name)];
};

public method .bin_see() {
    arg @args;
    
    return [400, .response(400, "VRML support is pending completion, sorry!")];
};

public method .bin_help() {
    arg path, info, header;
    var node, head, tail, cout, list, n, out, name;
    
    node = (| (info['args])["node"] |);
    if (!node)
        node = "help_coldcore";
    catch ~namenf
        node = (> $object_lib.to_dbref(node) <);
    with
        return [404, .response(404, "Unable to find help node: " + ((info['args])["node"]))];
    head = strings_to_buf([("<head><title>Help: " + (node.node_name())) + "</title></head>", page_body, ("<h2 align=center>" + (node.html_node_name('top))) + "</h2><hr size=1 noshade>"]);
    cout = $parse_lib.filter_ctext(node.body(), #[['formatter, $html_format], ['node, tostr(node)]]);
    tail = "<p><hr size=1 noshade><p align=center>";
    if (node.group()) {
        out = "";
        for n in (((node.parents())[1]).children()) {
            if (n.nolist())
                continue;
            name = (n.name()).word(1, "|");
            if (n == node)
                out += ((out ? "| " : "") + name) + " ";
            else if (n.holder())
                out += (((out ? "| " : "") + "<i>") + name) + "</i> ";
            else
                out += (((((out ? "| " : "") + "<a href=\"/bin/help?node=") + n) + "\">") + name) + "</a> ";
        }
        if (out)
            tail += out;
    }
    tail = str_to_buf(tail + "\n");
    switch (type(cout)) {
        case 'string:
            cout = [cout];
        case 'frob:
            cout = `[];
    }
    return [200, (head + cout) + tail];
};

public method .process_text() {
    arg what;
    var out, l, b;
    
    switch (type(what)) {
        case 'frob:
            return $parse_lib.filter_ctext(what, #[['formatter, $html_format]]);
        case 'list:
            out = `[];
            for l in (what)
                out += .process_text(l);
            return out;
        case 'string:
            // "<br>" == `[60, 98, 114, 62]
            return str_to_buf(what) + `[60, 98, 114, 62, 13, 10];
    }
};

public method .response() {
    arg code, message;
    var name, x;
    
    if (!(name = (| codes[code] |)))
        return .response(500, "We had a booboo!  Invalid code: " + tostr(code));
    if (type(message) == 'string)
        message = [("<p align=center>" + message) + "</p>"];
    return [((("<head><title>" + tostr(code)) + " ") + name) + "</title></head>", page_body, ((("<h1 align=center>" + tostr(code)) + " ") + name) + "</h1>", "<hr size=1 noshade>", @message, @.page_tail()];
};

public method .html_version() {
    return html_version;
};

public method .build_page() {
    arg what, name;
    var out;
    
    return (((`[60, 104, 101, 97, 100, 62, 60, 116, 105, 116, 108, 101, 62] + str_to_buf(name)) + `[60, 47, 116, 105, 116, 108, 101, 62, 60, 47, 104, 101, 97, 100, 62]) + str_to_buf(page_body)) + (.process_text(what));
};

public method .bin_object() {
    arg path, info, header;
    var out, obj, o, line, objs, m;
    
    obj = (| (info['args])["target"] |);
    if (!obj)
        return [400, .response(400, "Must specify a target object")];
    obj = (| $object_lib.to_dbref(obj) |);
    if (!obj)
        return [404, .response(404, ("Unable to find object \"" + ((info['args])["target"])) + "\"")];
    out = [("<head><title>" + (obj.namef('xref))) + "</title></head>", page_body, ("<h1 align=center>" + (.make_display_href(obj, "&methods"))) + "</h1>"];
    line = "<p align=center><b>Parent(s)</b>: " + ((| .make_object_href((obj.parents())[1]) |) || "(none)");
    for o in ((| (obj.parents()).subrange(2) |) || [])
        line += ", " + (.make_object_href(o));
    out += [line + "</p>", "<pre>"];
    objs = obj.children();
    if (obj) {
        out += ["<p align=center><b>Children:</b></p>", "Name                                 Perms  Size    Manager"];
        for o in (objs) {
            m = o.manager();
            if (!valid(o))
                m = toliteral(m);
            else
                m = .make_object_href(m);
            out += [((((((((("<a href=\"/bin/object?target=" + (o.objname())) + "\">") + pad(o.namef('xref), 36)) + "</a>") + " ") + (($object_lib.see_perms(o, ["", ""])).pad(5))) + "  ") + (((o.size()).to_english()).pad(8))) + " ") + m];
        }
    }
    return [200, out + ["</pre>"]];
};

public method ._show_header_objs() {
    arg objs, what;
    var o, line;
    
    if ((objs.length()) > 1) {
        line = (("<b>" + what) + "s</b>: ") + (.make_object_href(objs[1]));
        for o in (objs.subrange(2))
            line += ", " + (.make_object_href(o));
        line += "<br>";
    } else if (objs == 1) {
        line = (("<b>" + what) + "</b>: ") + (.make_object_href(objs[1]));
    } else {
        line = ("<b>" + what) + "</b>: (none)<br>";
    }
    return line;
};

public method ._show_methods() {
    arg obj;
    var methods, types, m, t, out;
    
    types = #[];
    for m in (obj.methods())
        types = types.add_elem(obj.method_access(m), [m] + (obj.method_info(m)));
    
    // hard-listing the types guarantee's their order
    out = [];
    for t in (['root, 'driver, 'public, 'protected, 'private]) {
        if (!(types.contains(t)))
            continue;
        out += [(tostr(t).capitalize()) + " methods:"];
        for m in (types[t])
            out += [strfmt("%5l %4r " + (.make_method_href([obj, m[1], m[2]])), $object_lib.parse_method_flags(m[7]), m[5])];
    }
    return out;
};

public method ._show_variables() {
    arg obj;
    var parent, out, v;
    
    out = [];
    for parent in (obj.data()) {
        if (valid(parent[1])) {
            out += [(parent[1]) + " variables:"];
            if ((parent[1]).has_flag('variables, this())) {
                for v in (parent[2])
                    out += [(("  " + (v[1])) + ": ") + toliteral(v[2])];
            } else {
                out += ["  ** Permission Denied **"];
            }
        } else {
            out += [($object_lib.get_name(parent[1])) + " variables:"];
            for v in (parent[2])
                out += [(("  " + (v[1])) + ": ") + toliteral(v[2])];
        }
        refresh();
    }
    return out;
};

public method .show_object() {
    arg obj, what;
    var out;
    
    out = [("<head><title>ColdC Object Display of " + obj) + "</title></head>", page_body, ("<h1>" + obj) + "</h1>", ("<b>Perms</b>: " + (((.flags()).prefix("+")).join())) + "<br>", ("<b>Size</b>: " + ((obj.size()).to_english())) + " bytes (on disk)<br>", ("<b>Manager</b>: " + (.make_object_href(obj))) + "<br>", ._show_header_objs(obj.writers('literal), "Writer"), ._show_header_objs(obj.parents(), "Parent")];
    if (obj.has_ancestor($located))
        out += [("<b>Location</b>: " + (.make_object_href(obj.location()))) + "<br>"];
    out += ["<p><pre>"];
    if ('methods in what) {
        if (!(obj.has_flag('methods, this())))
            out += ["  ** No permission to list methods **"];
        else
            out += ._show_methods(obj);
    } else {
        out += [((((("  <h3><a href=\"/bin/display?target=" + obj) + "&") + ((['methods] + what).join("=yes&"))) + "=yes\">Display Methods on ") + obj) + "</a></h3>"];
    }
    if ('vars in what) {
        if (!(obj.has_flag('vars, this())))
            out += ["  ** No permission to show variables **"];
        else
            out += ._show_variables(obj);
    } else {
        out += [((((("  <h3><a href=\"/bin/display?target=" + obj) + "&") + ((what + ['vars]).join("=yes&"))) + "=yes\">Display Variables on ") + obj) + "</a></h3>"];
    }
    return out + ["</pre>"];
};

public method .make_display_href() {
    arg obj, @args;
    
    args = args ? args.join("") : "";
    return (((("<a href=\"/bin/display?target=" + (obj.objname())) + args) + "\">") + (obj.namef('xref))) + "</a>";
    
    // $#Edited: 16 Jan 97 18:00 $brad
};

public method .decode(): native;

public method .encode(): native;


new object $object_lib: $libraries;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $object_lib;
var $root owned = [$object_lib];
var $root managed = [$object_lib];

public method .to_dbref() {
    arg obj;
    var dbref;
    
    switch (type(obj)) {
        case 'string:
            if (!obj)
                throw(~invdbref, "Invalid object reference \"\".");
            if ((obj[1]) == "$") {
                obj = obj.subrange(2);
                dbref = (| lookup(tosym(obj)) |);
            } else if ((obj[1]) == "#") {
                obj = substr(obj, 2);
                if (obj.is_numeric())
                    dbref = (| toobjnum(toint(obj)) |);
                else
                    throw(~objnf, ("Cannot find object \"#" + obj) + "\".");
            } else {
                dbref = toint(obj[1]);
                if (dbref || (obj == "0"))
                    dbref = toobjnum(dbref);
                else
                    dbref = (| lookup(obj) |);
            }
            if (!dbref)
                dbref = (> lookup(tosym((obj.replace(" ", "_")).lowercase())) <);
            return dbref;
        case 'objnum:
            return obj;
        default:
            return (> lookup(obj) <);
    }
};

public method .get_name() {
    arg obj, @args;
    var meth;
    
    // get_name(obj, 'method, [args]) (3rd arg must be a list)
    if (!valid(obj))
        return tostr(obj);
    [(meth ?= 'name), (args ?= [])] = args;
    return obj.(meth)(@args);
};

public method .see_perms() {
    arg obj, @args;
    var str, flag, who, encapsulate, flags;
    
    [(encapsulate ?= ["[", "]"])] = args;
    str = encapsulate[1];
    flags = obj.flags();
    if ('core in flags) {
        flags = flags.setremove('core);
        str += "*";
    } else {
        str += "-";
    }
    if ('fertile in flags) {
        flags = flags.setremove('fertile);
        str += "f";
    } else {
        str += "-";
    }
    if ('methods in flags) {
        flags = flags.setremove('methods);
        str += "m";
    } else {
        str += "-";
    }
    if ('variables in flags) {
        flags = flags.setremove('variables);
        str += "p";
    } else {
        str += "-";
    }
    if ('code in flags) {
        flags = flags.setremove('code);
        str += "c";
    } else {
        str += "-";
    }
    for flag in (flags)
        str += (tostr(flag)[1]).uppercase();
    return str + (encapsulate[2]);
};

public method .str_to_objlist() {
    arg args;
    var out, x, obj;
    
    if ("," in args)
        args = args.explode_english_list();
    else
        args = args.explode();
    return .list_to_objlist(args);
};

public method .list_to_objlist() {
    arg args;
    var out, x, obj;
    
    out = #[['valid, []], ['invalid, []]];
    for x in (args) {
        obj = (| .to_dbref(x) |);
        if (obj)
            out = out.add_elem('valid, obj);
        else
            out = out.add_elem('invalid, x);
    }
    return out;
};

public method .parse_method_flags() {
    arg flags;
    
    return (((" " + (('nooverride in flags) ? "!" : "-")) + (('forked in flags) ? "f" : "-")) + (('locked in flags) ? "l" : "-")) + (('native in flags) ? "n" : "-");
};

public method .format_object() {
    arg obj, chop;
    var len, line, out, c;
    
    if (type(obj) == 'frob)
        return ["Frob " + (obj.namef('ref))];
    c = obj.created_on();
    out = ["Object:   " + (obj.namef('xref)), "Created:  " + (c ? ctime(c) : "(Before Time)"), (("Quota:    " + (obj.quota())) + " bytes") + ((obj.quota_exempt()) ? " ** exempt **" : ""), "Perms:    " + (((obj.flags()).prefix("+")).join()), ("Size:     " + ((obj.size()).to_english())) + " bytes (on disk)", "Manager:  " + (.get_name(obj.manager(), 'namef, ['xref]))];
    line = obj.writers('literal);
    if ((line.length()) != 1)
        line = "Writers:  " + (line.to_english("(none)"));
    else
        line = "Writer:   " + ((line[1]).namef('xref));
    if (chop)
        line = line.chop(chop);
    out += [line];
    line = (obj.trusted('literal)) || [];
    if (listlen(line)) {
        line = "Trusts:   " + (line.to_english("(none)"));
        if (chop)
            line = line.chop(chop);
        out += [line];
    }
    line = obj.parents();
    if ((line.length()) > 1)
        line = "Parents:  " + ((line.mmap('namef, 'xref)).to_english());
    else if (!line)
        line = "Parents:  (none)";
    else
        line = "Parent:   " + ((line[1]).namef('xref));
    if (chop)
        line = line.chop(chop);
    out += [line];
    if (obj.has_ancestor($located))
        out += ["Location: " + (.get_name(obj.location(), 'namef, ['xref]))];
    if (obj.is($exit))
        out += [(("Exit:     from " + ((obj.source()).namef('ref))) + " to ") + ((obj.dest()).namef('ref))];
    return out;
};

public method .format_method_header() {
    arg obj, method, opt, flags, access;
    var f;
    
    if (access) {
        // shorten it a little
        access = tostr(access);
        access = strsub(access, "protected", "prot");
        access = strsub(access, "public", "pub");
        opt += ((opt ? " " : "") + "+access=") + access;
    }
    f = flags.join(",");
    
    // shorten it a little
    f = strsub(f, "nooverride", "noover");
    if (f)
        opt += ((opt ? " " : "") + "+flags=") + f;
    return (((("@program " + obj) + ".") + method) + "() ") + opt;
};


new object $integer: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $integer;
var $integer ones = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];
var $integer teens = ["eleven", "twelve", "thirteen", "fourteen", "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"];
var $integer tens = ["ten", "twenty", "thirty", "fourty", "fifty", "sixty", "seventy", "eighty", "ninety"];
var $root owned = [$integer];
var $root managed = [$integer];

public method .n_to_nth() {
    arg number;
    var tens_digit_is_1, ones_digit, single_digit;
    
    if (type(number) != 'integer)
        throw(~type, "Must receive an integer");
    ones_digit = abs(number) % 10;
    tens_digit_is_1 = ((abs(number) / 10) % 10) == 1;
    single_digit = abs(number) < 10;
    if ((ones_digit in [1, 2, 3]) && (!tens_digit_is_1)) {
        switch (ones_digit) {
            case 1:
                return tostr(number) + "st";
            case 2:
                return tostr(number) + "nd";
            case 3:
                return tostr(number) + "rd";
        }
    } else {
        return tostr(number) + "th";
    }
};

public method .parse_range() {
    arg range;
    var r1, r2, reg;
    
    if ("-" in range) {
        reg = regexp(range, "([0-9^#\.]+) *- *([0-9\$\.]+)");
        return [(> ._range_type(reg[1]) <), (> ._range_type(reg[2]) <)];
    } else {
        return [(> ._range_type(range) <), 'none];
    }
    
    // ("1-5") => (1, 5)      -- 1, 5
    // ("1-$") => (1, 'end)   -- 1, 'end (end number)
    // (".-3") => ('cur, 3)   -- 'cur (current number), 3
    // ("^-3") => ('bgn, 3)   -- 'bgn (beginning number), 3
    // ("#-3") => ('bgn, 3)   -- 'bgn (beginning number), 3
};

public method .to_english() {
    arg num;
    var num_str, sign;
    
    // 12500 => "12,500"
    // if (abs(num) < 9999)
    //  return tostr(num);
    sign = num ? abs(num) / num : 1;
    num = abs(num);
    num_str = "";
    while (num > 999) {
        num_str = ("," + (tostr(1000 + (num % 1000)).subrange(2))) + num_str;
        num = num / 1000;
    }
    num_str = tostr(num) + num_str;
    return ((sign == 1) ? "" : "-") + num_str;
};

public method .range() {
    arg x, y;
    var list, element;
    
    // creates a list of every number between x and y 
    list = [];
    for element in [x .. y]
        list += [element];
    return list;
};

public method .to_string() {
    arg @args;
    
    return (> tostr(@args) <);
    
    // $#Edited: 29 Nov 95 19:58 Lynx ($lynx)
};

public method ._range_type() {
    arg type;
    
    switch (type) {
        case "0" .. "9":
            return toint(type);
        case "$":
            return 'end;
        case ".":
            return 'cur;
        case "#", "^":
            return 'bgn;
        default:
            throw(~invrange, ("Invalid range character \"" + type) + "\".", type);
    }
};

public method .and(): native;

public method .or(): native;

public method .xor(): native;

public method .shleft(): native;

public method .shright(): native;

public method .not(): native;

public method .to_english_text() {
    arg number;
    var an, isneg, temp;
    
    an = abs(number);
    isneg = (number < 0) ? "negative " : "";
    if (!number)
        return "zero";
    if (an < 11)
        return isneg + (ones[an]);
    if (an < 20)
        return isneg + (teens[an - 10]);
    if (an < 100)
        return (isneg + (tens[an / 10])) + ((temp = an % 10) ? "-" + (temp.to_english_text()) : "");
    if (an < 1000)
        return ((isneg + (ones[an / 100])) + " hundred") + ((temp = an % 100) ? " " + (temp.to_english_text()) : "");
    if (an < 1000000)
        return ((isneg + ((an / 1000).to_english_text())) + " thousand") + ((temp = an % 1000) ? " " + (temp.to_english_text()) : "");
    if (an < 1000000000)
        return ((isneg + ((an / 1000000).to_english_text())) + " million") + ((temp = an % 1000000) ? " " + (temp.to_english_text()) : "");
    return ((isneg + ((an / 1000000000).to_english_text())) + " billion") + ((temp = an % 1000000) ? " " + (temp.to_english_text()) : "");
    
    // $#Written by: Kipp
    // $#Edited: 25 Aug 96 16:43 $jenner
};


new object $parse_lib: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $parse_lib boolean_strs = [["yes", "true", "1", "on"], ["no", "false", "0", "off"]];
var $root manager = $parse_lib;
var $root owned = [$parse_lib];
var $parse_lib ordinal = ["first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eight", "ninth", "tenth"];
var $root managed = [$parse_lib];

public method .object_match() {
    arg name, @who;
    var msg;
    
    // .object_match("name"[, who])
    // -> 0        name was the empty string
    // -> ~objnf   nothing matched name
    // -> ~ambig   more than one object matched name
    // Attempt to match an object name with who.match_environment().  If one
    // is found, return it.  Else, print a message and return one of the above
    // false values.
    // 'who' defaults to sender().
    who = who ? who[1] : sender();
    if (!name) {
        (| who.tell("You must give the name of something.") |);
        return 0;
    }
    catch ~objnf, ~ambig {
        return who.match_environment(name);
    } with {
        switch (error()) {
            case ~objnf:
                msg = ("I don't see any \"" + name) + "\" here.";
            case ~ambig:
                msg = ("I don't know which \"" + name) + "\" you mean.";
        }
        (| who.tell(msg) |);
        return error();
    }
};

public method .traceback() {
    arg traceback, @args;
    var line, out, pre, lines, cur, x, error;
    
    // $parse_lib.traceback(traceback(), lines, pre);
    // -1 lines represents the full error
    // pre is set to "! " unless otherwise specified.
    [(lines ?= -1), (pre ?= "! "), (error ?= 0)] = args;
    
    // The initial string
    out = [(pre + "=> ") + ((traceback[1])[2])];
    pre += "   ";
    
    // The primary error
    if (error == 0)
        out += [(pre + "Thrown by ") + (._traceback(@(traceback[2]).subrange(2)))];
    else
        out += [(((pre + "Error ") + error) + " caused by ") + (._traceback(@(traceback[2]).subrange(2)))];
    
    // The rest of it
    for x in [1 .. (traceback.length()) - 2] {
        if ((x <= lines) || (lines == (-1))) {
            line = ((traceback[x + 2])[1]) + ": ";
            line += ._traceback(@(traceback[x + 2]).subrange(2));
            out += [pre + line];
        }
    }
    return out;
};

public method ._traceback() {
    arg what, @more;
    var line;
    
    if (more) {
        if ((more[1]) == (more[2]))
            return ((((more[1]) + ".") + what) + "() line ") + (more[3]);
        else
            return ((((((more[2]) + ".") + what) + "() (") + (more[1])) + ") line ") + (more[3]);
    } else {
        return what;
    }
};

public method .range() {
    arg str;
    var out;
    
    out = split(str, " *- *");
    if ((out.length()) == 1) {
        if ("," in str)
            return ['specific, str];
        out = [(> ._range(str) <), 'single];
    } else if ((out.length()) == 2) {
        out = out.replace(1, (> ._range(out[1]) <));
        out = out.replace(2, (> ._range(out[2]) <));
    } else {
        throw(~range, "Invalid range reference.");
    }
    return out;
};

public method ._range() {
    arg str;
    
    if (str.is_numeric()) {
        return toint(str);
    } else {
        switch (str[1]) {
            case "$":
                return 'end;
            case ".":
                return 'current;
            case "^":
                return 'start;
            default:
                throw(~range, "Invalid range reference.");
        }
    }
};

public method .getopt() {
    arg line, @defaults;
    var out, newlist, part, v, opt, t, keys, key, x;
    
    // submit: [["template", value], [...]];
    // => if value is 1, it will take the next part of the string
    // receive: [["template", "flag", bool, value]], [...]]; 
    line = line.explode_quoted();
    out = [];
    newlist = [];
    [(defaults ?= [])] = defaults;
    while (line) {
        [x, @line] = line;
        if (x && ((x[1]) in ["-", "+"])) {
            opt = 0;
            v = "";
            part = x.subrange(2);
            if ("=" in part) {
                part = part.explode("=", 1);
                [part, v] = part;
            }
            for t in (defaults) {
                if (part.match_template(t[1])) {
                    opt = [t[1], part, (x[1]) == "+"];
                    if ((| t[2] |) && ((!v) && line)) {
                        [v, @line] = line;
                        if (v == "=")
                            [(v ?= ""), @line] = line;
                    }
                    opt += [v];
                }
            }
            if (!opt)
                opt = [0, part, (x[1]) == "+", ""];
            out += [opt];
        } else {
            newlist += [x];
        }
    }
    return [newlist, out];
};

public method .buildref() {
    arg type, obj, def, name, @ignore;
    var line;
    
    line = tostr(obj);
    if (obj != def)
        line += ("<" + def) + ">";
    if (type == 'object)
        return line;
    if (type == 'method)
        return ((line + ".") + tostr(name)) + "()";
    if (type == 'variable)
        return (line + ",") + tostr(name);
};

public method .filter_ctext() {
    arg what, @defaults;
    var dic, output;
    
    dic = ([@defaults, #[]][1]).union(#[['receiver, sender()], ['time, 'post], ['formatter, $text_format]]);
    switch (class(what)) {
        case $ctext_frob:
            output = (what.set_vars(dic)).format();
        case $message_frob:
            output = what.format(dic);
        default:
            output = what;
    }
    return output;
};

public method .ref() {
    arg str, @args;
    var def, me, obj, reg, member, match, type, second;
    
    [(me ?= sender())] = args;
    if ((args.length()) > 1)
        match = args[2];
    else
        match = [me, 'match_environment, []];
    if (str == ".") {
        // shortcut
        obj = (> (match[1]).(match[2])("", @match[3]) <);
        return ['object, obj, obj, 0, 0];
    }
    if ((reg = regexp(str, "^(.*)<([^>]*)>(.*)$"))) {
        def = (> (match[1]).(match[2])(reg[2], @match[3]) <);
        str = (reg[1]) + (reg[3]);
    }
    if ((reg = regexp(str, "([^\.,]*)([\.,]+)([^\( ]*)"))) {
        obj = reg[1];
        member = reg[3];
        type = reg[2];
        if (((type.length()) > 1) && (((type[1]) == ".") && (!obj))) {
            type = type.subrange(2);
            obj = (> (match[1]).(match[2])("", @match[3]) <);
        } else {
            obj = obj ? (> (match[1]).(match[2])(obj, @match[3]) <) : me;
        }
        if ("." in type) {
            if ("," in type)
                second = 'variable;
            type = 'method;
        } else {
            type = 'variable;
        }
    } else {
        obj = (> (match[1]).(match[2])(str, @match[3]) <);
        type = 'object;
    }
    return [type, obj, def || obj, member, second];
};

public method .parse_method_access() {
    arg str;
    var t;
    
    for t in (["pub?lic", "pro?tected", "pri?vate", "r?oot", "dr?iver", "f?rob"]) {
        if (match_template(str, t))
            return tosym(t.strip("?"));
    }
    return 'public;
};

public method .parse_method_flags() {
    arg flags;
    var t, out, flag;
    
    out = [];
    for flag in (flags.explode(",")) {
        for t in (["no?override", "l?ocked", "f?orked", "na?tive"]) {
            if (match_template(flag, t))
                out += [tosym(t.strip("?"))];
        }
    }
    return out;
};

public method .html_traceback() {
    arg t, status;
    var line, out, x;
    
    out = ("<h2>" + (((t[1])[2]).to_html())) + "</h2>";
    out += ("<i><b>Thrown by " + (._html_traceback(@t[2]))) + "</b></i><p>";
    for x in [3 .. listlen(t)]
        out += ((("<code><i>" + ((t[x])[1])) + "</i>: ") + (._html_traceback(@t[x]))) + "</code><br>";
    return $http.response(status, out + "</p>");
};

public method ._html_traceback() {
    arg type, what, @more;
    var line;
    
    switch (type) {
        case 'function:
            return ("function <tt>" + what) + "()</tt>";
        case 'opcode:
            return ("operator <tt>" + what) + "</tt>";
        default:
            line = ((("method <tt>" + (more[2])) + ".") + tostr(what)) + "()</tt>";
            if ((more[1]) != (more[2]))
                line = ((line + " (") + (more[1])) + ")";
            line = (line + " line ") + (more[3]);
            return line;
    }
};

public method .ordinal_reference() {
    arg str;
    var rx, num;
    
    if (!(rx = regexp(str, "^ *(first|second|third|fourth|fifth|sixth|seventh|eighth|ninth|tenth|1st|2nd|3rd|[456789]th|10th) *(.*)$")))
        return 0;
    num = toint(rx[1]) || ((rx[1]) in ordinal);
    return [rx[2], num];
    
    // Original code from LamdaMOO, Author Unknown
};

public method .possessive_reference() {
    arg str;
    var rx;
    
    if ((rx = regexp(str, "^my$|^my +(.+)?")))
        return ["me", (| rx[1] |) || ""];
    else if ((rx = regexp(str, "^([^ ]+s?)'s? *(.+)?")))
        return rx;
    return 0;
};

public method .ordinal() {
    return ordinal;
};

public method .ask() {
    arg question, @rx;
    var ans, def;
    
    [(rx ?= "(yes|y)"), (def ?= "")] = rx;
    ans = (sender().prompt(question)).trim();
    ans ?= def;
    if (ans == "@abort")
        throw(~stop, "** Aborted **");
    return match_regexp(ans, rx);
};


new object $code_lib: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $code_lib quotes = [["\"Abandon all hope, ye who enter here.\""], ["\"Pull out Wedge, your not doing any more good back there.\"", "", "- Luke Skywalker, StarWars"], ["\"God is in the details.\""], ["\"I don't practice what I preach,", "because I'm not the type of person I'm preaching too.\"", "", "- Bob Dobbs"], ["\"I haven't shaved for six years.", "I seem to be cursed with a thin beard.\"", "", "- Calvin, Age 6 (of Calvin & Hobbes)"], ["\"I may be a Dreamer, but I'm not the only one.\"", "", "- John Lennon"], ["\"C code.  C code run.  Run, Code, Run!  Please!?\"", "", "- Anonymous C hacker."], ["\"They who dream by day are cognizant of many things", "which escape those who dream only by night.\"", "", "- Edgar Allan Poe"], ["\"The good die first,", "and they whose hearts are dry as a summer dust", "burn to the socket.\"", "", "- William Wordsworth"], ["\"Banning guns to prevent murder", "is like banning word processors to prevent libel.\"", "", "- Unknown"], ["\"You will not be punished for your anger,", "you will be punished by your anger.\"", "", "- Buddha"], ["What part of:", "", "main() { printf(&unix[\"021%six0120\"],(unix)[\"have\"]+\"fun\"-0x60);}", "", "do you not understand?", "", "(taken from the 1987 Obfuscated C Code Contest)"], ["\"The goal of computer science is to build something that will", "last at least until we've finished building it.\""], ["\"Give me ambiguity or give me something else.\""], ["\"We are born naked, wet and hungry. Then things get worse.\""], ["\"Make it idiot proof and someone will make a better idiot.\""], ["\"Lottery: A tax on people who are bad at math.\""], ["\"There's too much blood in my caffeine system.\""], ["\"Artificial Intelligence usually beats real stupidity.\""], ["\"Ever notice how fast MS-Windows runs? Neither did I.\""], ["\"Very funny, Scotty. Now beam down my clothes.\""], ["\"Consciousness: that annoying time between naps.\""], ["\"The gene pool could use a little chlorine.\""], ["\"When there's a will, I want to be in it.\""], ["\"Change is inevitable, except from a vending machine.\""], ["\"MS-Windows is a virus:", "it takes over your computer and makes it run bad.\""], ["\"I have not failed 10,000 times,", "I have sucessfully found 10,000 ways that do not work.\"", "- Thomas Edison"], ["\"The difference between literature and journalism is", "that journalism is unreadable and literature is not read.\"", "", "- Oscar Wilde (1854-1900)"], ["\"The man who reads nothing at all is better educated", "than the man who reads nothing but newspapers.\"", "", "- Thomas Jefferson (1743-1826)"], ["\"In the mind of the beginner, there are many possibilities.", "In the mind of the expert there are few.\"", "", "- Shunryu Suzuki"], ["\"Time is a great teacher, but unfortunately it kills all of its pupils.\"", "", "- Hector Berlioz"], ["\"After I'm dead I'd rather have people ask", "why I have no monument, than why I have one.\"", "", "- Cato the Elder (234-249 B.C.)"], ["\"I loathe people who keep dogs. They are cowards who haven't", "got the guts to bite people themselves.\"", "", "-August Strindberg"], ["\"By the time I'd grown up, I natrually supposed that I'd be grown up.\"", "", "-Eve Babitz"], ["\"Every place has a spirit:", "it may be good, it may be bad", "it can be restful as eternity.", "This place-spirit can inhabit a book, a house, a town, a valley;", "the nature of the spirits is they remain.\"", "", "- William S. Burroughs"], ["\"I have never been lost... but I will admit to being confused for several weeks.\"", "", "- Daniel Boon"], ["Time is what keeps things from happening all at once."], ["According to my calculations the problem doesn't exist."], ["Forget about World Peace ... visualize using your turn signal."], ["Ever stop to think, and forget to start again?"], ["Diplomacy is the art of saying \"nice doggie!\"...till you can find a rock."], ["\"The sign of growing up is being able to form independent opinions,", "The sign of maturity is knowing when they are not wanted.\""]];
var $root manager = $code_lib;
var $root owned = [$code_lib];
var $root managed = [$code_lib];

public method .quotes() {
    return quotes;
};

public method .add_random_quote() {
    arg quote, @from;
    
    if (!($sys.is_admin(sender())))
        throw(~perm, "Sender is not an admin");
    if (type(quote) != 'string)
        throw(~type, "Quote must be given as a string.");
    quote = ("\"" + quote) + "\"";
    quote = quote.wrap_line(70);
    quote = from ? [@quote, "     - " + (from[1])] : quote;
    quotes += [quote];
};

public method .generate_listing() {
    arg who, @args;
    var meths, header, title, i;
    
    // called by one of the who_cmds, does all the grunge work.
    [(title ?= "Connected Users"), (meths ?= [['namef, 'doing], ['connected_time], ['idle_time], ['realm_name]]), (header ?= ["Name", "On for", "Idle", "Location"])] = args;
    header = map i in (header) to ([i, "".pad(i.length(), "-")]);
    
    // if who is empty, only print header
    if (!who)
        return [("--- " + title) + " (0) ---"];
    
    // get values using $list.mmap and format
    return ["--- %l (%l) ---".format(title, who.length()), @map i in (meths) to (who.mmap(@i)).tabulate(header, 0, 1, " ", (| sender().linelen() |) || 79), "---"];
};

public method .random_quote() {
    var which;
    
    which = random(quotes.length());
    if (which)
        return quotes[which];
    return [];
};

public method .valid_email() {
    arg email;
    var host, user, ip, tmp;
    
    email = email.explode("@");
    if ((email.length()) != 2)
        return ['invalid, email, ""];
    [user, host] = email;
    
    // if you want it to lookup the names, remove this return
    // when .hostname() and .ip() don't block this is a viable option
    return ['valid, user, host];
    if (!host)
        return ['invhostname, user, host];
    if (toint(host[1])) {
        tmp = $network.hostname(host);
        if (tmp == "-1")
            return ['invip, user, host];
    } else {
        tmp = $network.ip(host);
        if (tmp == "-1")
            return ['invhostname, user, host];
    }
    return ['valid, user, host];
};

public method .unparse_command() {
    arg command;
    var x, line;
    
    // command should be passed as a list, and can either be a command
    // or shortcut.  This will return a string.
    if ((command.length()) == 2)
        return toliteral(command[1]);
    line = "";
    for x in (command[3]) {
        if (type(x) == 'string)
            line = (line + (line ? " " : "")) + x;
        else
            line = ((line + (line ? " " : "")) + "%") + tostr(x);
    }
    return ((("\"" + (command[1])) + "\" => \"") + line) + "\"";
};

public method .parse_name() {
    arg name;
    var article, args, flag;
    
    // used to parse $has_name names and name templates
    [name, flag] = $parse_lib.getopt(name, [["u?nique"], ["p?roper"], ["n?ormal"]]);
    name = name.join();
    flag = (| flag.last() |) || ["p?roper", "p", 1, ""];
    switch (flag[1]) {
        case "n?ormal":
            article = 'normal;
        case "u?nique":
            article = 'uniq;
        default:
            article = 'prop;
    }
    name = name.split(" *, *");
    return [[name[1], article], name.subrange(2)];
};

public method .random_word() {
    arg @args;
    var len, out, con, vow, rare, c, caps, maxcaps, flag, last, min, max, extra;
    
    [(min ?= 3), (max ?= 10), (extra ?= #[])] = args;
    len = random(max - min) + min;
    out = "";
    con = "bcdfghjklmnprst";
    rare = ["q", "aa", "ee", "oo", "qu", "v", "w", "x", "z", "y"];
    vow = "aeiou";
    if ((| extra['con] |))
        con += extra['con];
    if ((| extra['vow] |))
        vow += extra['vow];
    if ((| extra['rare] |))
        rare += extra['rare];
    flag = random(15);
    maxcaps = random(4) + 2;
    while (strlen(out) < len) {
        switch (flag) {
            case 1, 2:
                if (rare) {
                    c = rare.random();
                    if (random(2) == 1)
                        rare = setremove(rare, c);
                    out += c;
                    flag = random(15);
                }
            case 3 .. 8:
                c = vow.random();
                while (c == last)
                    c = vow.random();
                out += c;
                flag = random(7) + 3;
            case 9 .. 15:
                c = con.random();
                while (c == last)
                    c = con.random();
                out += c;
                flag = random(10);
        }
        last = c;
    }
    return out;
};

public method .punctuation_type() {
    arg str;
    var end;
    
    end = str.length();
    switch (str[end]) {
        case "!":
            return "exclaim";
        case "?":
            return "ask";
        case ".":
            return "say";
        case ")":
            if (end > 1) {
                switch (str[end - 1]) {
                    case ";":
                        return "wink";
                    case ":":
                        return "smile";
                    case "8":
                        return "grin";
                    default:
                        return "say";
                }
            }
        case "(":
            if ((end > 1) && ((str[end - 1]) in [":", "8"]))
                return "frown";
    }
    return "say";
};

public method .verify_code() {
    arg code, method, warn;
    var l, line, m, warns, isadmin, msg;
    
    warns = [];
    method = ("\." + tostr(method)) + "\(";
    isadmin = sender().is($admin);
    for l in [1 .. code.length()] {
        line = code[l];
    
        // if its in a comment, ignore it
        if (match_begin(line, "//"))
            continue;
    
        // required warnings, sorry
        if ((m = line.match_regexp("[^._]anticipate_assignment\(")))
            warns += .point_to_line("WARNING: call to anticipate_assignment()", ((m[1])[1]) + 2, ((m[1])[2]) - 2, l, line);
        if ((m = line.match_regexp("(!)[a-z0-9_]+ in "))) {
            warns += ["WARNING: possible ambiguity, line " + l];
            warns += .point_to_line("WARNING: parenthesis suggested around followup expression to '!'", ((m[2])[1]) + 1, (m[2])[2], l, line);
        }
        if ((m = line.match_regexp("(if *\(|&&|\|\|) *[a-z0-9_]+ *(=)[^=]")))
            warns += .point_to_line("WARNING: parenthesis suggested around assignment expression", ((m[3])[1]) + 1, (m[3])[2], l, line);
    
        // optional warnings
        if (warn && (m = line.match_regexp(method)))
            warns += .point_to_line("WARNING: Possible Recursion", ((m[1])[1]) + 2, ((m[1])[2]) - 2, l, line);
    }
    return warns;
};

public method .generate_object_listing() {
    arg objs, multi, @args;
    var line, obj, col, name, fmt, out;
    
    if (!objs) {
        out = ["** None **"];
    } else {
        col = ((| sender().linelen() |) || 79) / 10;
        fmt = ((((("%3L%" + tostr(col * 4)) + "L %") + tostr(col)) + "L %") + tostr(col)) + "R ";
        out = [strfmt(fmt, "#", "Name", "Perms", "Size") + "Manager"];
        col = col * 4;
        for obj in (objs) {
            line = strfmt(fmt, obj.(multi)(@args).length(), obj.namef('xref), $object_lib.see_perms(obj, ["", ""]), obj.size());
            name = (obj.manager()).namef('xref);
            if ((name.length()) > col)
                name = name.pad(col);
            out += [line + name];
        }
    }
    return out;
};

public method .point_to_line() {
    arg err, left, right, lineno, line;
    var out;
    
    return [((err + ", line ") + lineno) + ":", "  " + line, strfmt("%*{-}l%*{^}l", left, "", right, "")];
};

public method ._debug_listing() {
    arg list;
    var indent, i, out, t, j;
    
    indent = "";
    out = [" Tick#  Event", " -----  -----------------------------"];
    t = 0;
    for i in (list) {
        if (type(i) == 'integer) {
            if (indent)
                indent = indent.subrange(3);
            out += [strfmt("%6r  %lreturn", i - t, indent)];
        } else {
            if (!t)
                t = i[1];
            j = strfmt("%6r  %l%l(%l)", (i[1]) - t, indent, ._show_ref(i), (toliteral(i[5]).match_pattern("[*]"))[1]);
            out += [j];
            indent += "  ";
        }
        refresh();
    }
    return out;
    
    // $#Edited: 07 Feb 97 03:44 $miro
    // $#Edited: 17 Mar 97 01:02 $brad
};

public method .generate_debug_listing() {
    arg info, mode;
    
    return .(tosym(("_" + tostr(mode)) + "_listing"))(info);
};

public method ._trace_listing() {
    arg list;
    var indent, i, out, t, j;
    
    indent = "";
    out = [" Tick#  Event", " -----  -----------------------------"];
    t = 0;
    for i in (list) {
        if (type(i) == 'integer) {
            if (indent)
                indent = indent.subrange(3);
        } else {
            if (!t)
                t = i[1];
            j = strfmt("%6r  %l%l", (i[1]) - t, indent, ._show_ref(i));
            out += [j.chop(79)];
            indent += "  ";
        }
        refresh();
    }
    return out;
    
    // $#Edited: 22 Feb 97 03:06 $brad
};

public method ._trace_profile() {
    arg list;
    var i, out, ref, times, sums, callers, t, tic, max, start;
    
    out = ["Object<definer>.method                               Tics  (%)  Cummul. (%)"];
    times = #[];
    sums = #[];
    callers = [];
    for i in (list) {
        refresh();
        if (type(i) == 'integer) {
            if (callers) {
                [[ref, tic], @callers] = callers;
                times = times.add(ref, (((| times[ref] |) || 0) + (i[1])) - t);
                sums = sums.add(ref, (((| sums[ref] |) || 0) + (i[1])) - tic);
            }
            t = i;
        } else {
            if (callers) {
                ref = (callers[1])[1];
                times = times.add(ref, (((| sums[ref] |) || 0) + (i[1])) - t);
            }
            ref = strfmt("%l<%l>.%l", i[2], i[3], i[4]);
            callers = [[ref, i[1]], @callers];
            t = i[1];
        }
        start ?= t;
    }
    max = 0.01 * (t - start);
    out = map i in (times.keys()) to (refresh() && [i, times[i], (times[i]) / max, sums[i], (sums[i]) / max]);
    out = out.sort(out.slice(2));
    out = map i in (out) to (strfmt(i, "%50l%7r%7r%7r%7r"));
    return out;
};

public method ._profile_listing() {
    arg list;
    var i, out, ref, times, sums, callers, t, tic, max, start, head;
    
    head = ["Object<definer>.method                               Tics    (%)  Total    (%)", "----------------------                               ----    ---  -----    ---"];
    times = #[];
    sums = #[];
    callers = [];
    for i in (list) {
        refresh();
        if (type(i) == 'integer) {
            if (callers) {
                [[ref, tic], @callers] = callers;
                times = times.add(ref, (((| times[ref] |) || 0) + i) - t);
                if (!(ref in callers))
                    sums = sums.add(ref, (((| sums[ref] |) || 0) + i) - tic);
            }
            t = i;
        } else {
            if (callers) {
                ref = (callers[1])[1];
                times = times.add(ref, (((| times[ref] |) || 0) + (i[1])) - t);
            }
            ref = ._show_ref(i);
            callers = [[ref, i[1]], @callers];
            t = i[1];
        }
        start ?= t;
    }
    max = 0.01 * (t - start);
    out = map i in (times.keys()) to (refresh() && [i.chop(50), times[i], (times[i]) / max, sums[i], (sums[i]) / max]);
    out = out.sort(map i in (out) to (-(i[2])));
    out = map i in (out) to (strfmt("%50l%7r%6.1r%%%7r%6.1r%%", @i));
    out = head + out;
    return out;
};

public method ._show_ref() {
    arg i;
    
    return ((i[2]) != (i[3])) ? strfmt("%l<%l>.%l()", i[2], i[3], i[4]) : strfmt("%l.%l()", i[2], i[4]);
};

public method .valid_message_id() {
    arg str;
    
    return !match_regexp(str, "[^a-z0-9-]");
};

public method .random_password() {
    var len, out, con, vow, rare, num, c, caps, maxcaps, flag, last;
    
    len = random(5) + 7;
    out = "";
    con = "bcdfghjklmnprst";
    rare = ["q", "aa", "ee", "oo", "qu", "v", "w", "x", "z", "y"];
    vow = "aeiou";
    num = "1234567890";
    flag = random(15);
    maxcaps = random(4) + 2;
    while (strlen(out) < len) {
        switch (flag) {
            case 1:
                c = num.random();
                out += c;
                flag = random(15);
            case 2, 3:
                if (rare) {
                    c = rare.random();
                    if (random(2) == 1)
                        rare = setremove(rare, c);
                    out += c;
                    flag = random(15);
                }
            case 4 .. 8:
                c = vow.random();
                while (c == last)
                    c = vow.random();
                out += c;
                flag = random(7) + 3;
            case 9 .. 15, -1:
                c = con.random();
                while (c == last)
                    c = con.random();
                out += c;
                flag = random(10);
            case -15 .. -9:
                c = con.random();
                while (c == last)
                    c = con.random();
                out += uppercase(c);
                flag = random(10);
            case -8 .. -4:
                c = vow.random();
                while (c == last)
                    c = vow.random();
                out += uppercase(c);
                flag = random(7) + 3;
            case -3, -2:
                if (rare) {
                    c = rare.random();
                    if (random(2) == 1)
                        rare = setremove(rare, c);
                    out += uppercase(c);
                    flag = random(15);
                }
        }
        last = c;
        if ((caps < maxcaps) && (random(10) == 1)) {
            caps++;
            flag = -flag;
        }
    }
    return out;
};

public method .valid_setting_id() {
    arg str;
    
    return !match_regexp(str, "[^@a-z0-9-]");
};


new object $list: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $list;
var $root help_node = $help_obj_list;
var $root owned = [$list];
var $root managed = [$list];

public method .to_english() {
    arg list, @options;
    var empty, and, sep;
    
    [(empty ?= "nothing"), (and ?= " and "), (sep ?= ", ")] = options;
    switch (list.length()) {
        case 0:
            return empty;
        case 1:
            return tostr(list[1]);
    }
    return (join(list.delete(list.length()), sep) + and) + tostr(list[list.length()]);
};

public method .mmap() {
    arg list, method, @args;
    var x;
    
    // call 'method on each object, return results.
    return map x in (list) to (x.(method)(@args));
};

public method .mfilter() {
    arg list, method, @args;
    var x;
    
    // similar to .mmap, but returns a list of objects which returned a
    // true value from 'method.
    return filter x in (list) where (x.(method)(@args));
};

public method .sort(): native;

public method .columnize() {
    arg list, cols, @rest;
    var width, lines, line, separator, linelength, curcol;
    
    // turn [...] into ".   .   ."
    // rest[1]==separator; rest[2]==linelength
    [(separator ?= "   "), (linelength ?= 78)] = rest;
    width = (linelength / cols) - (separator.length());
    lines = [];
    while (list) {
        line = (list[1]).pad(width);
        list = list.subrange(2);
        for curcol in [2 .. cols] {
            if (list) {
                line = (line + separator) + ((list[1]).pad(width));
                list = list.subrange(2);
            }
        }
        lines += [line];
    }
    return lines;
};

public method .reverse() {
    arg list;
    var i, len;
    
    // .reverse(list)
    // -> list with its elements reversed
    len = (list.length()) + 1;
    return map i in [1 .. len - 1] to (list[len - i]);
};

public method .compress() {
    arg list;
    var x;
    
    // [a,a,b,b,c,c,d,d] => [a,b,c,d]
    // removes duplicate entries in a list
    return hash x in (list) to ([x, 1]).keys();
};

public method .last() {
    arg list;
    
    return list[listlen(list)];
};

public method .count() {
    arg list, elem;
    var count, i;
    
    // count of elem in list
    for i in (list) {
        if (i == elem)
            count++;
    }
    return count;
};

public method .element_maxlength() {
    arg list;
    var i, s, t;
    
    s = 0;
    for i in (list) {
        if ((t = strlen(tostr(i))) > s)
            s = t;
    }
    return s;
};

public method .nth_element_maxlength() {
    arg lists, element;
    var list;
    
    // Returns longest string whose index is element in one of the lists in
    // lists.
    if (type(element) != 'integer)
        throw(~type, "Second argument is not an integer");
    if (type(lists) != 'list)
        throw(~type, "First argument is not a list");
    return map list in (lists) to (tostr(list[element]).length()).max();
};

public method .numbered_text() {
    arg text;
    var line;
    
    // receives a list of strings, returns that list with line numbers
    // prepended
    return map line in [1 .. text.length()] to ("%3r: %l".format(line, text[line]));
};

public method .slice() {
    arg big_list, element;
    var list, i;
    
    // Return elementh' element of all lists in big_list
    // No type or length checking done for speed purposes.
    // element can be a list, in which cases, a list of list is returned
    if (type(element) == 'integer)
        return map list in (big_list) to (list[element]);
    else
        return map list in (big_list) to (map i in (element) to (list[i]));
};

public method .swap() {
    arg list, a, b;
    var holder;
    
    // swap elements at indexes a and b
    if ((listlen(list) < a) || ((listlen(list) < b) || ((a < 1) || (b < 1))))
        throw(~args, "Index specifiers are outside the range of the list.");
    anticipate_assignment();
    holder = list[a];
    list = replace(list, a, list[b]);
    list = replace(list, b, holder);
    return list;
};

public method .max() {
    arg list;
    
    return (| max(@list) |) || 0;
};

public method .min() {
    arg list;
    
    return (| min(@list) |) || 0;
};

public method .lcolumnize() {
    arg list, @args;
    var line, part, lines, max, cols, col, width, len, sep;
    
    [(len ?= (| sender().linelen() |) || 78), (sep ?= " ")] = args;
    lines = [];
    line = "";
    max = (.element_maxlength(list)) + (sep.length());
    cols = (len > max) ? len / max : 1;
    width = (len / cols) - (sep.length());
    col = cols;
    for part in (list) {
        col = col - 1;
        if (!col) {
            lines = lines + [line + part];
            line = "";
            col = cols;
            continue;
        }
        line = line + (part.pad(width));
    }
    if (line)
        return lines + [line];
    return lines;
};

public method .mmap_objects() {
    arg list, method, @args;
    var x;
    
    return map x in (list) to ((type(x) == 'objnum) ? x.(method)(@args) : x);
};

public method .map_to_english() {
    arg list, method, @args;
    
    return .to_english(.mmap(list, method, @args));
};

public method .map_to_string() {
    arg list, method, @args;
    
    return .join(.mmap(list, method, @args));
};

public method .flatten() {
    arg list;
    var toret, elem;
    
    // [[[x], x], x]   =>   [x, x, x]
    toret = [];
    for elem in (list) {
        if (type(elem) == 'list)
            toret += .flatten(elem);
        else
            toret += [elem];
    }
    return toret;
};

public method .sum() {
    arg data;
    var ret, i;
    
    // returns a sum of each element in the list.
    [ret, @data] = data;
    for i in (data)
        ret += i;
    return ret;
    
    // $#Edited: 07 Dec 96 15:18 $miro
};

public method .numbers() {
    // returns a list of numbers
    return ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"];
};

public method .center_lines() {
    arg lines, width, @args;
    var line, fmt;
    
    fmt = ("%" + width) + "c";
    return map line in (lines) to (strfmt(fmt, line));
};

public method .to_buffer() {
    arg @args;
    
    return (> strings_to_buf(@args) <);
};

public method .delete(): native;

public method .replace(): native;

public method .chop() {
    arg list, @count;
    
    // chops the last <count> elements off the list.
    // return [] if count is longer then the list.
    count = count || 1;
    anticipate_assignment();
    return (| sublist(list, 1, listlen(list) - count) |) || [];
};

public method .join(): native;

public method .lmap() {
    arg list, method, @args;
    var x, s;
    
    // call methods for each thing in list on sender()
    s = sender();
    return map x in (list) to (s.(method)(x, @args));
};

public method .length(): native;

public method .union(): native;

public method .omap() {
    arg list, object, method, @args;
    var obj;
    
    // calls object.method(obj, @args) for each obj in list
    return map obj in (list) to (object.(method)(obj, @args));
};

public method .del() {
    arg list, element;
    
    return (> setremove(list, element) <);
};

public method .add() {
    arg list, element;
    
    return (> setadd(list, element) <);
};

public method .set_difference() {
    arg @args;
    var set, list, element;
    
    // Usage:  diff(set 1, set 2, ..., set n)
    // Returns all elements of set 1 that are not in sets 2..n
    if (!args)
        return [];
    set = args[1];
    anticipate_assignment();
    for list in (delete(args, 1)) {
        for element in (list)
            set = setremove(set, element);
    }
    return set;
};

public method .set_contains() {
    arg @args;
    var super, list, element;
    
    // True if the first list given is a superset of all subsequent lists.
    // False otherwise.  [] is a superset of [] and nothing else; anything is
    // a superset of [].  If only one list is given, return true.
    super = args ? args[1] : [];
    for list in (delete(args, 1)) {
        for element in (list) {
            if (!(element in super))
                return 0;
        }
    }
    return 1;
};

public method .set_equal() {
    arg set1, set2;
    var e, dict1, dict2;
    
    // True if the two lists given contain the same elements.
    // False otherwise.
    dict1 = hash e in (set1) to ([e, 1]);
    dict2 = hash e in (set2) to ([e, 1]);
    for e in (dict1.keys()) {
        if (!dict_contains(dict2, e))
            return 0;
    }
    for e in (dict2.keys()) {
        if (!dict_contains(dict1, e))
            return 0;
    }
    return 1;
};

public method .fold() {
    arg list, object, method, @args;
    var i, out;
    
    // apply object.method to a current result and the next element, return the
    // result
    switch (list.length()) {
        case 0:
            return 0;
        case 1:
            return list[1];
    }
    out = list[1];
    for i in (sublist(list, 2, listlen(list) - 1))
        out = object.(method)(out, i, @args);
    return out;
};

public method .setadd(): native;

public method .set_intersection() {
    arg l1, l2;
    var i, out;
    
    // set intersection if the arguments
    out = [];
    for i in (l1) {
        if (i in l2)
            out = out.setadd(i);
    }
    return out;
};

public method .setremove(): native;

public method .insert(): native;

public method .subrange(): native;

public method .prefix() {
    arg list, prefix;
    var elem;
    
    return map elem in (list) to (prefix + elem);
};

public method .valid_objects() {
    arg list;
    var obj;
    
    return filter obj in (list) where (valid(obj));
};

public method .grep() {
    arg lines, regexp;
    var line, result, out, reg;
    
    out = [];
    for line in [1 .. lines.length()] {
        if ((reg = match_regexp(lines[line], regexp)))
            out += [[line, reg, lines[line]]];
    }
    return out;
};

public method .vcolumnize() {
    arg list, cols, @rest;
    var linelength, sep, width, lines, i, j, line, outlist;
    
    [(linelength ?= (| sender().linelen() |) || 78), (sep ?= " ")] = rest;
    lines = ((list.length()) / cols) + (((list.length()) % cols) ? 1 : 0);
    width = linelength / cols;
    return ._vcolumnize(list, lines, cols, width, sep);
};

public method .make() {
    arg n, @elt;
    var i;
    
    [(elt ?= 0)] = elt;
    return map i in [1 .. n] to (elt);
};

public method ._vcolumnize() {
    arg list, lines, cols, width, @other;
    var outlist, line, i, j, sep;
    
    [(sep ?= " ")] = other;
    width -= sep.length();
    lines = (lines > (list.length())) ? list.length() : lines;
    outlist = [];
    for i in [1 .. lines] {
        line = (list[i]).pad(width);
        for j in [1 .. cols]
            (| (line = (line + sep) + ((list[i + (j * lines)]).pad(width))) |);
        outlist += [line];
    }
    return outlist;
};

public method .affix() {
    arg l1, l2;
    var last, first;
    
    // Combines l1 and l2 by appending the first element of l2 to the last
    // of l1.
    if (type(l2) != 'list)
        l2 = [l2];
    last = (| l1.last() |) || "";
    first = (| l2[1] |) || "";
    l1 = [@l1.chop(), last + first];
    if ((l2.length()) > 1)
        l1 += l2.subrange(2);
    return l1;
};

public method .addkey() {
    arg l, key, val;
    var i;
    
    i = find i in [1 .. l.length()] where (((l[i])[1]) == key);
    anticipate_assignment();
    return i ? replace(l, i, [key, val]) : (l + [[key, val]]);
};

public method .delkey() {
    arg l, key;
    var i;
    
    i = find i in [1 .. l.length()] where (((l[i])[1]) == key);
    anticipate_assignment();
    return i ? delete(l, i) : l;
};

public method .getkey() {
    arg l, key;
    var i, x;
    
    if (!(x = find i in [1 .. l.length()] where (((l[i])[1]) == key)))
        throw(~keynf, "Key not found.");
    return (l[x])[2];
};

public method .getkey_index() {
    arg l, key;
    var i, x;
    
    if (!(x = find i in [1 .. l.length()] where (((l[i])[1]) == key)))
        throw(~keynf, "Key not found.");
    return x;
};

public method .setremove_all() {
    arg list, remove;
    var part;
    
    if (type(list) != 'list)
        throw(~type, "First argument must be a list.");
    if (type(remove) != 'list)
        throw(~type, "Second argument must be a list.");
    anticipate_assignment();
    for part in (remove)
        list = setremove(list, part);
    return list;
};

public method .vcolumnize2() {
    arg list, lines, @rest;
    var linelength, sep, cols, width, i, j, line, outlist;
    
    [(linelength ?= (| sender().linelen() |) || 78), (sep ?= " ")] = rest;
    cols = ((list.length()) / lines) + (((list.length()) % lines) ? 1 : 0);
    width = linelength / cols;
    return ._vcolumnize(list, lines, cols, width, sep);
};

public method .vcolumnize3() {
    arg list, lines, @rest;
    var linelength, cols, width, i, j, line, outlist;
    
    [(linelength ?= (| sender().linelen() |) || 78)] = rest;
    cols = ((list.length()) / lines) + (((list.length()) % lines) ? 1 : 0);
    width = linelength / cols;
    outlist = [];
    for i in [1 .. lines] {
        line = "";
        for j in [0 .. cols]
            (| (line = line + ((list[i + (j * lines)]).pad(width))) |);
        outlist += [line];
    }
    return outlist;
};

public method .vcolumnize4() {
    arg list, @args;
    var linelength, sep, lines, cols, width, max;
    
    [(linelength ?= (| sender().linelen() |) || 79), (sep ?= " ")] = args;
    max = (.element_maxlength(list)) + (sep.length());
    cols = (linelength > max) ? linelength / max : 1;
    width = linelength / cols;
    lines = ((list.length()) / cols) + (((list.length()) % cols) ? 1 : 0);
    return ._vcolumnize(list, lines, cols, width, sep);
};

public method .random() {
    arg list;
    
    return list[random(listlen(list))];
};

public method .to_dict() {
    arg list;
    var a;
    
    return hash a in (list) to (a);
};

public method .match_nth() {
    arg objs, str, nth;
    var obj, n;
    
    n = nth;
    for obj in (objs) {
        if (obj.match_name(str)) {
            if (!--n)
                return obj;
        }
    }
    throw(~match, ((("There are not " + ((.numbers())[nth])) + " ") + str) + "'s available.");
};

public method .match_object() {
    arg objs, str;
    var obj, found;
    
    found = [];
    for obj in (objs) {
        if (obj.match_name(str))
            found += [obj];
    }
    if (listlen(found) == 1)
        return found[1];
    if (listlen(found) > 1)
        throw(~ambig, "ambiguous match", found);
    throw(~objnf, "Object not found.");
};

public method .tabulate() {
    arg list, headers, @rest;
    var i, j, t, t1, trim_cols, header_sep, colsizes, len;
    
    if (!list)
        return [];
    [(colsizes ?= 0), (trim_cols ?= 0), (header_sep ?= " "), (len ?= 79)] = rest;
    if (!headers)
        headers = .make(list.length(), []);
    if (type(headers[1]) == 'string)
        headers = map i in (headers) to ([i]);
    
    // Find the column sizes
    if (!colsizes) {
        if (trim_cols) {
            t = map i in (list) to (refresh() && ((i.element_maxlength()) + 2));
            t1 = filter i in [1 .. t.length()] where ((t[i]) > 2);
            t = map i in (t1) to (t[i]);
            list = map i in (t1) to (list[i]);
            headers = map i in (t1) to (headers[i]);
        }
        colsizes = t ? map i in [1 .. headers.length()] to (refresh() && max(t[i], ((headers[i]).element_maxlength()) + 2)) : map i in [1 .. list.length()] to (refresh() && (max((headers[i]).element_maxlength(), (list[i]).element_maxlength()) + 2));
    }
    t = map i in (colsizes) to (("%" + i) + "l").sum();
    t1 = map i in (colsizes) to (((("%" + i) + "{") + header_sep) + "}l").sum();
    
    // Now format the thing...
    return map i in (headers.transpose()) to (refresh() && ((t1.format(@i)).pad(len))) + map i in (list.transpose()) to (refresh() && ((t.format(@i)).pad(len)));
};

public method .transpose() {
    arg list;
    
    return $math.transpose(list);
};

public method .format() {
    arg list, format;
    
    return strfmt(format, @list);
    
    // $#Edited: 28 Feb 97 07:39 $miro
};


new object $help_lib: $libraries;

var $root manager = $help_lib;
var $root created_on = 805931416;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $help_lib default_node = $help_coldcore;
var $root managed = [$help_lib];
var $root owned = [$help_lib];
var $help_lib indices = [$help_index_core, $help_index_cmds, $help_index_driver, $help_index_subsystem, $help_index_function, $help_index_objects];

public method .default_node() {
    return default_node;
};

public method .history_cap() {
    return 15;
};

public method .group_nodes_in_html() {
    arg nodes, noemph, @args;
    var name, names, n;
    
    names = [];
    for n in (nodes) {
        if (n in noemph)
            name = n.name();
        else
            name = .node_name_in_html(n);
        names += [name];
    }
    return names.to_english(@args);
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .node_name_in_html() {
    arg node;
    
    return ((("<a href=\"/bin/help?" + node) + "\">") + (node.name())) + "</a>";
};

public method .indices() {
    return indices;
    
    // $#Edited: 15 Nov 96 11:02 $brandon
};

public method .set_indices() {
    arg @new;
    var o;
    
    (> .perms(sender()) <);
    if (filter o in (new) where ((type(o) != 'objnum) || (!(o.is($help_index)))))
        throw(~type, "Arguments must be $help_index objects.");
    
    // do this all at once so you can manage the order
    indices = new;
};


new object $misc: $core;

var $root child_index = 47;
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root manager = $misc;
var $root managed = [$misc];
var $root owned = [$misc];


new object $mail_root: $misc;

var $root child_index = 3;
var $root fertile = 1;
var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root manager = $mail_root;
var $root owned = [$mail_root];
var $root managed = [$mail_root];


new object $mail_list: $mail_root, $has_name;

var $root child_index = 2;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $has_name name = ['uniq, "mail_list", "the mail_list"];
var $mail_list notify = [$mail_list];
var $mail_list last_received_on = 0;
var $mail_list senders = 1;
var $mail_list mail = [];
var $mail_list readers = 1;
var $root trusted_by = [$mail_db];
var $root manager = $mail_list;
var $root managed = [$mail_list];
var $root owned = [$mail_list];

public method .del_sender_from_notification() {
    var who;
    
    who = sender();
    if (!(who.has_ancestor($user)))
        throw(~type, "Sender is not a user.");
    if (!(.has_flag('sender, who)))
        throw(~perm, ((who.name()) + " cannot read ") + (.mail_name()));
    notify = notify.setremove(who);
};

public method .add_sender_to_notification() {
    var who;
    
    who = sender();
    if (!(who.has_ancestor($user)))
        throw(~type, "Sender is not a user.");
    if (!(.has_flag('sender, who)))
        throw(~perm, ((who.name()) + " cannot read ") + (.mail_name()));
    notify = setadd(notify, who);
};

public method .list_is_sendable_by() {
    arg who;
    
    if (.is_writable_by(who))
        return 1;
    if (type(senders) == 'list)
        return who in senders;
    return senders;
};

public method .list_is_readable_by() {
    arg who;
    
    if (.is_writable_by(who))
        return 1;
    if (type(readers) == 'list)
        return who in readers;
    return readers;
};

public method .set_name() {
    arg new_name, @args;
    var old_name;
    
    old_name = .name();
    if (new_name && ((new_name[1]) == "*"))
        new_name = new_name.subrange(2);
    (> pass(new_name, @args) <);
    (| $mail_db.key_changed(old_name, new_name) |);
};

public method .start() {
    if (!(.list_is_readable_by(sender())))
        throw(~perm, ("Sender cannot read " + (.mail_name())) + ".");
    if (mail)
        return mail[1];
    return 0;
};

public method .last_received_on() {
    return last_received_on;
};

public method .recent_mail() {
    arg @diff;
    
    if (!(.list_is_readable_by(sender())))
        throw(~perm, ("Sender cannot read " + (.mail_name())) + ".");
    [(diff ?= 20)] = diff;
    if ((mail.length()) < diff)
        return [0, mail];
    return [((mail.length()) - diff) - 1, mail.subrange((mail.length()) - diff)];
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .set_notify() {
    arg new_value;
    
    (> .perms(sender(), 'manager) <);
    if ((type(new_value) != 'integer) && (type(new_value) != 'list))
        throw(~type, "new value must be submitted as a list of users or boolean integer.");
    notify = new_value;
};

public method .set_senders() {
    arg new_value;
    
    (> .perms(sender(), 'manager) <);
    if ((type(new_value) != 'integer) && (type(new_value) != 'list))
        throw(~type, "new value must be submitted as a list of users or boolean integer.");
    senders = new_value;
};

public method .notify() {
    (> .perms(sender(), 'manager) <);
    return notify;
};

public method .del_mail() {
    arg old_mail, @sender;
    
    // what the hell am I thinking?
    [(sender ?= sender())] = sender;
    if (!($mail_lib.has_mail_perms(caller())))
        throw(~perm, ((caller().namef('xref)) + " cannot remove ") + (old_mail.mail_name()));
    if (old_mail == (mail.last()))
        last_received_on = (| (mail[(mail.length()) - 1]).time() |) || 0;
    (| old_mail.del_recipient(this()) |);
    mail = mail.del(old_mail);
};

protected method ._announce_new_mail() {
    arg new_mail;
    var line, who, n;
    
    if (!notify)
        return;
    line = ((((.mail_name()) + " has been sent new mail by ") + ((new_mail.from()).name())) + ": ") + (new_mail.subject());
    for who in (notify)
        (| who.tell(line.chop(who.linelen())) |);
    
    // $# Edited 05 Nov 1995 14:04 Lynx ($lynx)
};

public method .mail() {
    //  if (!.list_is_sendable_by(sender()))
    //      throw(~perm, "Sender cannot read " + .mail_name() + ".");
    return mail;
};

public method .add_mail() {
    var new_mail;
    
    (> .perms(caller(), $mail_message) <);
    last_received_on = time();
    new_mail = sender();
    
    // make sure we do not already have it
    if (new_mail in mail)
        return;
    
    // add it
    mail = mail.add(new_mail);
    ._announce_new_mail(new_mail);
};

public method .senders() {
    (> .perms(sender(), 'manager) <);
    return senders;
};

public method .mail_name() {
    return $mail_lib.mail_name(this());
};

root method .init_mail_list() {
    mail = [];
    senders = 1;
    readers = [.manager()];
    notify = [.manager()];
    if (!(.has_ancestor($user))) {
        readers = 1;
        (| $mail_db.insert(.name(), this()) |);
    } else {
        readers = [.manager()];
    }
};

root method .uninit_mail_list() {
    var m;
    
    for m in (mail)
        .del_mail(let[1]);
    mail = [];
    senders = 1;
    readers = [.manager()];
    notify = [];
    if (!(.has_ancestor($user)))
        (| $mail_db.remove(.name()) |);
};

public method .mail_list_next() {
    arg cur;
    
    if (!(.list_is_readable_by(sender())))
        throw(~perm, "Sender cannot read this list.");
    return mail[(cur in mail) + 1];
};

public method .mail_list_prev() {
    arg cur;
    
    if (!(.list_is_readable_by(sender())))
        throw(~perm, "Sender cannot read this list.");
    return mail[(cur in mail) - 1];
};

public method .notify_bad_mail() {
    arg badmail;
    
    // this is a hack, we shouldn't ever get bad mail if things worked right
    (> .perms(caller(), $mail_ui) <);
    mail = setremove(mail, badmail);
    
    // $#Edited: 18 Nov 96 09:31 $brandon
};

root method .core_mail_list() {
    var o;
    
    if (type(senders) == 'list)
        senders = filter o in (senders) where (valid(o));
    if (type(notify) == 'list)
        notify = filter o in (notify) where (valid(o));
    if (type(readers) == 'list)
        readers = filter o in (readers) where (valid(o));
};


new object $mail_ui: $mail_list, $user_interfaces;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $mail_ui subscribed = #[];
var $mail_ui current = 0;
var $mail_list letters = #[];
var $mail_list letters_index = #[];
var $mail_list senders = 1;
var $mail_list readers = [];
var $mail_list notify = [$mail_ui];
var $mail_list last_letter = 0;
var $mail_list mail = [];
var $has_commands local = #[["@sub?scribed", [["@sub?scribed", "*", "@sub?scribed <any>", 'subscribe_cmd, #[[1, ['any, []]]]]]], ["@unsub?scribed", [["@unsub?scribed", "*", "@unsub?scribed <any>", 'unsubscribe_cmd, #[[1, ['any, []]]]]]], ["@mail-list?s", [["@mail-list?s", "", "@mail-list?s", 'mail_lists_cmd, #[]]]], ["@read", [["@read", "*", "@read <any>", 'mail_read_cmd, #[[1, ['any, []]]]]]], ["@remove-m?ail|@rmm?ail", [["@remove-m?ail|@rmm?ail", "*", "@remove-m?ail|@rmm?ail <any>", 'mail_remove_cmd, #[[1, ['any, []]]]]]], ["@nn|@next-new", [["@nn|@next-new", "*", "@nn|@next-new <any>", 'next_new_cmd, #[[1, ['any, []]]]]]], ["@mail", [["@mail", "*", "@mail <any>", 'mail_on_cmd, #[[1, ['any, []]]]]]], ["@send", [["@send", "*", "@send <any>", 'send_to_cmd, #[[1, ['any, []]]]]]]];
var $has_commands shortcuts = #[];
var $has_name name = ['prop, "Mail User Interface", "Mail User Interface"];
var $root manager = $mail_ui;
var $root managed = [$mail_ui];
var $root owned = [$mail_ui];

protected method .send_to_cmd() {
    arg cmdstr, cmd, str;
    var subj, lists, note, list, x, mail, text, args;
    
    (> .perms(caller(), 'command) <);
    if ((args = match_template(str, "* to *"))) {
        note = args[1];
        args = args[3];
    } else {
        note = "";
        args = str;
    }
    if (args) {
        lists = [];
        for list in (args.explode_english_list()) {
            catch ~listnf {
                list = (> $mail_lib.match_mail_recipient(list) <);
                lists += [list];
            } with {
                .tell(("The list \"" + list) + "\" is invalid.");
            }
        }
        if (!lists)
            return "No lists specified.";
    } else {
        lists = [current['list]];
    }
    
    // get the text of the message
    if (note) {
        text = (> (.match_env_nice(note)).text() <);
    } else {
        text = .read("-- Enter text for mail message, \".\" when done or \"@abort\" to abort --");
        if (text == 'aborted)
            return;
        if (text == 'engaged)
            return "** Already reading - mail send aborted **";
    }
    subj = .prompt("Subject: ");
    if (subj == "@abort")
        return "** Aborted mail send **";
    if (subj == 'engaged)
        return "** Already reading - mail send aborted **";
    mail = $mail_message.new_mail();
    mail.set_subject(subj);
    mail.set_text(text);
    catch any
        mail.send(@lists);
    with
        return (traceback()[1])[2];
    return "Mail sent.";
    
    // $#Edited: 30 Nov 96 04:08 $brad
};

protected method .mail_read_cmd() {
    arg cmdstr, cmd, str;
    var mail, m, args, lname, list, rng, args;
    
    (> .perms(caller(), 'command) <);
    if ((args = match_template(str, "* on *"))) {
        rng = args[1];
        catch ~listnf
            list = (> $mail_lib.match_mail_recipient(args[3]) <);
        with
            return (traceback()[1])[2];
    } else {
        rng = str;
        list = current['list];
    }
    catch ~perm
        (> .new_list(list) <);
    with
        return (traceback()[1])[2];
    if (((list.mail()).length()) == 0)
        return ("There is no mail on " + (list.mail_name())) + ".";
    if (!rng)
        return ("You must specify a message to read on " + (list.mail_name())) + ".";
    catch ~range {
        if (rng == "next") {
            .read_mail((> list.mail_list_next((subscribed[list])[2]) <), list);
        } else if (rng == "prev") {
            .read_mail((> list.mail_list_prev((subscribed[list])[2]) <), list);
        } else {
            for m in ($mail_lib.range_to_actual($parse_lib.range(rng), current))
                .read_mail(m, list);
        }
    } with {
        return ((("Mail message " + rng) + " does not exist on ") + (list.mail_name())) + ".";
    }
};

protected method .mail_remove_cmd() {
    arg cmdstr, cmd, str;
    var mail, args, lmail, list, rng, m, x, name, lname, offset, ans;
    
    (> .perms(caller(), 'command) <);
    if ((args = match_template(str, "* on|from *"))) {
        rng = args[1];
        list = args[3];
    } else if (!str) {
        return "You must specify a message and list.";
    } else {
        // grr, be hacky
        args = explode(str);
        if ((args.length()) > 1) {
            list = args.last();
            if (!(| $mail_lib.match_mail_recipient(list) |)) {
                rng = str;
                list = "";
            } else {
                rng = (args.delete(args.length())).join();
            }
        } else {
            rng = str;
            list = "";
        }
    }
    if (!rng)
        return ("You must specify a message to remove from " + lname) + ".";
    if (!list) {
        list = current['list];
        ans = .prompt(("Remove mail from " + (list.mail_name())) + "? ");
        if (type(ans) == 'symbol)
            return;
        if (match_regexp(ans, "no|n"))
            return "Ok, aborting..";
    } else {
        catch ~listnf
            list = (> $mail_lib.match_mail_recipient(list) <);
        with
            return ("The list \"" + list) + "\" is invalid.";
    }
    lname = list.mail_name();
    catch any
        (> .new_list(list) <);
    with
        return (traceback()[1])[2];
    if (rng && ((rng[1]) == "$")) {
        catch ~namenf
            mail = [(> $object_lib.to_dbref(rng) <)];
        with
            return (traceback()[1])[2];
    } else {
        catch ~range
            mail = (> $mail_lib.range_to_actual($parse_lib.range(rng), current) <);
        with
            return (traceback()[1])[2];
    }
    lmail = list.mail();
    if ((mail[1]) != (| lmail[1] |)) {
        offset = (mail[1]) in lmail;
        lmail = sublist(lmail, offset);
        offset--;
    }
    for m in (mail) {
        catch ~perm {
            x = (m in lmail) + offset;
            name = ((((("#" + x) + " \"") + (m.subject())) + "\" (") + m) + ")";
            list.del_mail(m);
            .tell(((("Removed message " + name) + " from ") + (list.mail_name())) + ".");
        } with {
            .tell((traceback()[1])[2]);
        }
    }
};

protected method .read_mail() {
    arg mail, list;
    var loc;
    
    loc = mail in (list.mail());
    .tell(strfmt("Message %l (%l) on %s:", loc, mail.name(), list.mail_name()));
    .tell(mail.format());
    mail.did_read();
    subscribed = subscribed.add(list, [time(), mail]);
};

protected method .subscribed() {
    return subscribed;
};

protected method .unsubscribe_cmd() {
    arg cmdstr, cmd, str;
    var list, line, mname;
    
    (> .perms(caller(), 'command) <);
    if (!str)
        return .mail_lists_cmd();
    list = $mail_lib.match_mail_recipient(str);
    if (list == this())
        return "You cannot unsubscribe yourself.";
    mname = list.mail_name();
    if (!(list in (subscribed.keys())))
        return "You are not subscribed to " + mname;
    .unsubscribe(list);
    return ("Successfully unsubscribed from " + mname) + ".";
};

protected method .subscribe_cmd() {
    arg cmdstr, cmd, str;
    var list, mname, l, args, line, len, out;
    
    (> .perms(caller(), 'command) <);
    
    // this is ugly bad bad
    args = $parse_lib.getopt(str, [["n?ew"]]);
    if (!(args[1])) {
        if ("n?ew" in ((args[2]).slice(1))) {
            out = [];
            for l in ((subscribed.keys()).setremove(this())) {
                if ((l.last_received_on()) > ((subscribed[l])[1]))
                    out = (out = ["  " + (l.mail_name())]);
            }
            if (out)
                .tell(["New mail on:"] + out);
            return;
        }
        .tell("Currently Subscribed Lists:");
        len = (.linelen()) / 3;
        for l in ((subscribed.keys()).setremove(this())) {
            line = "  " + (l.mail_name());
            if ((l.last_received_on()) > ((subscribed[l])[1]))
                line += " (new mail)";
            .tell(line);
        }
        return;
    }
    list = $mail_lib.match_mail_recipient(str);
    mname = $mail_lib.mail_name(list);
    if (list in (subscribed.keys()))
        return .tell(("You are already subscribed to " + mname) + ".");
    if (!(list.list_is_readable_by(this())))
        return .tell(mname + " is not subscribeable by you.");
    .subscribe(list);
    .tell(("Successfully subscribed to " + mname) + ".");
};

protected method .subscribe() {
    arg list;
    
    if (!subscribed)
        subscribed = #[];
    subscribed = subscribed.add(list, [time(), 0]);
    (| list.add_sender_to_notification() |);
};

protected method .unsubscribe() {
    arg list;
    
    subscribed = subscribed.del(list);
    (| list.del_sender_from_notification() |);
};

protected method .mail_lists_cmd() {
    arg @args;
    var l, line;
    
    (> .perms(caller(), 'command) <);
    for l in (($mail_db.database()).values()) {
        line = "";
        if (l.list_is_readable_by(this()))
            line = "[Readable]";
        if (l.list_is_sendable_by(this()))
            line = ("[Sendable]" + (line ? " " : "")) + line;
        .tell((((l.mail_name()).pad(((.linelen()) - (line.length())) - 1)) + " ") + line);
    }
};

protected method .new_list() {
    arg list;
    
    // check here so we can assume later that this error will not bite us
    if (!(subscribed.contains(list))) {
        if (!(list.list_is_readable_by(this())))
            throw(~perm, "You cannot read mail on " + (list.mail_name()));
    }
    
    // set the current list
    if (list != (current['list]))
        current = current.add('list, list);
};

root method .init_mail_ui() {
    current = #[['list, this()]];
    .subscribe(this());
    .new_list(this());
    (| .subscribe($mail_list_news) |);
    
    // now change the 'news' subscription so it notifies them NOW
    subscribed = subscribed.add($mail_list_news, [0, 0]);
};

protected method .mail_on_cmd() {
    arg cmdstr, cmd, str;
    var args, lmail, mail, rng, start, end, line, list, len, out, m, rows;
    
    (> .perms(caller(), 'command) <);
    if ((args = match_template(str, "* on *"))) {
        rng = args[1];
        list = args[3];
    } else if (match_template(str, "* to *")) {
        return (> .send_to_cmd(cmdstr, cmd, str) <);
    } else {
        rng = "";
        list = str;
    }
    if (!list) {
        list = current['list];
    } else {
        catch ~listnf, ~perm {
            list = (> $mail_lib.match_mail_recipient(list) <);
            (> .new_list(list) <);
        } with {
            return (traceback()[1])[2];
        }
    }
    if (!rng) {
        mail = list.mail();
        end = mail.length();
    
        // minus two for the head and tail
        rows = (.get_rows()) - 2;
        if (end > rows) {
            start = end - rows;
            mail = sublist(mail, start);
        } else {
            start = 1;
        }
        rng = (start + "-") + end;
    } else {
        catch ~range
            mail = $mail_lib.range_to_actual($parse_lib.range(rng), current);
        with
            return (traceback()[1])[2];
    }
    if (!mail)
        return "No mail on " + (list.mail_name());
    len = (.linelen()) - 33;
    out = [((("Mail from " + rng) + " on ") + (list.mail_name())) + ":"];
    lmail = list.mail();
    for m in (mail) {
        if (!valid(m))
            list.notify_bad_mail(m);
        else
            out += [strfmt("%s%3r:%s%*L %14L%11l", (mail == (| (subscribed[list])[2] |)) ? "=>" : "  ", m in lmail, (m.has_read(this())) ? " " : "!", len, m.subject(), $object_lib.get_name(m.from(), 'name), $time.format("%d-%h-%Y", m.time()))];
    }
    .tell(out + ["------"]);
};

protected method .mail_to_cmd() {
    arg cmdstr, cmd, str;
    var subj, lists, note, list, x, mail, text, args;
    
    (> .perms(caller(), 'command) <);
    if ((args = match_template(str, "* to *"))) {
        note = args[1];
        args = args[3];
    } else if ((cmd == "@mail") && (args = match_template(str, "* on *"))) {
        return (> .mail_on_cmd(cmdstr, cmd, str) <);
    } else {
        note = "";
        args = str;
    }
    if (args) {
        lists = [];
        for list in (args.explode_english_list()) {
            catch ~listnf {
                list = (> $mail_lib.match_mail_recipient(list) <);
                lists += [list];
            } with {
                .tell(("The list \"" + list) + "\" is invalid.");
            }
        }
        if (!lists)
            return "No lists specified.";
    } else {
        lists = [current['list]];
    }
    
    // get the text of the message
    if (note) {
        text = (> (.match_env_nice(note)).text() <);
    } else {
        text = .read("-- Enter text for mail message, \".\" when done or \"@abort\" to abort --");
        if (text == 'aborted)
            return;
        if (text == 'engaged)
            return "** Already reading - mail send aborted **";
    }
    subj = .prompt("Subject: ");
    if (subj == "@abort")
        return "** Aborted mail send **";
    if (subj == 'engaged)
        return "** Already reading - mail send aborted **";
    mail = $mail_message.new_mail();
    mail.set_subject(subj);
    mail.set_text(text);
    catch any
        mail.send(@lists);
    with
        return (traceback()[1])[2];
    return "Mail sent.";
};

protected method .next_new_cmd() {
    arg cmdstr, cmd, str;
    var mail, list, keys, start;
    
    (> .perms(caller(), 'command) <);
    if (str) {
        catch any
            list = (> $mail_lib.match_mail_recipient(str) <);
        with
            return (traceback()[1])[2];
        .new_list(list);
        mail = (| list.mail_list_next((subscribed[list])[2]) |);
        while (mail && (mail.has_read(this()))) {
            refresh();
            mail = (| list.mail_list_next(mail) |);
        }
        if (!mail)
            return ("No new mail on " + ($mail_lib.mail_name(list))) + ".";
        .read_mail(mail, list);
    } else {
        keys = dict_keys(subscribed);
        if (!keys)
            return "You are not subscribed to any lists.";
        if (!((current['list]) in keys))
            current = current.add('list, keys[1]);
        start = (list = current['list]);
        while (1) {
            // anything left on this list?
            mail = (| list.mail_list_next((subscribed[list])[2]) |);
            while (mail && (mail.has_read(this()))) {
                refresh();
                mail = (| list.mail_list_next(mail) |);
            }
            if (mail)
                break;
    
            // pick a new list
            catch any
                list = (> keys[(list in keys) + 1] <);
            with
                list = (| keys[1] |);
    
            // die?
            if ((!list) || (list == start))
                return "No new mail.";
        }
        .new_list(list);
        .read_mail(mail, list);
    }
};

root method .uninit_mail_ui() {
    var l;
    
    for l in ((subscribed || #[]).keys())
        (| .unsubscribe(l) |);
};


new object $location: $physical, $command_cache;

var $location contents = [];
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $described prose = [];
var $has_name name = ['uniq, "Generic Container Object", "the Generic Container Object"];
var $has_commands shortcuts = #[];
var $root manager = $location;
var $root managed = [$location];
var $root owned = [$location];
var $root child_index = 1;

root method .init_location() {
    contents = [];
};

root method .uninit_location() {
    var obj;
    
    for obj in (contents)
        obj.move_to((| obj.get_setting("home", $thing) |) || $nowhere);
};

public method .contents() {
    return contents || [];
};

public method .contains() {
    arg obj;
    
    return (obj in (.contents())) ? 1 : 0;
};

public method .find_in_contents() {
    arg str;
    var obj;
    
    for obj in (.contents()) {
        if (obj.match_name(str))
            return;
    }
};

public method .will_arrive() {
    arg old_place;
    
    if (caller() != $located)
        throw(~perm, "Caller is not $located.");
};

public method .will_leave() {
    arg place;
    
    if (caller() != $located)
        throw(~perm, "Caller is not $located.");
};

public method .did_arrive() {
    arg place;
    
    if (caller() != $located)
        throw(~perm, "Caller is not $located.");
    .add_object_to_remote_cache(sender());
};

public method .did_leave() {
    arg place;
    
    if (caller() != $located)
        throw(~perm, "Caller is not $located.");
    (| .del_object_from_remote_cache(sender()) |);
};

public method .add_sender_to_contents(): nooverride {
    if (caller() != $located)
        throw(~perm, "Caller is not $located.");
    if ((sender().location()) != this())
        throw(~location, "Sorry, but you're not here.");
    contents = contents.setadd(sender());
    
    // $#Edited: 19 Mar 96 02:56 Levi ($user_levi)
};

public method .del_sender_from_contents() {
    if (caller() != $located)
        throw(~perm, "Caller not an agent of located protocol.");
    contents = setremove(contents, sender());
};

public method .validate_contents() {
    var obj, newcont;
    
    if (!(.is_writable_by(sender())))
        throw(~perm, "Must be a writer to validate contents");
    newcont = [];
    for obj in (contents) {
        if (valid(obj) && ((obj.has_ancestor($located)) && ((obj.location()) == this())))
            newcont = newcont.setadd(obj);
    }
    contents = newcont;
};

public method .environment() {
    return [this()] + contents;
};

public method .add_to_contents(): nooverride {
    arg what;
    
    if (caller() != $located)
        throw(~perm, "Caller is not $located.");
};

public method .contents_accept_mail() {
    return 1;
};

public method .realm() {
    arg @args;
    var loc;
    
    loc = "";
    if ((| .location() |))
        loc = (.location()).realm();
    return ((loc + "[") + (.name())) + "]";
    
    // $#Edited: 19 Feb 97 02:23 $miro
};

public method .realm_name() {
    return "";
};

public method .add_frob_to_contents() {
    arg frob;
    
    if (!(sender().is($thing_frob)))
        throw(~perm, "Caller is not $thing_frob.");
    if (type(frob) != 'frob)
        throw(~type, "Argument is not a frob.");
    if ((frob.location()) != this())
        throw(~location, "Sorry, but you're not here.");
    contents = (.contents()).setadd(frob);
};

public method .del_frob_from_contents() {
    arg frob;
    
    if ((!(sender().is($thing_frob))) && (sender() != this()))
        throw(~perm, "Caller is not $thing_frob.");
    if (type(frob) != 'frob)
        throw(~type, "Argument not a frob.");
    contents = contents.setremove(frob);
};

public method .announce() {
    arg str, @except;
    var obj, part, s;
    
    if ((type(str) == 'frob) && ((class(str) == $message_frob) && (this() in (str.parts()))))
        str = str.change_entry(this(), "general");
    s = sender();
    for obj in (.contents()) {
        if (!(obj in except))
            (| obj.tell(str, s) |);
    }
};


new object $located_location: $thing, $location;

var $root child_index = 13;
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $location contents = [];
var $located location = $void;
var $located obvious = 1;
var $described prose = [];
var $has_name name = ['uniq, "Generic Located Location", "the Generic Located Location"];
var $command_cache shortcut_cache = [];
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 1]]]]];
var $has_commands remote = #[];
var $root manager = $located_location;
var $root managed = [$located_location];
var $root owned = [$located_location];
var $thing gender = $gender_neuter;

public method .environment() {
    return (.contents()) + pass();
};

public method .description() {
    arg flags;
    var desc, out, c;
    
    // type is either 'on' or 'in'
    if (!(flags.contains('type)))
        return (> pass(flags) <);
    out = [];
    for c in (.contents())
        out += [c.name()];
    return (> pass(flags) <) + [((((("There is " + (out.to_english())) + " ") + (flags['type])) + " ") + (.name())) + "."];
};


new object $body: $located_location;

var $root child_index = 20;
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core, 'command_cache];
var $location contents = [];
var $located location = $void;
var $located obvious = 1;
var $body body_parts = #[];
var $body available_body_parts = 0;
var $body wearing = [];
var $body remote_command_cache = 0;
var $described prose = [];
var $has_name name = ['uniq, "Generic Body", "the Generic Body"];
var $command_cache shortcut_cache = [["|*", ['quote_cmd, ["quote ", 1]]], ["\"*", ['say_cmd, ["say ", 1]]], ["%*", ['think_cmd, ["think ", 1]]], ["!*", ['spoof_cmd, ["spoof ", 1]]], [",*,*", ['esay_cmd, ["esay ", 1, " with ", 2]]], [":*", ['emote_cmd, ["emote ", 1]]], [".*", ['pose_cmd, ["pose ", 1]]], ["''*", ['to_say_cmd, ["to ", "", " say ", 1]]], ["'* *", ['to_say_cmd, ["to ", 1, " say ", 2]]]];
var $command_cache local_cache = #[["wh", ["wh?isper"]], ["whi", ["wh?isper"]], ["whis", ["wh?isper"]], ["whisp", ["wh?isper"]], ["whispe", ["wh?isper"]], ["whisper", ["wh?isper"]], ["say", ["say"]], ["to", ["to"]], ["emote", ["emote"]], ["quote", ["quote"]], ["spoof", ["spoof"]], ["pose", ["pose"]], ["think", ["think"]], ["wear", ["wear"]], ["remove", ["remove|shed"]], ["shed", ["remove|shed"]], ["@a", ["@a?ction"]], ["@ac", ["@a?ction"]], ["@act", ["@a?ction"]], ["@acti", ["@a?ction"]], ["@actio", ["@a?ction"]], ["@action", ["@a?ction"]]];
var $root manager = $body;
var $root managed = [$body];
var $root owned = [$body];
var $body interaction = 0;
var $has_commands shortcuts = #[["|*", ['quote_cmd, ["quote ", 1]]], ["\"*", ['say_cmd, ["say ", 1]]], ["%*", ['think_cmd, ["think ", 1]]], ["!*", ['spoof_cmd, ["spoof ", 1]]], [",*,*", ['esay_cmd, ["esay ", 1, " with ", 2]]], [":*", ['emote_cmd, ["emote ", 1]]], [".*", ['pose_cmd, ["pose ", 1]]], ["''*", ['to_say_cmd, ["to ", "", " say ", 1]]], ["'* *", ['to_say_cmd, ["to ", 1, " say ", 2]]]];
var $has_commands local = #[["wh?isper", [["wh?isper", "* to *", "wh?isper <any> to <any>", 'whisper_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["say", [["say", "*", "say <any>", 'say_cmd, #[[1, ['any, []]]]]]], ["to", [["to", "* say *", "to <any> say <any>", 'to_say_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["emote", [["emote", "*", "emote <any>", 'emote_cmd, #[[1, ['any, []]]]]]], ["quote", [["quote", "*", "quote <any>", 'quote_cmd, #[[1, ['any, []]]]]]], ["spoof", [["spoof", "*", "spoof <any>", 'spoof_cmd, #[[1, ['any, []]]]]]], ["pose", [["pose", "*", "pose <any>", 'spoof_cmd, #[[1, ['any, []]]]]]], ["think", [["think", "*", "think <any>", 'think_cmd, #[[1, ['any, []]]]]]], ["wear", [["wear", "*", "wear <any>", 'wear_cmd, #[[1, ['any, []]]]]]], ["remove|shed", [["remove|shed", "*", "remove|shed <any>", 'remove_cmd, #[[1, ['any, []]]]]]], ["@a?ction", [["@a?ction", "*", "@a?ction <any>", 'action_cmd, #[[1, ['any, []]]]]]]];
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 1]]]]];
var $thing gender = $gender_neuter;
var $body actions = 0;

public method .tell() {
    arg @args;
    
    // $#Edited: 18 Dec 96 09:27 $brandon
};

public method .set_body_part() {
    arg part, frob, param;
    
    if (sender().has_ancestor($wearable_frob))
        throw(~perm, "Sender must be $wearable_frob.");
    body_parts = body_parts.add(frob.new_with(part, param));
};

public method .wearing() {
    arg @args;
    var x, w;
    
    w = wearing || [];
    if (args && ('objects in args)) {
        for x in [1 .. w.length()]
            w = w.replace(x, class(w[x]));
    }
    return w;
};

public method .body_parts() {
    return body_parts;
};

public method .namef() {
    arg type;
    var str;
    
    switch (type) {
        case 'doing, 'nactivity, 'activity, 'titled:
            return .name();
        default:
            return (> pass(type) <);
    }
    
    // $# Edited 28 Oct 1995 21:08 Lynx ($lynx)
};

public method .available_body_parts() {
    return available_body_parts || ['head, 'rleg, 'lleg, 'rarm, 'larm, 'torso];
};

public method .wear() {
    arg what;
    
    if (caller() != $wearable_frob)
        throw(~wear, "You can only wear descendants of $wearable_frob.");
    wearing = setadd(wearing || [], what);
};

public method .shed() {
    arg what;
    
    if (caller() != $wearable_frob)
        throw(~wear, "You can only wear descendants of $wearable_frob.");
    wearing = setremove(wearing, what);
};

public method .will_move() {
    arg mover, place;
    
    // exits should always be able to pull "bodies" through them
    // this becomes sortof a big override returning, but ... *shrug*
    if (mover.is($exit))
        return;
    (> pass(mover, place) <);
};

public method .description() {
    arg flags;
    var ctext, what, w;
    
    ctext = (> pass(flags) <);
    if ((w = .wearing()))
        ctext += [((((.gender()).pronoun('psc)) + " is wearing ") + ((w.mmap('name)).to_english())) + "."];
    
    //   else
    //       ctext += [.gender().pronoun('psc) + " is naked, baring it all to the world."];
    return ctext;
    
    // $#Edited: 23 Dec 96 13:37 $brandon
};

public method .environment() {
    return pass() + (wearing || []);
    
    // $#Edited: 27 Nov 96 14:01 $brandon
};

protected method .parse_interaction_reference() {
    arg targets, what, @userdb;
    var recip, target, msg, out;
    
    [(userdb ?= 0)] = userdb;
    targets = (targets && (targets.explode_list())) || [];
    if (!targets) {
        if (!(targets = (| interaction['objs] |)))
            throw(~stop, ("You must direct your " + what) + " to a target.");
        out = targets[2];
    } else {
        out = [];
        for recip in (targets) {
            target = 0;
            if (userdb)
                target = (| $user_db.match_begin(recip) |);
            if (!target) {
                catch ~objnf
                    target = (> .match_environment(recip) <);
                with
                    throw(~stop, (traceback()[1])[2]);
            }
            if (!(target.is($body)))
                throw(~stop, (target.namef('ref)) + " is not a valid recipient.");
            out = setadd(out, target);
        }
    }
    return out;
};

protected method .add_interaction() {
    arg key, value;
    
    if (!interaction)
        interaction = #[];
    if (type(value) != 'list)
        value = [value];
    value = [time(), value];
    interaction = interaction.add(key, value);
};

protected method .whisper_cmd() {
    arg cmdstr, com, what, prep, who;
    var loc, targets, t, msg, recips;
    
    (> .perms(caller(), $user, $body) <);
    targets = (> .parse_interaction_reference(who, "whisper") <);
    .add_interaction('objs, targets);
    loc = .location();
    if (((targets.mmap('location)).compress()) != [loc]) {
        who = filter t in (targets) where ((t.location()) != loc);
        return ("You must be in the same place as " + (who.english_name_list())) + ", to whisper to them.";
    }
    msg = (((.name()) + " whispers, \"") + what) + "\"";
    for t in (targets)
        (| t.directed_tell(msg, 'whisper) |);
    recips = (targets.mmap('name)).to_english();
    loc.announce((((.name()) + " whispers to ") + recips) + ".", this(), @targets);
    .tell(((("You whisper, \"" + what) + "\" to ") + recips) + ".");
};

protected method .think_cmd() {
    arg cmdstr, cmd, what;
    
    (> .perms(caller(), $user, $body) <);
    (.location()).announce((((.name()) + " . o O ( ") + what) + " )");
};

protected method .emote_cmd() {
    arg cmdstr, com, what;
    
    (> .perms(caller(), $user, $body) <);
    if (what && ((what[1]) == ":"))
        (.location()).announce((.name()) + (what.subrange(2)));
    else
        (.location()).announce(((.name()) + " ") + what);
};

protected method .say_cmd() {
    arg cmdstr, cmd, what;
    var type, how, idx;
    
    (> .perms(caller(), $user, $body) <);
    if (what)
        how = $code_lib.punctuation_type(what);
    else
        how = "say";
    (.location()).announce((((((.name()) + " ") + how) + "s, \"") + what) + "\"");
};

protected method .esay_cmd() {
    arg cmdstr, cmd, how, prep, what;
    
    (> .perms(caller(), $user, $body) <);
    (.location()).announce((((((.name()) + " ") + (how.trim())) + ", \"") + (what.trim())) + "\"");
};

protected method .spoof_cmd() {
    arg cmdstr, cmd, what;
    var name;
    
    (> .perms(caller(), $user, $body) <);
    name = .name();
    if (!(((name + " ") in what) || ((" " + name) in what)))
        what = (what + "     -- ") + name;
    (.location()).announce(what);
};

protected method .to_say_cmd() {
    arg cmdstr, com, who, prep, message;
    var targets, target, line;
    
    (> .perms(caller(), $user, $body) <);
    targets = (> .parse_interaction_reference(who, "say") <);
    .add_interaction('objs, targets);
    line = (((.name()) + " (to ") + ((targets.mmap('name)).to_english())) + ") ";
    if (message)
        line += ((message[1]) == ":") ? message.subrange(2) : (((($code_lib.punctuation_type(message)) + "s, \"") + message) + "\"");
    else
        line += "says, \"\"";
    for target in (targets)
        target.directed_tell(line, 'tosay);
    (.location()).announce(line, @targets);
};

protected method .pose_cmd() {
    arg cmdstr, cmd, args;
    var action, targs, m, word, tail, i, str1, str2, str3, line, objs;
    
    (> .perms(caller(), $user, $body) <);
    if (!args) {
        (.location()).announce(.name());
        return;
    }
    action = args.word(1);
    if (" " in args) {
        args = substr(args, (" " in args) + 1);
        if ("and" in args) {
            targs = args.explode_english_list();
            word = targs.last();
            targs = delete(targs, listlen(targs));
            targs = map m in (targs) to ((| .match_environment(m) |) || m);
            if ((m = (| .match_environment(word) |))) {
                args = "";
                targs += [m];
            } else {
                args = substr(word, " " in word);
                m = word.word(1);
                targs += [(| .match_environment(m) |) || m];
            }
        } else {
            m = " " + (args.word(1));
            targs = [(| .match_environment(m) |) || m];
            args = (| substr(args, (" " in args) + 1) |) || "";
        }
    } else {
        .tell("You " + action);
        (.location()).announce((((.name()) + " ") + action) + "s", this());
        return;
    }
    
    // convert to ctext some day
    if (args) {
        str1 = strsed(args, " +my($| |\.)", " your%1");
        str1 = strsed(args, " +me($| |\.)", " yourself%1");
        word = (" " + ((.gender()).pronoun('pp))) + "%1";
        str2 = strsed(args, " +my($| |\.)", word);
        word = (" " + ((.gender()).pronoun('pr))) + "%1";
        str2 = strsed(args, " +me($| |\.)", word);
        str3 = str2;
    }
    objs = map m in (targs) to (((type(m) == 'objnum) && (m.name())) || m).to_english();
    .tell(((("You " + action) + " ") + objs) + args);
    
    // I'll do something better later
    for m in (targs) {
        line = (((.name()) + " ") + action) + "s ";
        if (type(m) == 'objnum)
            m.tell((line + strsub(objs, m.name(), "you")) + args);
    }
    line += objs + args;
    objs = filter m in (targs) where (type(m) == 'objnum) + [this()];
    (.location()).announce(line, @objs);
};

protected method .quote_cmd() {
    arg cmdstr, cmd, what;
    
    (.location()).announce(((.name()) + " | ") + what);
};

public method .ptell() {
    arg what, flags;
    
    .tell(what);
    
    // $#Edited: 30 Nov 96 10:58 $brandon
};

protected method .handle_parser_result() {
    arg action, @more;
    var r, c;
    
    switch (action) {
        case 'error:
            ._tell(more[1]);
        case 'match, 'command:
            r = (> (more[1]).(more[2])(@more.subrange(3)) <);
            if (type(r) in ['list, 'frob, 'string])
                .ptell(r, #[['type, 'parser], ['command, more[2]]]);
        case 'failed:
            for c in (($place_lib.coordinate_shortcuts()).keys()) {
                if (line.match_template(c)) {
                    .tell(("There is no exit " + line) + " here.");
                    r = 1;
                }
            }
            if (!r)
                .tell(("I don't understand " + (line.chop((.linelen()) - 22))) + ".");
        case 'ok:
            // do nothing, probably a null command
        default:
            ._tell("Unusual response from the parser: " + toliteral(more));
    }
};

protected method .wear_cmd() {
    arg cmd, cmdstr, what;
    
    (> .perms(caller(), $user, $body) <);
    what = (> .match_env_nice(what) <);
    if (!(what.is($wearable_frob)))
        return ("You cannot wear " + (what.name())) + ".";
    what = (> what.wear() <);
    return "You wear " + (what.name());
};

protected method .remove_cmd() {
    arg cmd, cmdstr, what;
    
    (> .perms(caller(), $user, $body) <);
    what = (> .match_env_nice(what) <);
    if (!(what.is($wearable_frob)))
        return ("You are not wearing " + (what.name())) + ".";
    what = (> what.shed() <);
    return "You remove " + (what.name());
};

public method .directed_tell() {
    arg what, type;
    
    ._tell(what);
    .send_event('social, sender(), type, what);
};

public method .tell_traceback() {
    arg traceback;
    
    if ((.manager()) != this())
        (.manager()).tell_traceback(traceback);
    
    // $#Edited: 17 Dec 96 21:20 $brandon
};

public method ._tell() {
    arg @args;
    var m;
    
    m = .manager();
    if ((m != this()) && ((m.location()) != (.location())))
        (| m.tell(@args.prefix(("<" + (.name())) + "> ")) |);
};

public method .tell_realm_announce() {
    arg realm, message;
    var loc, r;
    
    pause();
    loc = .location();
    if (!(loc.will_propagate()))
        return;
    r = (.location()).realm();
    while (r != $realm) {
        if (r == realm) {
            .tell(message);
            return;
        }
        if (!(r.will_propagate()))
            return;
        r = (r.parents())[1];
    }
    
    // $#Edited: 07 Mar 97 16:32 $miro
};

public method .event_notify() {
    arg event, origin, @args;
    
    if (caller() != $event_handler)
        throw(~perm, caller() + " is not $event_handler.");
    if (event == 'realm_announce)
        .tell_realm_announce(origin, args[1]);
    
    // $#Edited: 07 Mar 97 16:32 $miro
};

protected method .action_cmd() {
    arg cmdstr, cmd, string;
    var a, data, parse, out;
    
    (> .perms(caller(), 'command) <);
    if (!string) {
        out = [];
        if (actions)
            out = map a in (actions) to (pad(a[1], 25) + (a[2]));
        if ((data = ((.location()).prose()).get_var('details)))
            out += map a in (data) to ((pad(a[1], 25) + "look detail ") + (a[1]));
        if (!out)
            return "No actions registered.";
        return [strfmt("%25sCommand", "What"), strfmt("%25s-------", "----"), @out, "---"];
    }
    if (actions) {
        for a in (actions) {
            if ((a[1]).match_begin(string)) {
                data = a;
                break;
            }
        }
        if (data) {
            parse = $command_parser.parse(this(), data[2], $null_parser);
            (> .handle_parser_result(@parse) <);
            return;
        }
    }
    catch ~nodetail
        return (.location()).get_detail(string);
    .ptell(("No '" + string) + "' action registered.", #[['type, 'error]]);
};

public method .reset_actions() {
    (| clear_var('actions) |);
    
    // $#Edited: 17 Mar 97 13:51 $brandon
};

public method .actions() {
    return actions;
    
    // $#Edited: 17 Mar 97 13:51 $brandon
};

public method .register_action() {
    arg name, link;
    
    actions = dict_add(actions || #[], name, link);
};


new object $robot: $body;

var $root manager = $reaper;
var $has_name name = ['uniq, "Robot", "the Robot"];
var $described prose = <$ctext_frob, [["A generic automated robot object."], #[['this, $robot]]]>;
var $located location = $lost_and_found;
var $located obvious = 1;
var $body body_parts = #[];
var $location contents = [];
var $command_cache shortcut_cache = [];
var $root owned = [$robot];
var $command_cache remote_cache = #[["@reactions", [["@reactions"], #[[$robot, 1]]]], ["@boot", [["@boot"], #[[$thing, 1]]]]];
var $robot last_id = 0;
var $robot reactions = 0;
var $robot active = 0;
var $robot match_types = #[["regexp", ['regexp, "rex"]], ["pattern", ['match_pattern, "pat"]], ["template", ['match_template, "tmp"]]];
var $has_commands remote = #[["@reactions", [["@reactions", "*", "@reactions <this>", 'reactions_cmd, #[[1, ['this, []]]]]]]];
var $robot active_ids = 0;
var $thing gender = $gender_neuter;

public method .parse_line() {
    arg line;
    var parse;
    
    (> .perms(sender()) <);
    catch any {
        parse = $command_parser.parse(this(), line, $null_parser);
        (> .handle_parser_result(@parse) <);
    } with {
        if (error() == ~stop) {
            if ((traceback()[1])[2])
                .tell((traceback()[1])[2]);
        } else if ((.manager()) != this()) {
            (.manager()).tell_traceback(traceback(), line, 0, error());
        }
    }
};

public method .react_command() {
    arg str, match, sender, cmd;
    
    .parse_line(cmd);
    
    // $#Edited: 17 Dec 96 21:51 $brandon
};

public method .react_subcmd() {
    arg str, match, sender, cmd;
    var m;
    
    cmd = strsub(cmd, "%P", sender.name());
    for m in [1 .. listlen(match)]
        cmd = strsub(cmd, "%" + m, match[m]);
    .parse_line(cmd);
};

public method .tell() {
    arg what, @who;
    var line;
    
    if (!(.active()))
        return;
    switch (type(what)) {
        case 'list:
            for line in (what)
                .tell(line, @who);
        case 'string:
            // drop through, this is what we want
        default:
            return;
    }
    if (who && (sender().is($place)))
        who = who[1];
    else
        who = sender();
    if (who == this())
        return;
    .check_reactions('tell, what, who);
};

public method .event_notify() {
    arg event, origin, @args;
    
    if (caller() != $event_handler)
        throw(~perm, caller() + " is not $event_handler.");
    if (!(.active()))
        return;
    if (event == 'social)
        .check_reactions(args[2], args[3], args[1]);
    
    // $#Edited: 07 Mar 97 15:57 $miro
};

public method .startup() {
    .hook_events('startup);
};

protected method .check_reactions() {
    arg type, str, sender;
    var rnum, t, id, chance, times, method, template, m, types;
    
    rnum = random(100);
    if (type == 'tell)
        types = ['tell, 'any];
    else
        types = [type, 'notell, 'any];
    for t in (types) {
        if (!dict_contains(active, t))
            continue;
        for id in (dict_keys(active[t])) {
            [chance, times] = (active[t])[id];
            if (rnum > chance)
                break;
            [method, template] = reactions[id];
            if ((!template) || (m = str.(method)(template))) {
                if (times == 1)
                    .remove_active(t, id);
                else if (times > 1)
                    .update_active(t, id, [chance, --times]);
                if ((.do_reaction(str, m, id, sender)) != 'continue)
                    return;
            }
        }
    }
};

public method .active() {
    return active;
};

protected method .update_active() {
    arg key, id, value;
    
    active = dict_add(active, key, dict_add(active[key], id, value));
};

protected method .remove_active() {
    arg key, id;
    
    active = dict_add(active, key, dict_del(active[key], id));
    if (!(active[key]))
        active = dict_del(active, key);
    if (!active)
        clear_var('active);
};

public method .activate_reaction() {
    arg id;
    var ra, key, e, inserted, chance, times;
    
    if ((!reactions) || (!dict_contains(reactions, id)))
        throw(~noreaction, ("No reaction with id '" + id) + "'.");
    if (!active)
        active = #[];
    [key, chance, times] = sublist(reactions[id], 3, 3);
    if (dict_contains(active, key)) {
        ra = active[key];
        if (ra.contains(id))
            return .update_active(key, id, [chance, times]);
        active = dict_del(active, key);
        ra = map e in (ra) to (e);
    } else {
        ra = [];
    }
    for e in [1 .. listlen(ra)] {
        if ((((ra[e])[2])[1]) < chance) {
            ra = insert(ra, e, [id, [chance, times]]);
            inserted++;
        }
    }
    if (!inserted)
        ra += [[id, [chance, times]]];
    active = dict_add(active, key, hash e in (ra) to (e));
    active_ids = dict_add(active_ids || #[], id, key);
};

protected method .do_reaction(): forked {
    arg str, match, id, sender;
    var method, args, min, max, time, range;
    
    [[method, args], min, max] = sublist(reactions[id], 6);
    range = max - min;
    if (range < 2)
        time = 1;
    else
        time = random(range) + min;
    $scheduler.sleep(time);
    catch any
        return (> .(method)(str, match, sender, @args) <);
    with
        .tell_traceback(traceback());
    return 'stop;
};

public method .tell_traceback() {
    arg @args;
    
};

public method .add_reaction() {
    arg @args;
    var r, id;
    
    // make sure it doesn't already exist..
    for r in (reactions || #[]) {
        if (((r[2])[2]) == (args[2])) {
            if ((r[2]) == args)
                return r[1];
        }
    }
    (> .check_reaction_args(@args) <);
    reactions = dict_add(reactions || #[], ++last_id, args);
};

private method .check_reaction_args() {
    arg method, template, type, chance, times, hook, min, max;
    
    (> .check_reaction_matchwith(method) <);
    (> .check_reaction_template(template) <);
    (> .check_reaction_type(type) <);
    (> .check_reaction_chance(chance) <);
    (> .check_reaction_times(times) <);
    (> .check_reaction_hook(hook) <);
    (> .check_reaction_hook_method(hook[1]) <);
    (> .check_reaction_hook_args(hook[2]) <);
    (> .check_reaction_min(min) <);
    (> .check_reaction_max(max) <);
};

public method .del_reaction() {
    arg id;
    var key;
    
    (> .perms(sender()) <);
    if (!dict_contains(reactions, id))
        return;
    key = (reactions[id])[3];
    (| .remove_active(key, id) |);
    reactions = reactions.del(id);
};

public method .reactions() {
    return reactions;
    
    // $#Edited: 18 Dec 96 10:25 $brandon
};

public method .match_type() {
    arg type;
    
    type = strsed(tostr(type), "match_", "");
    if (!dict_contains(match_types, type))
        throw(~type, "Invalid type matcher: " + type);
    return (| match_types[type] |);
    
    // $#Edited: 18 Dec 96 17:41 $brandon
};

public method .reactions_cmd() {
    arg cmdstr, cmd, this;
    var id, m, tmpl, type, chance, times, method, args, max, min, out, t, a;
    
    // [id, [match, template, type, chance, times, [method, args], max, min]]
    out = [];
    for id in (dict_keys(reactions || #[])) {
        [m, tmpl, type, chance, times, [method, args], min, max] = reactions[id];
        t = $robot.match_type(m);
        a = dict_contains(active_ids, id);
        out += [strfmt("%l%3r %3r %4r %6l %8c %22l %l %l", a ? "*" : " ", id, chance, (times == (-1)) ? "inf" : times, type, (min == max) ? min : ((min + "~") + max), method, t[2], tmpl ? ("\"" + tmpl) + "\"" : "anything")];
    }
    if (out)
        return (["-- Defined Reactions:", "  ID %CH    # TYPE    DELAY   HOOK                   MT  TEMPLATE"] + out) + ["--"];
    return "-- No Reactions Defined --";
};

private method .check_reaction_hook() {
    arg hook;
    
    if (type(hook) != 'list)
        throw(~type, "Reaction hook is not a list.");
    if (listlen(hook) != 2)
        throw(~type, "Reaction hook is not a two element list.");
};

private method .check_reaction_hook_method() {
    arg method;
    
    if (type(method) != 'symbol)
        throw(~type, "Reaction hook method is not a symbol.");
};

private method .check_reaction_hook_args() {
    arg args;
    
    if (type(args) != 'list)
        throw(~type, "Reaction hook arguments is not a list.");
};

private method .check_reaction_min() {
    arg min;
    
    if (type(min) != 'integer)
        throw(~type, "Reaction minimum delay is not a integer.");
};

private method .check_reaction_max() {
    arg max;
    
    if (type(max) != 'integer)
        throw(~type, "Reaction maximum delay is not a integer.");
};

private method .check_reaction_matchwith() {
    arg method;
    
    if (type(method) != 'symbol)
        throw(~type, "Match type is not a symbol.");
};

private method .check_reaction_template() {
    arg template;
    
    if (type(template) != 'string)
        throw(~type, "Match template is not a string.");
};

private method .check_reaction_type() {
    arg type;
    
    if (type(type) != 'symbol)
        throw(~type, "Reaction type is not a symbol.");
};

private method .check_reaction_chance() {
    arg chance;
    
    if (type(chance) != 'integer)
        throw(~type, "Reaction chance is not a integer.");
};

private method .check_reaction_times() {
    arg times;
    
    if (type(times) != 'integer)
        throw(~type, "Reaction times is not a integer.");
};

public method .update_reaction() {
    arg id, part, value;
    var r, chance, times, active;
    
    (> .perms(sender()) <);
    if (!(reactions.contains(id)))
        throw(~noreaction, ("No reaction with id \"" + id) + "\".");
    r = reactions[id];
    if ((active = dict_contains(active_ids, id)))
        .deactivate_reaction(id);
    switch (part) {
        case 'matchwith:
            (> .check_reaction_matchwith(value) <);
            r = replace(r, 1, value);
        case 'template:
            (> .check_reaction_template(value) <);
            r = replace(r, 2, value);
        case 'type:
            (> .check_reaction_type(value) <);
            r = replace(r, 3, value);
        case 'chance:
            (> .check_reaction_chance(value) <);
            r = replace(r, 4, value);
        case 'times:
            (> .check_reaction_times(value) <);
            r = replace(r, 5, value);
        case 'method, 'hook_method:
            (> .check_reaction_hook_method(value) <);
            r = replace(r, 6, replace(r[6], 1, value));
        case 'args, 'hook_args:
            (> .check_reaction_hook_args(value) <);
            r = replace(r, 6, replace(r[6], 2, value));
        case 'min, 'min_delay:
            (> .check_reaction_min(value) <);
            r = replace(r, 7, value);
        case 'max, 'max_delay:
            (> .check_reaction_max(value) <);
            r = replace(r, 8, value);
        default:
            throw(~invpart, ("Invalid part '" + part) + ".");
    }
    reactions = reactions.add(id, r);
    if (active)
        .activate_reaction(id);
};

public method .deactivate_reaction() {
    arg id;
    
    if (active_ids && dict_contains(active_ids, id)) {
        .remove_active(active_ids[id], id);
        active_ids = dict_del(active_ids, id);
        if (!active_ids)
            clear_var('active_ids);
    }
    
    // $#Edited: 19 Dec 96 10:38 $brandon
};


new object $command_aliases: $user_interfaces;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $command_aliases command_aliases = [];
var $root manager = $command_aliases;
var $root managed = [$command_aliases];
var $root owned = [$command_aliases];

root method .init_command_aliases() {
    command_aliases = [];
};

root method .uninit_command_aliases() {
    command_aliases = [];
};

public method .command_aliases() {
    return command_aliases;
};

public method .all_command_aliases() {
    var user, aliases, userc;
    
    // Collect complete command alias list from ancestors.
    aliases = [];
    for user in (.ancestors()) {
        userc = (| user.command_aliases() |);
        if (userc)
            aliases += userc;
        if (user == definer())
            break;
    }
    return aliases;
};

public method .match_command_aliases() {
    arg str;
    var alias, argf, match, newstr;
    
    // attempts to rebuild the string for an alias.
    if (sender() != this())
        throw(~perm, "Sender is not this.");
    for alias in (.all_command_aliases()) {
        match = str.match_pattern(alias[1]);
        if (match != 0) {
            newstr = alias[2];
            for argf in [1 .. match.length()]
                newstr = newstr.replace("%" + tostr(argf), match[argf]);
            return newstr;
        }
    }
    return str;
};

public method .add_command_alias() {
    arg alias, actual;
    var relation, a;
    
    (> .perms(sender()) <);
    if ((type(alias) != 'string) || (type(actual) != 'string))
        throw(~type, "alias and actual are not strings.");
    relation = (> $command_lib.parse_relation(alias, actual) <);
    
    // have it 'replace' the old alias (if one exists) by first removing
    // the old one, and adding the new one later.
    for a in (command_aliases) {
        if ((a[1]) == alias)
            command_aliases = command_aliases.setremove(a);
    }
    command_aliases += [[(relation[1])[1], (relation[2])[2]]];
    
    // $# Edited 18 Oct 1995 12:55 Lynx ($lynx)
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .del_command_alias() {
    arg alias;
    var ca, rel;
    
    (> .perms(sender()) <);
    if (type(alias) != 'string)
        throw(~type, "alias is not a string.");
    rel = (> $command_lib.parse_relation(alias, alias) <);
    rel = rel[1];
    for ca in (command_aliases) {
        if ((ca[1]) == (rel[1])) {
            command_aliases = command_aliases.setremove(ca);
            return;
        }
    }
    throw(~aliasnf, ("alias `" + alias) + "' is not found");
    
    // $# Edited 18 Oct 1995 13:19 Lynx ($lynx)
};


new object $bad_commands: $user_interfaces;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $bad_commands non_supported_cmds = #[["quit", "@quit"], ["WHO", "@who"], ["@create", "@new"], ["help", "@help"], ["news", "@news"], ["page", "@page"], ["@gender", "@set gender"], ["uptime", "@status"], ["@alias", "@add-command-alias` or `@add-name-alias"], ["@check", "@monitor"], ["@paranoid", "@monitor"], ["@version", "@status"], ["@lock", "@set lock"], ["@unlock", "@set lock"]];
var $has_commands local = #[["@create", [["@create", "*", "@create <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["help", [["help", "*", "help <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["page", [["page", "*", "page <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["who", [["who", "*", "who <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["quit", [["quit", "*", "quit <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["news", [["news", "*", "news <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@gender", [["@gender", "*", "@gender <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["uptime", [["uptime", "*", "uptime <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@alias", [["@alias", "*", "@alias <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@check|@paranoid", [["@check|@paranoid", "*", "@check|@paranoid <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@version", [["@version", "*", "@version <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@lock", [["@lock", "*", "@lock <any>", 'old_command_cmd, #[[1, ['any, []]]]]]], ["@unlock", [["@unlock", "*", "@unlock <any>", 'old_command_cmd, #[[1, ['any, []]]]]]]];
var $root manager = $bad_commands;
var $root managed = [$bad_commands];
var $root owned = [$bad_commands];

public method .add_old_cmd_reference() {
    arg oldcmd, @newcmd;
    
    (> .perms(caller()) <);
    if (this() != $bad_commands)
        throw(~perm, "Only define bad commands on $bad_commands");
    if ((" " in oldcmd) || (("<" in oldcmd) || ("*" in oldcmd)))
        throw(~perm, "Just the first word of the old command.");
    if (newcmd)
        non_supported_cmds = non_supported_cmds.add(oldcmd, newcmd[1]);
    .add_command(oldcmd + " <any>", 'old_command_cmd);
};

protected method .old_command_cmd() {
    arg cmdstr, com, @args;
    var line, equiv, pref;
    
    (> .perms(caller(), 'command) <);
    equiv = (| ($bad_commands.non_supported_cmds())[com] |);
    line = ("Oops, `" + com) + "` is not supported here.";
    if (equiv)
        line = ((line + "  Try `") + equiv) + "`";
    .tell(line);
    .tell("Use `@help commands` for an explanation on the differences in commands.");
};

public method .non_supported_cmds() {
    return non_supported_cmds;
};


new object $help_ui: $user_interfaces;

var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $has_commands local = #[["@help", [["@help", "*", "@help <any>", 'help_cmd, #[[1, ['any, []]]]]]]];
var $has_commands shortcuts = #[["?*", ['help_cmd, ["?", 1]]]];
var $help_ui current = 1;
var $help_ui history = [$help_coldcore];
var $root manager = $help_ui;
var $help_ui index = 0;
var $root owned = [$help_ui];
var $root managed = [$help_ui];

root method .init_help_ui() {
    history = [$help_lib.default_node()];
    current = 1;
};

public method .current_node() {
    return history[current];
};

protected method .help_cmd() {
    arg cmdstr, cmd, args;
    var o, opt, optval, way, node, links, i;
    
    (> .perms(caller(), 'command) <);
    o = #[["?", ["h?istory"]], ["<", ["b?ack"]], [">", ["f?orward"]], ["!", ["fix"]], ["#", ["l?inks"]], ["^", ["u?p"]]];
    args = $parse_lib.getopt(args, o.values());
    opt = args[2];
    args = args[1];
    if (!opt) {
        if (!args) {
            if (cmd == "?")
                node = .current_node();
            else
                node = $help_lib.default_node();
        } else {
            args = args.join();
            if ((args[1]) in (o.keys())) {
                opt = (o[args[1]])[1];
                if ((args.length()) > 1)
                    optval = args.subrange(2);
            } else if ((o = match_template(args, "* in *"))) {
                if (!(i = $help_index.match_children(o[3])))
                    return ("\"" + (o[3])) + "\" is not a help index.";
                if ((!(o[1])) || ((o[1]) == "#"))
                    node = i;
                else if (!(node = (| i.match_begin(o[1]) |)))
                    return ((("Unable to find help on \"" + (o[1])) + "\" in the ") + (i.name())) + " index.";
            } else {
                catch ~nonode, ~ambig {
                    node = (> .parse_help_reference(args) <);
                } with {
                    if (error() == ~ambig)
                        return ([("Topic '" + args) + "' has multiple possibilities:", ""] + ((((traceback()[1])[3]).mmap('namef, 'ref)).prefix("    "))) + ["", "---"];
                    return (traceback()[1])[2];
                }
            }
        }
    } else {
        // since all options override each other, just use the last one.
        optval = (opt[opt.length()])[4];
        opt = (opt[opt.length()])[1];
    }
    if (!node) {
        catch ~nonode {
            switch (opt) {
                case "u?p":
                    o = ((.current_node()).parents())[1];
                    while ((o.is($help_node)) && (o.holder()))
                        o = (o.parents())[1];
                    if ((!(o.is($help_node))) || (o.top_of_help_heirarchy()))
                        return "You are at the top of this help node heirarchy.";
                    node = o;
                case "h?istory":
                    return ._help_node_history();
                case "b?ack":
                    if (!optval)
                        optval = "";
                    node = (> ._navigate_node_history("<" + optval) <);
                case "f?orward":
                    if (!optval)
                        optval = "";
                    node = (> ._navigate_node_history(">" + optval) <);
                case "fix":
                    .tell("Fixing your help history.");
                    for node in (history) {
                        if ((!valid(node)) || (!(node.has_ancestor($help_node))))
                            history = setremove(history, node);
                    }
                    current = listlen(history);
                    return;
                case "l?inks":
                    node = .current_node();
                    links = node.links();
                    if (!links) {
                        .tell(("No links from " + (node.name())) + ".");
                    } else {
                        .tell(("Links from " + (node.name())) + ":");
                        .tell(map i in (links) to (strfmt("%30l %s", @i)).prefix("    "));
                    }
                    if (node.group()) {
                        links = ((node.parents())[1]).children();
                        links = filter o in (links) where ((!(o.nolist())) && (o != node));
                        if (!links)
                            return ("No group nodes with " + (node.name())) + ".";
                        .tell(("Group nodes with " + (node.name())) + ":");
                        .tell(map i in (links) to (strfmt("%30e %s", i.name(), i)).prefix("    "));
                    }
                    return;
            }
        } with {
            return (traceback()[1])[2];
        }
    }
    .set_help_node(node);
    .tell_help_node(node);
    
    // $#Edited: 20 Jan 97 20:45 $brandon
};

protected method .last_visited() {
    (> .perms(sender()) <);
    return last_visited;
};

public method .help_index() {
    return index;
};

protected method ._back_help_node() {
    var pos;
    
    pos = current - 1;
    if (pos >= 1) {
        current = pos;
        return history[current];
    }
    throw(~nonode, "You are at the start of your help node history, use \"??\" to list the history.");
};

protected method ._forward_help_node() {
    var pos;
    
    pos = current + 1;
    if ((pos <= ($help_lib.history_cap())) && (pos <= (history.length()))) {
        current = pos;
        return history[current];
    }
    throw(~nonode, "You are at the end of your help node history, use \"??\" to list the history.");
};

protected method .set_help_node() {
    arg node, @navhist;
    var cur;
    
    if (node.index())
        index = node.index();
    cur = history[current];
    if (node in history) {
        if ((history[current]) == node)
            return;
        if (navhist)
            return (current = node in history);
        else
            history = setremove(history, node);
    } else if (listlen(history) >= ($help_lib.history_cap())) {
        history = sublist(history, 1, $help_lib.history_cap());
    }
    current = cur in history;
    if (navhist) {
        if (current)
            history = insert(history, current + 1, node);
    } else {
        history = (history ? sublist(history, 1, current) : []) + [node];
    }
    current = node in history;
};

protected method ._navigate_node_history() {
    arg str;
    var node, r, hist, match;
    
    while ((r = regexp(str, "^ *([<>]) *([^<>]*) *"))) {
        if (r[2]) {
            if ((r[1]) == "<")
                hist = (sublist(history, 1, current - 1).reverse()) + (sublist(history, current).reverse());
            else
                hist = sublist(history, current + 1) + sublist(history, 1, current);
            r = r[2];
            for node in (hist) {
                if (node.match_name(r)) {
                    .set_help_node(node);
                    match++;
                    break;
                }
            }
            if (!match)
                throw(~nonode, ("There is no node \"" + r) + "\" in your history.");
        } else if ((r[1]) == "<") {
            (| .set_help_node(._back_help_node()) |);
        } else {
            (| .set_help_node(._forward_help_node()) |);
        }
        str = strsed(str, "^ *([<>]) *([^<>]*) *", "");
    }
    return history[current];
};

protected method ._help_node_history() {
    var node, line;
    
    .tell("Help node history:");
    for node in [1 .. history.length()] {
        line = "   ";
        if (node == current)
            line = "=> ";
        catch any {
            .tell(line + ((history[node]).name()));
        } with {
            history = history.delete(node);
            .set_help_node(history[1]);
            .tell(line + ">> ERROR: INVALID NODE IN HISTORY <<");
        }
    }
};

protected method .tell_help_node() {
    arg node;
    var out, len, clen, line, n, name, changed, sibs, end, start, flen;
    
    // len = .linelen() % 2 ? .linelen() - 1 : .linelen();
    len = .linelen();
    name = node.node_name();
    while (strlen(name) >= (len - 10)) {
        name = substr(name, (":" in name) + 1);
        changed++;
    }
    if (changed)
        name = ".." + name;
    line = strfmt("%*{-}c", len, (" " + name) + " ");
    .tell(line);
    .ptell(node.body(), #[['type, 'help], ['ctype, 'ctext]]);
    if (node.group()) {
        line = (start = (end = ""));
        sibs = filter n in (((node.parents())[1]).children()) where (!(n.nolist()));
        flen = (((strlen((sibs.mmap('small_name)).join()) + (listlen(sibs) * 3)) + 3) + strlen(end)) + strlen(start);
        while (flen > len) {
            if ((listlen(sibs) / 2) >= (node in sibs)) {
                sibs = sublist(sibs, 1, listlen(sibs) - 1);
                if (!end)
                    end = ".. ";
            } else {
                sibs = sublist(sibs, 2);
                if (!start)
                    start = ".. ";
            }
            flen = (((strlen((sibs.mmap('small_name)).join()) + (listlen(sibs) * 3)) + 3) + strlen(end)) + strlen(start);
        }
        if (sibs) {
            for n in (sibs) {
                if (n == node)
                    line += ". ";
                else if (n.holder())
                    line += (((n.name()).word(1, "|")).word(1)) + " ";
                else
                    line += ("[" + (((n.name()).word(1, "|")).word(1))) + "] ";
            }
            line = (((" " + start) + line) + end).center(len, "-", 'both);
        } else {
            line = "-" * len;
        }
    } else {
        line = "-" * len;
    }
    .tell(["", line]);
};

root method .uninit_help_ui() {
    clear_var('history);
    clear_var('current);
    clear_var('index);
};

protected method .help_node_history() {
    return history;
};

protected method .parse_help_reference() {
    arg str;
    var node, cnode, current, indices, len, links, i, matches, m;
    
    if ((str[1]) == "$") {
        node = (| $object_lib.to_dbref(str) |);
        if ((!node) || ((!(node.has_ancestor($help_node))) && (!(| (node = node.help_node()).has_ancestor($help_node) |))))
            throw(~nonode, ("\"" + str) + "\" is not a help node, and does not have a help node assigned to it.");
        return node;
    }
    if ((m = match_template(str, "*=*"))) {
        if (!(m[2]))
            throw(~nonode, ("Search in " + (m[1])) + " for nothing?");
        else if (match_template(m[1], "g?roup"))
            return (> .find_help_in_group(m[2]) <);
        else if (match_template(m[1], "l?inks"))
            return (> .find_help_in_links(m[2]) <);
        else if (match_template(m[1], "i?ndex"))
            return (> .find_help_in_index(m[2]) <);
        if (!(i = $help_index.match_children(m[1])))
            throw(~nonode, ("\"" + (m[1])) + "\" is not a help index.");
        if ((m[2]) == "#")
            return i;
        if (!(node = (| i.match_begin(m[2]) |)))
            throw(~nonode, ((("Unable to find help on \"" + (m[2])) + "\" in the ") + (i.name())) + " index.");
        return node;
    }
    return (| .find_help_in_links(str) |) || ((| .find_help_in_group(str) |) || (> .find_help_in_index(str) <));
};

public method .find_help_in_links() {
    arg str;
    var links, node, index;
    
    links = ((| .current_node() |) || ($help_lib.default_node())).links();
    for node in (links.keys()) {
        if (match_begin(node, str)) {
            node = links[node];
            return node;
        }
    }
    throw(~nonode, ("Unable to find link \"" + str) + "\".");
    
    // $#Edited: 09 Nov 96 20:11 $brandon
    // $#Moved 10 Nov 96 10:56 from $brandon.find_help_in_links() by $brandon
};

public method .find_help_in_group() {
    arg str;
    var sibling, node;
    
    node = (.current_node()) || ($help_lib.default_node());
    if (node.group()) {
        for sibling in (((node.parents())[1]).children()) {
            if ((sibling == node) || ((sibling.nolist()) || (sibling.holder())))
                continue;
            if (sibling.match_name(str))
                return sibling;
        }
    }
    throw(~nonode, ("Unable to find group node \"" + str) + "\".");
};

public method .find_help_in_index() {
    arg str;
    var indices, i, node, index, matches, len;
    
    // get from $help_lib to keep in a consistent prioritized order
    indices = $help_lib.indices();
    
    // put the 'current' node at the end, and use it first
    if ((i = sender().help_index())) {
        indices = setremove(indices, i);
        indices = setadd(indices, i);
    }
    
    // loop through the indices backwards
    len = listlen(indices);
    matches = [];
    for i in [1 .. len] {
        i = (len - i) + 1;
        catch any {
            // return the first perfect match
            if ((node = (> (indices[i]).match_begin(str) <)))
                return node;
        } with {
            if (error() == ~ambig)
                matches += ((traceback()[1])[3]) || [];
        }
    }
    if (matches)
        throw(~ambig, "More than one match.", matches);
    throw(~nonode, ("Unable to find help on \"" + str) + "\".");
};

protected method .reset_help_history() {
    history = [$help_coldcore];
    current = 1;
};

protected method .clear_help_history() {
    (| clear_var('history) |);
    (| clear_var('current) |);
};

public method .fmt_help_from() {
    arg from;
    var node, c, name;
    
    c = .task_connection();
    for node in (from.traverse()) {
        name = (node.name()).word(1, "|");
        c.write(["", name, "=" * strlen(name)]);
        if (!(node.holder()))
            c.write($parse_lib.filter_ctext(node.body(), #[['formatter, $plaintext_format]]));
    }
};


new object $editor_reference: $has_commands;

var $root manager = $editor_reference;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root created_on = 820684615;
var $root inited = 1;
var $editor_reference active_editor = 0;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[["@mcp-upload-session", [["@mcp-upload-session", "*", "@mcp-upload-session <descendant of $editor_session>", 'mcp_upload_cmd, #[[1, ['descendant, [$editor_session]]]]]]], ["@cleanup-sessions|@c-s?essions", [["@cleanup-sessions|@c-s?essions", "", "@cleanup-sessions|@c-s?essions", 'cleanup_sessions, #[]]]], ["@edit", [["@edit", "*", "@edit <any>", 'edit_cmd, #[[1, ['any, []]]]]]]];
var $editor_reference bg_sessions = 0;
var $root managed = [$editor_reference];
var $root owned = [$editor_reference];
var $root defined_settings = #[["local-editor", #[['parse, ['parse_local_editor]]]]];
var $root settings = #[["local-editor", 'none]];

protected method .reinvoke_editor() {
    arg @session;
    var i, t, name;
    
    t = "";
    [(session ?= active_editor), (name ?= "")] = session;
    if (session == 0)
        return "No session to resume.";
    if (active_editor && ((active_editor != session) || (!(| session.is_resumable() |))))
        t = (.store_editor()) + " ";
    if ((!valid(session)) || (!(session in (bg_sessions + [active_editor])))) {
        active_editor = 0;
        return "Invalid session - editor cleared.";
    }
    if (!(| session.is_resumable() |))
        return "The session is not resumable.";
    active_editor = session;
    bg_sessions = bg_sessions.setremove(active_editor);
    bg_sessions = filter i in (bg_sessions) where (valid(i));
    .add_parser($editor_parser);
    return (((t + "Resumed ") + active_editor) + (name ? " " + name : "")) + ".";
};

public method .invoke_editor() {
    arg @args;
    
    // finishing object, finishing method, initial text, client data;
    if (active_editor != 0)
        throw(~misc, "Editor already active");
    active_editor = $editor_session.spawn();
    if (active_editor.startup(@args))
        .add_parser($editor_parser);
    
    // $#Edited: 06 Aug 96 16:38 $jenner
};

public method .quit_editor() {
    if (active_editor == 0)
        throw(~misc, "No active editor.");
    .perms(sender(), active_editor);
    .del_parser($editor_parser);
    active_editor.destroy();
    clear_var('active_editor);
};

public method .store_editor() {
    var t;
    
    if (active_editor) {
        (sender() == this()) || (> .perms(sender(), active_editor) <);
        .del_parser($editor_parser);
        bg_sessions = (bg_sessions ? bg_sessions : []).setadd(active_editor);
        t = active_editor;
        active_editor = 0;
        return "Editor session %s saved.".format(t);
    }
    return "No active editor.";
    
    // $#Edited: 06 Aug 96 16:38 $jenner
};

public method .active_editor() {
    return active_editor;
    
    // $#Edited: 06 Aug 96 16:38 $jenner
};

public method .cleanup_sessions() {
    arg @who_cares;
    var out, s;
    
    (sender() == $housekeeper) || (> .perms(sender(), this()) <);
    out = [];
    for s in (bg_sessions || []) {
        if (valid(s) && (s.cleanup_session()))
            s.destroy();
        else
            out = setadd(out, s);
    }
    bg_sessions = out;
    if (valid(active_editor) && (active_editor.cleanup_session())) {
        active_editor.destroy();
        clear_var('active_editor);
    }
    return "Clean and invalid sessions cleared.";
};

public method .edit_cmd() {
    arg cmdstr, com, args;
    var syn, num, sess, out, type, i, e, bg;
    
    (> .perms(caller(), 'command) <);
    syn = "@edit <object reference> [+type=...]";
    args = args.trim();
    if (!args) {
        // list sessions
        out = [];
        e = .active_editor();
        if (e) {
            if ($editor_parser in (.parsers()))
                out += ["** %0 " + (e.session_name())];
            else
                out += ["   %0 " + (e.session_name())];
        }
        bg = .background_editor_sessions();
        for sess in [1 .. listlen(bg)]
            out += [(("   %" + sess) + " ") + ((bg[sess]).session_name())];
        if (out)
            return ["Editor Sessions:"] + out;
        return "No editor sessions.";
    } else if ((args[1]) == "%") {
        // resume session
        args = substr(args, 2);
        if ((!args) || ((args[1]) == " ")) {
            num = 0;
        } else {
            catch ~nonum
                num = (> args.to_number() <);
            with
                return (traceback()[1])[2];
        }
        if (!num) {
            if (.active_editor())
                return .reinvoke_editor(.active_editor(), "%0");
            else if (.background_editor_sessions())
                sess = (.background_editor_sessions())[1];
            else
                return "No sessions to resume.";
        } else {
            if ((listlen((.background_editor_sessions()) || []) < num) || (num < 0))
                return ("There is not an editor session %" + num) + ".";
            sess = (.background_editor_sessions())[num];
        }
        return .reinvoke_editor(sess, "%" + num);
    } else {
        args = $parse_lib.getopt(args, [["t?ype", 1]]);
        if ((i = "t?ype" in ((args[2]).slice(1))))
            type = ((args[2])[i])[4];
        type ?= "any";
        catch ~objnf
            args = replace(args, 1, (> $parse_lib.ref((args[1]).join()) <));
        with
            return (traceback()[1])[2];
        if (.active_editor()) {
            .tell("Storing active editor..");
            .store_editor();
        }
        return .new_editor_session(@args, type);
    }
};

public method .local_editor() {
    return .get_setting("local-editor", $editor_reference);
};

protected method .mcp_upload_cmd() {
    arg cmdstr, cmd, session;
    var text, status, tmp;
    
    (> .perms(caller(), 'command) <);
    text = (| .read("Reading the editor session text...") |);
    if (type(text) != 'list)
        return "Upload failed.";
    if (!(session in bg_sessions))
        return "Illegal session - upload failed.";
    tmp = active_editor;
    active_editor = session;
    catch any {
        status = session.mcp_upload(text);
    } with {
        .tell_traceback(traceback());
        status = "Compilation failed.";
    }
    active_editor = tmp;
    return status;
    
    // $#Edited: 21 Aug 96 15:26 $jenner
};

public method .edit_sessions_notify() {
    var e, s, bg;
    
    if (bg_sessions) {
        .tell("<editor> Use @edit to resume the following editor sessions:");
        e = .active_editor();
        if (e) {
            if ($editor_parser in (.parsers()))
                .tell("<editor> ** %0 " + (e.session_name()));
            else
                .tell("<editor>    %0 " + (e.session_name()));
        }
        bg = .background_editor_sessions();
        for s in [1 .. listlen(bg)]
            .tell((("<editor>    %" + s) + " ") + ((bg[s]).session_name()));
    } else if (.active_editor()) {
        .tell("<editor> Disconnected from an active session. Use @edit %0 to resume.");
    }
};

public method .do_save() {
    arg @info;
    
    // The purpose of this method is to ensure that save is ran with
    // this user's perms
    if ((!(sender().has_ancestor($editor_session))) || (!((sender().startup_sender()) == this())))
        throw(~perm, "Permission denied");
    return (> (info[1]).(info[2])(info[3], info[4]) <);
};

public method .background_editor_sessions() {
    return bg_sessions;
    
    // $#Edited: 11 Dec 96 14:26 $brandon
};

public method .parse_local_editor() {
    arg value, @args;
    var styles;
    
    value = (| (styles = #[["None", 'none], ["MCP", 'mcp]])[value] |);
    if (!value)
        throw(~wrong, "Local editor must be one of: " + ((styles.keys()).to_english("", " or ")));
    return value;
};


new object $channel_ui: $user_interfaces;

var $root manager = $channel_ui;
var $channel_ui active_channels = #[];
var $root flags = ['variables, 'methods, 'code, 'command_cache, 'fertile, 'core];
var $root created_on = 838251646;
var $channel_ui channel_dict = #[];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[["@desc-c?hannel", [["@desc-c?hannel", "* as *", "@desc-c?hannel <any> as <any>", 'describe_channel_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["@ch?annels", [["@ch?annels", "*", "@ch?annels <any:+f?ull +d?etailed>", 'list_channels_cmd, #[[1, ['any_opt, [["f?ull"], ["d?etailed"]]]]]]]], ["@join-lock-channel|@jlc", [["@join-lock-channel|@jlc", "* with|to *", "@join-lock-channel|@jlc <any> with|to <any>", 'channel_add_lock_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["@leave-lock-channel|@llc", [["@leave-lock-channel|@llc", "* with|to *", "@leave-lock-channel|@llc <any> with|to <any>", 'channel_add_lock_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["@use-lock-channel|@ulc", [["@use-lock-channel|@ulc", "* with|to *", "@use-lock-channel|@ulc <any> with|to <any>", 'channel_add_lock_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["@add-channel-manager|@acm", [["@add-channel-manager|@acm", "* to *", "@add-channel-manager|@acm <user> to <any>", 'channel_add_manager, #[[1, ['user, []]], [3, ['any, []]]]]]], ["@del-channel-manager|@dcm", [["@del-channel-manager|@dcm", "* from *", "@del-channel-manager|@dcm <user> from <any>", 'channel_del_manager, #[[1, ['user, []]], [3, ['any, []]]]]]], ["@add-ch?annel|@addcom", [["@add-ch?annel|@addcom", "*", "@add-ch?annel|@addcom <any>", 'addcom_cmd, #[[1, ['any, []]]]]]], ["@del-ch?annel|@delcom", [["@del-ch?annel|@delcom", "*", "@del-ch?annel|@delcom <any>", 'delcom_cmd, #[[1, ['any, []]]]]]], ["@purge-channel", [["@purge-channel", "*", "@purge-channel <any>", 'channel_purge_cmd, #[[1, ['any, []]]]]]], ["@blahblahblah", [["@blahblahblah", "* * * *", "@blahblahblah <any> <any> <any> <any>", 'addcom_cmd, #[[1, ['any, []]], [2, ['any, []]], [3, ['any, []]], [4, ['any, []]]]]]]];
var $root inited = 1;
var $root managed = [$channel_ui];
var $root owned = [$channel_ui];
var $channel_ui channel_creation = 1;
var $root trusted_by = [$channel_db];
var $channel_ui credits = ["Chuck and Brad"];

public method .broadcast() {
    arg channel, msg;
    var q, spammer_name, message;
    
    (> .perms(sender()) <);
    
    // is this really a command?. If so, do the command.
    switch (msg) {
        case "who":
            if ((channel in ($channel_db.system_channels())) && (!($sys.is_system(sender()))))
                return "Sorry, that's a listen only channel.";
            .channel_members(channel);
            return;
        case "off":
            .channel_off(channel);
            return;
        case "on":
            .channel_on(channel);
            return;
    }
    if ((channel in ($channel_db.system_channels())) && (channel != 'All))
        return "Sorry, that's a listen only channel.";
    if (!(active_channels.contains(channel)))
        return "You must be on a channel to send a message to it.";
    
    // check for poses, thinking, etc.
    spammer_name = .name();
    switch (msg[1]) {
        case ":":
            message = (spammer_name + " ") + (msg.subrange(2));
        case "%":
            message = ((spammer_name + " . o O ( ") + (msg.subrange(2))) + " )";
        case "!":
            (> .channel_moderator_ok() <);
            message = msg.subrange(2);
        default:
            message = (spammer_name + ": ") + msg;
    }
    ._broadcast(channel, message);
    
    // $#Edited: 15 Feb 97 17:20 $brad
    // $#Edited: 15 Feb 97 18:00 $brad
    // $#Edited: 15 Feb 97 18:02 $brad
};

protected method .channel_on() {
    arg channel;
    
    if (!(active_channels.contains(channel))) {
        active_channels = active_channels.add(channel, 1);
        if (channel in ($channel_db.system_channels()))
            .tell(("<" + channel) + "> You have joined this channel");
        else
            .broadcast(channel, ":has joined this channel.");
    } else {
        .tell("You are already on this channel.");
    }
    
    // $#Edited: 15 Feb 97 17:58 $brad
};

public method .channel_moderator_ok() {
    (> .check_mojo() <);
    return 1;
    
    // $#Edited: 24 Jul 96 18:23 $user_chuck
};

protected method .channel_off() {
    arg channel;
    
    if (active_channels.contains(channel)) {
        if (channel in ($channel_db.system_channels()))
            .tell(("<" + channel) + "> You have left this channel.");
        else
            .broadcast(channel, ":has left this channel.");
        active_channels = active_channels.del(channel);
    } else {
        .tell("You are not on this channel.");
    }
    
    // $#Edited: 20 Nov 96 20:36 $brad
};

protected method .list_channels_cmd() {
    arg cmdstr, cmd, args;
    var opts, f, d, cur_channels, cd_keys, cd_values, i, alias, db, active, msg, match_with, match_pattern, tmp, form, add;
    
    (> .perms(caller(), 'command) <);
    opts = (args[2]).slice(1);
    if ((f = (| "f?ull" in opts |)))
        f = ((args[2])[f])[3];
    if ((d = (| "d?etailed" in opts |)))
        d = ((args[2])[d])[3];
    cd_keys = channel_dict.keys();
    cd_values = channel_dict.values();
    cur_channels = f ? (($channel_db.database()).values()).slice(1) : cd_values;
    match_with = (| .get_setting("match-with", $programmer) |) || 'match_pattern;
    match_pattern = (| (args[1])[1] |) || ((| .get_setting("match-default", $programmer) |) || "*");
    cur_channels = filter f in (cur_channels) where ((f.to_string()).(match_with)(match_pattern) != 0);
    if (!cur_channels)
        return "No channels found.";
    msg = [];
    add = [];
    for i in (cur_channels) {
        alias = (| cd_keys[i in cd_values] |) || "";
        db = (| $channel_db.exact_match(tosym((i.to_string()).lowercase())) |);
        if (type(db) == 'list) {
            msg += [[(active_channels.contains(i)) ? "*" : " ", alias, tostr(db[1]), (db[7]) || "<no description>"]];
            form = "%26r: %50l";
            if (d) {
                tmp = [form.format("Number of users", tostr(db[2])), form.format("Owner", (db[5]).name()), form.format("Managers", ((db[6]).mmap('namef, 'name)).to_english())];
                if (db[3])
                    tmp += [form.format("Join Lock", (db[3]).lock_name())];
                if (db[4])
                    tmp += [form.format("Leave Lock", (db[4]).lock_name())];
                if (db[8])
                    tmp += [form.format("Use Lock", (db[8]).lock_name())];
                add += [tmp];
            }
        } else {
            msg += [[(active_channels.contains(i)) ? "*" : " ", alias, "", "Channel not in database!"]];
        }
        refresh();
    }
    msg = (msg.transpose()).tabulate([["", ""], ["Alias", "-----"], ["Channel", "-------"], ["Description", "-----------"]]);
    if (d)
        msg = [msg[1], msg[2], @map i in [3 .. msg.length()] to ([msg[i]] + (add[i - 2])).sum()];
    return [@msg, "   -----"];
};

public method .listen_channel() {
    arg channel;
    
    if (active_channels.contains(channel))
        return 1;
    return 0;
    
    // $#Edited: 22 Aug 96 19:55 $user_chuck
};

public method .channel_members() {
    arg channel;
    var q, members;
    
    members = [];
    for q in ($user_db.connected()) {
        if (q.listen_channel(channel))
            members += [q.name()];
    }
    .tell(("Listening to channel " + channel) + ":");
    .tell(members.columnize(4));
    return members;
    
    // $#Edited: 24 Jul 96 18:49 $user_chuck
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .channel_alias() {
    arg ch_alias;
    
    return (| channel_dict[ch_alias] |) || "";
    
    // $#Edited: 24 Jul 96 18:50 $user_chuck
};

public method .channel_msg() {
    arg channel, msg;
    
    (caller() == definer()) || (> .perms(sender(), 'system) <);
    if ((channel == 'All) || (active_channels.contains(channel)))
        .tell((("<" + channel) + "> ") + msg);
    
    // $#Edited: 15 Feb 97 17:44 $brad
};

protected method .init_channel_ui() {
    channel_dict = #[];
    active_channels = #[];
    
    // $#Edited: 26 Aug 96 19:38 $user_chuck
    // $#Edited: 27 Aug 96 17:45 $miro
};

protected method .addcom_cmd() {
    arg cmdstr, cmd, args;
    var elements, db, channel, lowerchannel, msg;
    
    (> .perms(caller(), 'command) <);
    elements = args.explode("=");
    if ((elements.length()) != 2) {
        return "Syntax: @addcom <alias>=<channel_name>";
    } else if (channel_dict.contains(elements[1])) {
        return "You are already using that alias for a channel.";
    } else {
        channel = tosym(elements[2]);
        lowerchannel = tosym((elements[2]).lowercase());
        db = (| $channel_db.exact_match(lowerchannel) |) || 0;
        if (type(db) == 'list) {
            if ((type(db[3]) == 'frob) && ((!((db[3]).try(sender()))) && (!($sys.is_system(sender())))))
                return ("Sorry, channel " + (db[1])) + " is join-locked.";
            msg = (("Channel " + (elements[2])) + " added with alias ") + (elements[1]);
        } else if (.can_create_channel()) {
            db = [channel, 0, 0, 0, sender(), [sender()], 0, 0];
            $channel_db.insert(lowerchannel, db);
            msg = (("Channel " + (elements[2])) + " created with alias ") + (elements[1]);
        } else {
            return "Sorry, that channel doesn't exist, and you are not authorized to create new channels.";
        }
    }
    $channel_db.value_changed(lowerchannel, db.replace(2, (db[2]) + 1));
    channel_dict = channel_dict.add(elements[1], db[1]);
    .channel_on(db[1]);
    return msg;
    
    // $#Edited: 15 Feb 97 18:04 $brad
    // $#Edited: 22 Feb 97 02:15 $brad
};

protected method .delcom_cmd() {
    arg cmdstr, cmd, args;
    var db, channel, del_from_db, msg, dict_var;
    
    (> .perms(caller(), 'command) <);
    del_from_db = 1;
    msg = ("Channel alias " + args) + " deleted.";
    dict_var = channel_dict[args];
    channel = (| tosym(((channel_dict[args]).to_string()).lowercase()) |) || 0;
    if (type(channel) == 'symbol) {
        db = (| $channel_db.exact_match(channel) |) || 0;
        if (type(db) == 'list) {
            if ((type(db[4]) == 'frob) && ((!((db[4]).try(sender()))) && (!($sys.is_system(sender())))))
                return "Channel leave locked, you can't leave it!";
        } else {
            del_from_db = 0;
            msg = ("That channel didn't seem to be in the channel database.  Channel alias " + args) + " deleted.";
        }
    } else {
        return "You do not have that channel alias defined.";
    }
    if (del_from_db)
        $channel_db.value_changed(channel, db.replace(2, (db[2]) - 1));
    if (active_channels.contains(dict_var))
        .channel_off(dict_var);
    channel_dict = channel_dict.del(args);
    return msg;
    
    // $#Edited: 16 Feb 97 22:36 $brad
};

public method .channel_dict() {
    return channel_dict;
    
    // $#Edited: 02 Nov 96 18:39 $brad
};

public method .active_channels() {
    return active_channels;
    
    // $#Edited: 02 Nov 96 18:39 $brad
};

public method .can_create_channel() {
    if ((sender().has_ancestor($user)) && (($channel_ui.channel_creation()) || ($sys.is_system(sender()))))
        return 1;
    else
        return 0;
    
    // $#Edited: 06 Nov 96 10:49 $brad
    // $#Edited: 08 Nov 96 21:30 $brad
};

protected method .channel_add_lock_cmd() {
    arg cmdstr, cmd, this, prep, str;
    var channel, db, lock, mode, modestr;
    
    (> .perms(caller(), 'command) <);
    if ((cmd[2]) == "j") {
        mode = 3;
        modestr = "join";
    } else if ((cmd[2]) == "l") {
        mode = 4;
        modestr = "leave";
    } else {
        mode = 8;
        modestr = "use";
    }
    channel = tosym(this.lowercase());
    db = (| $channel_db.exact_match(channel) |) || 0;
    if (type(db) == 'list) {
        if ((!(sender() in (db[6]))) && (!($sys.is_system(sender())))) {
            return "Sorry, you're not on the manager list for that channel.";
        } else if ((str.length()) == 0) {
            $channel_db.value_changed(channel, db.replace(mode, 0));
            return ((("You un-" + modestr) + "lock channel ") + (db[1])) + ".";
        } else {
            catch ~objnf, ~parse {
                lock = $lock_parser.parse(str, sender());
                $channel_db.value_changed(channel, db.replace(mode, lock));
                return ((((("You " + modestr) + "lock channel ") + (db[1])) + " with ") + (lock.lock_name('thing))) + ".";
            } with {
                switch (error()) {
                    case ~objnf:
                        return "Object not found in lock string.";
                    case ~parse:
                        return "Invalid lock string.";
                }
            }
        }
    } else {
        return "Channel not found, nothing locked.";
    }
    
    // $#Edited: 15 Feb 97 17:34 $brad
};

protected method .describe_channel_cmd() {
    arg cmdstr, cmd, channel, prep, desc;
    var db, channel;
    
    (> .perms(caller(), 'command) <);
    channel = (| tosym(channel.lowercase()) |) || 0;
    if (channel == 0)
        return "@desc-ch?annel <channel> as <description>";
    db = (| $channel_db.exact_match(channel) |) || 0;
    if (db == 0)
        return "That channel does not exist.";
    if ((!(sender() in (db[6]))) && (!($sys.is_system())))
        return "You are not a manager for channel " + (db[1]);
    $channel_db.value_changed(channel, db.replace(7, desc));
    return "Description updated.";
    
    // $#Edited: 08 Dec 96 12:47 $brad
};

public method ._broadcast() {
    arg channel, message;
    var q;
    
    if (!(caller() in [$channel_ui, $user, $sys]))
        throw(~perm, "You are not allowed to call $channel_ui._broadcast() directly");
    for q in ($user_db.connected())
        q.channel_msg(channel, message);
    
    // $#Edited: 03 Nov 96 16:16 $brad
    // $#Edited: 03 Nov 96 16:24 $brad
};

public method .channel_add_manager() {
    arg cmdstr, cmd, user, prep, channel;
    var db, channel;
    
    channel = (| tosym(channel.lowercase()) |) || 0;
    if (channel == 0)
        return "@add-channel-manager|@acm <user> to <channel>";
    db = (| $channel_db.exact_match(channel) |) || 0;
    if (db == 0)
        return "That channel does not exist.";
    if ((sender() != (db[5])) && (!($sys.is_system(sender()))))
        return "You are not the channel owner.";
    if (user in (db[6]))
        return ((user.name()) + " is already a manager of channel ") + (db[1]);
    $channel_db.value_changed(channel, db.replace(6, [@db[6], user]));
    return "Manager added.";
    
    // $#Edited: 30 Nov 96 21:22 $miro
    // $#Edited: 08 Dec 96 12:47 $brad
    // $#Edited: 22 Feb 97 02:15 $brad
};

public method .channel_del_manager() {
    arg cmdstr, cmd, user, prep, channel;
    var db, channel;
    
    channel = (| tosym(channel.lowercase()) |) || 0;
    if (channel == 0)
        return "@add-channel-manager|@acm <user> from <channel>";
    db = (| $channel_db.exact_match(channel) |) || 0;
    if (db == 0)
        return "That channel does not exist.";
    if ((sender() != (db[5])) && (!($sys.is_system(sender()))))
        return "You are not the channel owner.";
    if (!(user in (db[6])))
        return ((user.name()) + " is not a manager of channel ") + (db[1]);
    $channel_db.value_changed(channel, db.replace(6, (db[6]).del(user)));
    return "Manager deleted.";
    
    // $#Edited: 08 Dec 96 12:48 $brad
    // $#Edited: 22 Feb 97 02:15 $brad
};

public method .channel_creation() {
    return channel_creation;
    
    // $#Edited: 08 Nov 96 21:24 $brad
};

public method .uninit_channel_ui() {
    var c, channel, db;
    
    for c in (.channel_dict()) {
        if ((| active_channels[c[2]] |) || 0)
            .channel_off(c[2]);
        channel = (| tosym(((c[2]).to_string()).lowercase()) |) || 0;
        if (type(channel) == 'symbol) {
            db = (| $channel_db.exact_match(channel) |) || 0;
            if (type(db) == 'list)
                $channel_db.value_changed(channel, db.replace(2, (db[2]) - 1));
        }
    }
    active_channels = #[];
    channel_dict = #[];
    
    // $#Edited: 16 Feb 97 22:58 $brad
};

public method .channel_purge_cmd() {
    arg cmdstr, cmd, channel;
    var db, channel, connected, u;
    
    channel = (| tosym(channel.lowercase()) |) || 0;
    if (channel == 0)
        return "@add-channel-manager|@acm <user> to <channel>";
    db = (| $channel_db.exact_match(channel) |) || 0;
    if (db == 0)
        return "That channel does not exist.";
    if ((sender() != (db[5])) && (!($sys.is_system(sender()))))
        return "You are not the channel owner.";
    $channel_db.remove(channel);
    connected = $user_db.connected();
    for u in ((((($user_db.database()).to_dict()).to_list()).slice(2)).compress()) {
        if ((u in connected) && (((u.channel_dict()).invert()).contains(db[1])))
            u.tell((("<" + (db[1])) + "> Channel deleted by ") + (sender().name()));
        (| u._del_active_channel(db[1]) |);
        (| u._del_channel_dict(((u.channel_dict()).invert())[db[1]]) |);
        pause();
    }
    return "Channel deleted.";
    
    // $#Edited: 22 Feb 97 03:38 $brad
};

private method ._del_active_channel() {
    arg key;
    
    active_channels = active_channels.del(key);
    
    // $#Edited: 22 Feb 97 02:49 $brad
};

public method ._del_channel_dict() {
    arg key;
    
    channel_dict = channel_dict.del(key);
    
    // $#Edited: 22 Feb 97 03:36 $brad
};


new object $user_info: $user_interfaces;

var $root manager = $user_info;
var $has_commands remote = #[];
var $root flags = ['variables, 'methods, 'code, 'fertile, 'core];
var $root created_on = 843753238;
var $has_commands shortcuts = #[];
var $root inited = 1;
var $has_commands local = #[];
var $user_info info = 0;
var $user_info info_defaults = #[["rl-name", 1], ["rl-email", 0], ["rl-address", 0], ["rl-affiliation", 0], ["rl-position", 0], ["rl-location", 0], ["rl-interests", 0], ["rl-plan", 0], ["rl-projects", 0], ["rl-home-page", 1]];
var $root managed = [$user_info];
var $root owned = [$user_info];
var $root defined_settings = #[["rl-name", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-email", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-address", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-affiliation", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-position", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-location", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-interests", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-plan", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-projects", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]], ["rl-home-page", #[['get, ['get_user_info]], ['set, ['set_user_info]], ['clear, ['clear_user_info]], ['format, ['format_user_info]], ['access, ['public_user_info]]]]];

public method .info_defaults() {
    arg @name;
    
    if (name)
        return (> info_defaults[name[1]] <);
    return info_defaults;
};

protected method .get_user_info() {
    arg name, @args;
    
    if ((| $user_info.info_defaults(name) |) == ~keynf)
        throw(~setting, ("Invalid user info setting '" + name) + "'");
    return (| info[name] |) || [0, ""];
};

public method .set_info_default() {
    arg name, def;
    
    def = def ? 1 : 0;
    info_defaults = dict_add(info_defaults, name, def);
    
    // $#Edited: 26 Sep 96 10:45 $brandon
};

public method .set_user_info() {
    arg name, definer, value, @args;
    var tmp, bool, public, def;
    
    def = $user_info.info_defaults();
    if (!(def.contains(name)))
        throw(~setting, ("Invalid user info setting '" + name) + "'");
    value = (value.explode_quoted()).join(" ");
    if (value && ((value[1]) in ["+", "-"])) {
        bool = (value[1]) == "+";
        tmp = substr(value, 2);
        if ((tmp = match_template(tmp, "p?ublic *"))) {
            value = tmp[2];
            public = bool;
        } else {
            public = def[name];
        }
    } else {
        public = def[name];
    }
    if (!info)
        info = #[];
    info = info.add(name, [public, value]);
};

public method .display_info() {
    arg @no_blanks;
    var out, i, v, sys;
    
    out = [];
    sys = .is_writable_by(sender());
    for i in (($user_info.info_defaults()).keys()) {
        v = (| info[i] |) || [0, ""];
        if ((!(v[2])) && no_blanks)
            continue;
        i = substr(i, 4);
        if ((v[1]) || sys)
            out += [(((i.capitalize()) + ":").pad(13)) + (v[2])];
        else
            out += [(((i.capitalize()) + ":").pad(13)) + "** PRIVATE **"];
    }
    return out;
};

public method .public_user_info() {
    arg name, sender, @caller;
    var i;
    
    i = (| info[name] |) || [0, ""];
    if ((!(i[1])) && (!(.is_writable_by(sender))))
        throw(~private, ("'" + name) + "' is private.");
};

public method .user_info() {
    arg name;
    var i;
    
    // call this method to bypass the settings system.
    i = (| info[name] |) || ((| info["rl-" + name] |) || [0, ""]);
    if ((!(i[1])) && (!(.is_writable_by(sender()))))
        throw(~private, ("'" + name) + "' is private.");
    return i[2];
};

protected method .clear_user_info() {
    arg name;
    
    if (info.contains(name))
        info = info.del(name);
};

protected method .format_user_info() {
    arg value;
    
    return ((value[1]) ? "+public " : "") + toliteral(value[2]);
};


new object $user: $body, $mail_ui, $command_aliases, $bad_commands, $help_ui, $editor_reference, $channel_ui, $user_info;

var $root inited = 1;
var $root created_on = 796268969;
var $root owned = [$user];
var $root manager = $user;
var $root flags = ['methods, 'code, 'core, 'command_cache, 'variables];
var $root managed = [$user];
var $root child_index = 4;
var $location contents = [];
var $located location = $void;
var $located obvious = 1;
var $user password = "*";
var $user connected_at = 0;
var $user last_command_at = 0;
var $user connections = [];
var $user ext_parsers = 0;
var $user title = 0;
var $user action = 0;
var $user activity = 0;
var $user parsers = [$command_parser];
var $user context = #[['last, $body_cave]];
var $user remembered = 0;
var $user evaluator = 0;
var $user connected_seconds = 0;
var $user task_connections = #[];
var $user global_tell = 0;
var $user formatter = $text_format;
var $user content_type = 'plain;
var $command_aliases command_aliases = [];
var $mail_list letters = #[];
var $mail_list letters_index = #[];
var $mail_list senders = 1;
var $mail_list readers = [];
var $mail_list notify = [$user];
var $mail_list last_letter = 0;
var $mail_list mail = [];
var $mail_ui subscribed = #[[$user, [791485891, 0]]];
var $mail_ui current = #[['location, 0], ['list, $user]];
var $described prose = [];
var $has_name name = ['prop, "Generic User Object", "Generic User Object"];
var $user registered = 0;
var $has_commands local = #[["@quit", [["@quit", "", "@quit", 'quit_cmd, #[]]]], ["i?nventory", [["i?nventory", "", "i?nventory", 'inventory_cmd, #[]]]], ["@audit", [["@audit", "*", "@audit <any>", 'audit_cmd, #[[1, ['any, []]]]]]], ["@who", [["@who", "*", "@who <any>", 'who_cmd, #[[1, ['any, []]]]]]], ["@del-command-a?lias|@dca?lias", [["@del-command-a?lias|@dca?lias", "*", "@del-command-a?lias|@dca?lias <any>", 'del_command_alias_cmd, #[[1, ['any, []]]]]]], ["@command-a?liases|@ca?liases", [["@command-a?liases|@ca?liases", "*", "@command-a?liases|@ca?liases <any>", 'command_aliases_cmd, #[[1, ['any, []]]]]]], ["@add-command-a?lias|@aca?lias", [["@add-command-a?lias|@aca?lias", "*", "@add-command-a?lias|@aca?lias <any>", 'add_command_alias_cmd, #[[1, ['any, []]]]]]], ["@com?mands", [["@com?mands", "*", "@com?mands <any>", 'commands_cmd, #[[1, ['any, []]]]]]], ["@news", [["@news", "", "@news", 'news_cmd, #[]]]], ["@forget", [["@forget", "*", "@forget <any>", 'forget_cmd, #[[1, ['any, []]]]]]], ["@whereis|@where-is", [["@whereis|@where-is", "*", "@whereis|@where-is <any>", 'whereis_cmd, #[[1, ['any, []]]]]]], ["@ways", [["@ways", "", "@ways", 'ways_cmd, #[]]]], ["@password|@passwd", [["@password|@passwd", "*", "@password|@passwd <any>", 'password_cmd, #[[1, ['any, []]]]]]], ["@age", [["@age", "*", "@age <object>", 'age_cmd, #[[1, ['object, []]]]]]], ["@context", [["@context", "", "@context", 'context_cmd, #[]]]], ["get|take", [["get|take", "*", "get|take <thing>", 'get_cmd, #[[1, ['descendant, [$thing]]]]], ["get|take", "* from *", "get|take <any> from <descendant of $location>", 'get_from_cmd, #[[1, ['any, []]], [3, ['descendant, [$location]]]]]]], ["drop", [["drop", "*", "drop <thing>", 'drop_cmd, #[[1, ['descendant, [$thing]]]]]]], ["@rename", [["@rename", "*", "@rename <any>", 'rename_cmd, #[[1, ['any, []]]]]]], ["@add-writer|@aw", [["@add-writer|@aw", "*", "@add-writer|@aw <any>", 'add_writer_cmd, #[[1, ['any, []]]]]]], ["@del-writer|@dw", [["@del-writer|@dw", "*", "@del-writer|@dw <any>", 'del_writer_cmd, #[[1, ['any, []]]]]]], ["@chman?age", [["@chman?age", "*", "@chman?age <any>", 'chmanage_cmd, #[[1, ['any, []]]]]]], ["@manage?d", [["@manage?d", "*", "@manage?d <any>", 'managed_cmd, #[[1, ['any, []]]]]]], ["@remember", [["@remember", "* as *", "@remember <object> as <any>", 'remember_cmd, #[[1, ['object, []]], [3, ['any, []]]]]]], ["@remembered", [["@remembered", "*", "@remembered <any>", 'remembered_cmd, #[[1, ['any, []]]]]]], ["give|put", [["give|put", "* to|in *", "give|put <thing> to|in <thing>", 'give_to_cmd, #[[1, ['descendant, [$thing]]], [3, ['descendant, [$thing]]]]]]], ["discard", [["discard", "*", "discard <object>", 'discard_cmd, #[[1, ['object, []]]]]]], ["@writes", [["@writes", "*", "@writes <object>", 'writes_cmd, #[[1, ['object, []]]]]]], ["@trusted?-by", [["@trusted?-by", "*", "@trusted?-by <object>", 'trusted_by_cmd, #[[1, ['object, []]]]]]], ["@add-trust?ee|@at", [["@add-trust?ee|@at", "*", "@add-trust?ee|@at <object:>", 'add_trustee_cmd, #[[1, ['object_opt, []]]]]]], ["@del-trust?ee|@dt", [["@del-trust?ee|@dt", "*", "@del-trust?ee|@dt <object:>", 'del_trustee_cmd, #[[1, ['object_opt, []]]]]]], ["@monitor", [["@monitor", "*", "@monitor <any>", 'monitor_cmd, #[[1, ['any, []]]]]]], ["@ex?amine", [["@ex?amine", "*", "@ex?amine <object:+c?hop>", 'examine_cmd, #[[1, ['object_opt, [["c?hop"]]]]]]]], ["@map", [["@map", "", "@map", 'map_cmd, #[]]]], ["@finger|@ustat", [["@finger|@ustat", "*", "@finger|@ustat <user>", 'finger_cmd, #[[1, ['user, []]]]]]], ["@trusts|@trustee?s", [["@trusts|@trustee?s", "*", "@trusts|@trustee?s <object>", 'trusts_cmd, #[[1, ['object, []]]]]]], ["@writers", [["@writers", "*", "@writers <object>", 'writers_cmd, #[[1, ['object, []]]]]]], ["@manager", [["@manager", "*", "@manager <object>", 'manager_cmd, #[[1, ['object, []]]]]]], ["view", [["view", "*", "view <any>", 'view_detail_cmd, #[[1, ['any, []]]]]]], ["@desc?ribe|@prose", [["@desc?ribe|@prose", "*", "@desc?ribe|@prose <any>", 'description_cmd, #[[1, ['any, []]]]]]], ["l?ook|exam?ine", [["l?ook|exam?ine", "*", "l?ook|exam?ine <any>", 'look_cmd, #[[1, ['any, []]]]]]], ["walk|go", [["walk|go", "*", "walk|go <any>", 'go_cmd, #[[1, ['any, []]]]]]], ["@ant|@add-name-template", [["@ant|@add-name-template", "*", "@ant|@add-name-template <any>", 'add_name_template_cmd, #[[1, ['any, []]]]]]], ["@dnt|@del-name-template", [["@dnt|@del-name-template", "*", "@dnt|@del-name-template <any>", 'del_name_template_cmd, #[[1, ['any, []]]]]]], ["@name-template?s|@template?s", [["@name-template?s|@template?s", "*", "@name-template?s|@template?s <object>", 'name_templates_cmd, #[[1, ['object, []]]]]]], ["@register|@register-name", [["@register|@register-name", "*", "@register|@register-name <any>", 'register_name_cmd, #[[1, ['any, []]]]]]], ["@unregister|@unregister-name", [["@unregister|@unregister-name", "*", "@unregister|@unregister-name <any>", 'unregister_name_cmd, #[[1, ['any, []]]]]]], ["@registered", [["@registered", "", "@registered", 'registered_cmd, #[]]]], ["@page", [["@page", "* with *", "@page <any> with <any>", 'remote_cmd, #[[1, ['any, []]], [3, ['any, []]]]]]], ["@paste?-to", [["@paste?-to", "*", "@paste?-to <any>", 'paste_cmd, #[[1, ['any, []]]]]]], ["@new", [["@new", "*", "@new <any>", 'new_cmd, #[[1, ['any, []]]]]]], ["@status|@uptime", [["@status|@uptime", "*", "@status|@uptime <any>", 'status_cmd, #[[1, ['any, []]]]]]], ["@msg?s|@message?s", [["@msg?s|@message?s", "*", "@msg?s|@message?s <any>", 'msg_cmd, #[[1, ['any, []]]]]]], ["@date|@time", [["@date|@time", "*", "@date|@time <any>", 'date_cmd, #[[1, ['any, []]]]]]], ["@set", [["@set", "*", "@set <any>", 'set_cmd, #[[1, ['any, []]]]]]]];
var $has_commands shortcuts = #[["--*", ['remote_cmd, ["@page ", "", " with ", 1]]], ["-* *", ['remote_cmd, ["@page ", 1, " with ", 2]]]];
var $user monitor = 0;
var $root trusted_by = [$user_db];
var $user failed = 0;
var $channel_ui channel_dict = #[];
var $channel_ui active_channels = #[];
var $user rows = 0;
var $user cols = 0;
var $command_cache local_cache = #[["@quit", ["@quit"]], ["i", ["i?nventory"]], ["in", ["i?nventory"]], ["inv", ["i?nventory"]], ["inve", ["i?nventory"]], ["inven", ["i?nventory"]], ["invent", ["i?nventory"]], ["invento", ["i?nventory"]], ["inventor", ["i?nventory"]], ["inventory", ["i?nventory"]], ["@audit", ["@audit"]], ["@who", ["@who"]], ["@del-command-a", ["@del-command-a?lias|@dca?lias"]], ["@del-command-al", ["@del-command-a?lias|@dca?lias"]], ["@del-command-ali", ["@del-command-a?lias|@dca?lias"]], ["@del-command-alia", ["@del-command-a?lias|@dca?lias"]], ["@del-command-alias", ["@del-command-a?lias|@dca?lias"]], ["@dca", ["@del-command-a?lias|@dca?lias"]], ["@dcal", ["@del-command-a?lias|@dca?lias"]], ["@dcali", ["@del-command-a?lias|@dca?lias"]], ["@dcalia", ["@del-command-a?lias|@dca?lias"]], ["@dcalias", ["@del-command-a?lias|@dca?lias"]], ["@command-a", ["@command-a?liases|@ca?liases"]], ["@command-al", ["@command-a?liases|@ca?liases"]], ["@command-ali", ["@command-a?liases|@ca?liases"]], ["@command-alia", ["@command-a?liases|@ca?liases"]], ["@command-alias", ["@command-a?liases|@ca?liases"]], ["@command-aliase", ["@command-a?liases|@ca?liases"]], ["@command-aliases", ["@command-a?liases|@ca?liases"]], ["@ca", ["@command-a?liases|@ca?liases"]], ["@cal", ["@command-a?liases|@ca?liases"]], ["@cali", ["@command-a?liases|@ca?liases"]], ["@calia", ["@command-a?liases|@ca?liases"]], ["@calias", ["@command-a?liases|@ca?liases"]], ["@caliase", ["@command-a?liases|@ca?liases"]], ["@caliases", ["@command-a?liases|@ca?liases"]], ["@add-command-a", ["@add-command-a?lias|@aca?lias"]], ["@add-command-al", ["@add-command-a?lias|@aca?lias"]], ["@add-command-ali", ["@add-command-a?lias|@aca?lias"]], ["@add-command-alia", ["@add-command-a?lias|@aca?lias"]], ["@add-command-alias", ["@add-command-a?lias|@aca?lias"]], ["@aca", ["@add-command-a?lias|@aca?lias"]], ["@acal", ["@add-command-a?lias|@aca?lias"]], ["@acali", ["@add-command-a?lias|@aca?lias"]], ["@acalia", ["@add-command-a?lias|@aca?lias"]], ["@acalias", ["@add-command-a?lias|@aca?lias"]], ["@com", ["@com?mands"]], ["@comm", ["@com?mands"]], ["@comma", ["@com?mands"]], ["@comman", ["@com?mands"]], ["@command", ["@com?mands"]], ["@commands", ["@com?mands"]], ["@news", ["@news"]], ["@forget", ["@forget"]], ["@whereis", ["@whereis|@where-is"]], ["@where-is", ["@whereis|@where-is"]], ["@ways", ["@ways"]], ["@password", ["@password|@passwd"]], ["@passwd", ["@password|@passwd"]], ["@age", ["@age"]], ["@context", ["@context"]], ["get", ["get|take"]], ["take", ["get|take"]], ["drop", ["drop"]], ["@rename", ["@rename"]], ["@add-writer", ["@add-writer|@aw"]], ["@aw", ["@add-writer|@aw"]], ["@del-writer", ["@del-writer|@dw"]], ["@dw", ["@del-writer|@dw"]], ["@chman", ["@chman?age"]], ["@chmana", ["@chman?age"]], ["@chmanag", ["@chman?age"]], ["@chmanage", ["@chman?age"]], ["@manage", ["@manage?d"]], ["@managed", ["@manage?d"]], ["@remember", ["@remember"]], ["@remembered", ["@remembered"]], ["give", ["give|put"]], ["put", ["give|put"]], ["discard", ["discard"]], ["@writes", ["@writes"]], ["@trusted", ["@trusted?-by"]], ["@trusted-", ["@trusted?-by"]], ["@trusted-b", ["@trusted?-by"]], ["@trusted-by", ["@trusted?-by"]], ["@add-trust", ["@add-trust?ee|@at"]], ["@add-truste", ["@add-trust?ee|@at"]], ["@add-trustee", ["@add-trust?ee|@at"]], ["@at", ["@add-trust?ee|@at"]], ["@del-trust", ["@del-trust?ee|@dt"]], ["@del-truste", ["@del-trust?ee|@dt"]], ["@del-trustee", ["@del-trust?ee|@dt"]], ["@dt", ["@del-trust?ee|@dt"]], ["@monitor", ["@monitor"]], ["@ex", ["@ex?amine"]], ["@exa", ["@ex?amine"]], ["@exam", ["@ex?amine"]], ["@exami", ["@ex?amine"]], ["@examin", ["@ex?amine"]], ["@examine", ["@ex?amine"]], ["@map", ["@map"]], ["@finger", ["@finger|@ustat"]], ["@ustat", ["@finger|@ustat"]], ["@trusts", ["@trusts|@trustee?s"]], ["@trustee", ["@trusts|@trustee?s"]], ["@trustees", ["@trusts|@trustee?s"]], ["@writers", ["@writers"]], ["@manager", ["@manager"]], ["view", ["view"]], ["@desc", ["@desc?ribe|@prose"]], ["@descr", ["@desc?ribe|@prose"]], ["@descri", ["@desc?ribe|@prose"]], ["@describ", ["@desc?ribe|@prose"]], ["@describe", ["@desc?ribe|@prose"]], ["@prose", ["@desc?ribe|@prose"]], ["l", ["l?ook|exam?ine"]], ["lo", ["l?ook|exam?ine"]], ["loo", ["l?ook|exam?ine"]], ["look", ["l?ook|exam?ine"]], ["exam", ["l?ook|exam?ine"]], ["exami", ["l?ook|exam?ine"]], ["examin", ["l?ook|exam?ine"]], ["examine", ["l?ook|exam?ine"]], ["walk", ["walk|go"]], ["go", ["walk|go"]], ["@ant", ["@ant|@add-name-template"]], ["@add-name-template", ["@ant|@add-name-template"]], ["@dnt", ["@dnt|@del-name-template"]], ["@del-name-template", ["@dnt|@del-name-template"]], ["@name-template", ["@name-template?s|@template?s"]], ["@name-templates", ["@name-template?s|@template?s"]], ["@template", ["@name-template?s|@template?s"]], ["@templates", ["@name-template?s|@template?s"]], ["@register", ["@register|@register-name"]], ["@register-name", ["@register|@register-name"]], ["@unregister", ["@unregister|@unregister-name"]], ["@unregister-name", ["@unregister|@unregister-name"]], ["@registered", ["@registered"]], ["@page", ["@page"]], ["@paste", ["@paste?-to"]], ["@paste-", ["@paste?-to"]], ["@paste-t", ["@paste?-to"]], ["@paste-to", ["@paste?-to"]], ["@new", ["@new"]], ["@status", ["@status|@uptime"]], ["@uptime", ["@status|@uptime"]], ["@msg", ["@msg?s|@message?s"]], ["@msgs", ["@msg?s|@message?s"]], ["@message", ["@msg?s|@message?s"]], ["@messages", ["@msg?s|@message?s"]], ["@date", ["@date|@time"]], ["@time", ["@date|@time"]], ["@set", ["@set"]], ["wh", ["wh?isper"]], ["whi", ["wh?isper"]], ["whis", ["wh?isper"]], ["whisp", ["wh?isper"]], ["whispe", ["wh?isper"]], ["whisper", ["wh?isper"]], ["say", ["say"]], ["to", ["to"]], ["emote", ["emote"]], ["quote", ["quote"]], ["spoof", ["spoof"]], ["pose", ["pose"]], ["think", ["think"]], ["wear", ["wear"]], ["remove", ["remove|shed"]], ["shed", ["remove|shed"]], ["@a", ["@a?ction"]], ["@ac", ["@a?ction"]], ["@act", ["@a?ction"]], ["@acti", ["@a?ction"]], ["@actio", ["@a?ction"]], ["@action", ["@a?ction"]], ["@sub", ["@sub?scribed"]], ["@subs", ["@sub?scribed"]], ["@subsc", ["@sub?scribed"]], ["@subscr", ["@sub?scribed"]], ["@subscri", ["@sub?scribed"]], ["@subscrib", ["@sub?scribed"]], ["@subscribe", ["@sub?scribed"]], ["@subscribed", ["@sub?scribed"]], ["@unsub", ["@unsub?scribed"]], ["@unsubs", ["@unsub?scribed"]], ["@unsubsc", ["@unsub?scribed"]], ["@unsubscr", ["@unsub?scribed"]], ["@unsubscri", ["@unsub?scribed"]], ["@unsubscrib", ["@unsub?scribed"]], ["@unsubscribe", ["@unsub?scribed"]], ["@unsubscribed", ["@unsub?scribed"]], ["@mail-list", ["@mail-list?s"]], ["@mail-lists", ["@mail-list?s"]], ["@read", ["@read"]], ["@remove-m", ["@remove-m?ail|@rmm?ail"]], ["@remove-ma", ["@remove-m?ail|@rmm?ail"]], ["@remove-mai", ["@remove-m?ail|@rmm?ail"]], ["@remove-mail", ["@remove-m?ail|@rmm?ail"]], ["@rmm", ["@remove-m?ail|@rmm?ail"]], ["@rmma", ["@remove-m?ail|@rmm?ail"]], ["@rmmai", ["@remove-m?ail|@rmm?ail"]], ["@rmmail", ["@remove-m?ail|@rmm?ail"]], ["@nn", ["@nn|@next-new"]], ["@next-new", ["@nn|@next-new"]], ["@mail", ["@mail"]], ["@send", ["@send"]], ["@create", ["@create"]], ["help", ["help"]], ["page", ["page"]], ["who", ["who"]], ["quit", ["quit"]], ["news", ["news"]], ["@gender", ["@gender"]], ["uptime", ["uptime"]], ["@alias", ["@alias"]], ["@check", ["@check|@paranoid"]], ["@paranoid", ["@check|@paranoid"]], ["@version", ["@version"]], ["@lock", ["@lock"]], ["@unlock", ["@unlock"]], ["@help", ["@help"]], ["@mcp-upload-session", ["@mcp-upload-session"]], ["@cleanup-sessions", ["@cleanup-sessions|@c-s?essions"]], ["@c-s", ["@cleanup-sessions|@c-s?essions"]], ["@c-se", ["@cleanup-sessions|@c-s?essions"]], ["@c-ses", ["@cleanup-sessions|@c-s?essions"]], ["@c-sess", ["@cleanup-sessions|@c-s?essions"]], ["@c-sessi", ["@cleanup-sessions|@c-s?essions"]], ["@c-sessio", ["@cleanup-sessions|@c-s?essions"]], ["@c-session", ["@cleanup-sessions|@c-s?essions"]], ["@c-sessions", ["@cleanup-sessions|@c-s?essions"]], ["@edit", ["@edit"]], ["@desc-c", ["@desc-c?hannel"]], ["@desc-ch", ["@desc-c?hannel"]], ["@desc-cha", ["@desc-c?hannel"]], ["@desc-chan", ["@desc-c?hannel"]], ["@desc-chann", ["@desc-c?hannel"]], ["@desc-channe", ["@desc-c?hannel"]], ["@desc-channel", ["@desc-c?hannel"]], ["@ch", ["@ch?annels"]], ["@cha", ["@ch?annels"]], ["@chan", ["@ch?annels"]], ["@chann", ["@ch?annels"]], ["@channe", ["@ch?annels"]], ["@channel", ["@ch?annels"]], ["@channels", ["@ch?annels"]], ["@join-lock-channel", ["@join-lock-channel|@jlc"]], ["@jlc", ["@join-lock-channel|@jlc"]], ["@leave-lock-channel", ["@leave-lock-channel|@llc"]], ["@llc", ["@leave-lock-channel|@llc"]], ["@use-lock-channel", ["@use-lock-channel|@ulc"]], ["@ulc", ["@use-lock-channel|@ulc"]], ["@add-channel-manager", ["@add-channel-manager|@acm"]], ["@acm", ["@add-channel-manager|@acm"]], ["@del-channel-manager", ["@del-channel-manager|@dcm"]], ["@dcm", ["@del-channel-manager|@dcm"]], ["@add-ch", ["@add-ch?annel|@addcom"]], ["@add-cha", ["@add-ch?annel|@addcom"]], ["@add-chan", ["@add-ch?annel|@addcom"]], ["@add-chann", ["@add-ch?annel|@addcom"]], ["@add-channe", ["@add-ch?annel|@addcom"]], ["@add-channel", ["@add-ch?annel|@addcom"]], ["@addcom", ["@add-ch?annel|@addcom"]], ["@del-ch", ["@del-ch?annel|@delcom"]], ["@del-cha", ["@del-ch?annel|@delcom"]], ["@del-chan", ["@del-ch?annel|@delcom"]], ["@del-chann", ["@del-ch?annel|@delcom"]], ["@del-channe", ["@del-ch?annel|@delcom"]], ["@del-channel", ["@del-ch?annel|@delcom"]], ["@delcom", ["@del-ch?annel|@delcom"]], ["@purge-channel", ["@purge-channel"]], ["@blahblahblah", ["@blahblahblah"]]];
var $command_cache shortcut_cache = [["--*", ['remote_cmd, ["@page ", "", " with ", 1]]], ["-* *", ['remote_cmd, ["@page ", 1, " with ", 2]]], ["|*", ['quote_cmd, ["quote ", 1]]], ["\"*", ['say_cmd, ["say ", 1]]], ["%*", ['think_cmd, ["think ", 1]]], ["!*", ['spoof_cmd, ["spoof ", 1]]], [",*,*", ['esay_cmd, ["esay ", 1, " with ", 2]]], [":*", ['emote_cmd, ["emote ", 1]]], [".*", ['pose_cmd, ["pose ", 1]]], ["''*", ['to_say_cmd, ["to ", "", " say ", 1]]], ["'* *", ['to_say_cmd, ["to ", 1, " say ", 2]]], ["?*", ['help_cmd, ["?", 1]]]];
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 1]]]]];
var $user auto_look = 0;
var $root defined_settings = #[["experienced", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["global-tell", #[['get, ['get_global_tell]], ['set, ['set_global_tell]], ['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["cols", #[['get, ['get_cols]], ['set, ['set_cols]], ['parse, ['is_type, 'integer]]]], ["rows", #[['get, ['get_rows]], ['set, ['set_rows]], ['parse, ['is_type, 'integer]]]], ["prompt", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["auto-look", #[['get, ['get_auto_look]], ['set, ['set_auto_look]], ['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["content-type", #[['set, ['set_content_type]], ['parse, ['parse_content_type]], ['format, ['format_content_type]], ['clear, ['clear_content_type]], ['get, ['get_content_type]]]], ["extended-parsers", #[['parse, ['parse_ext_parsers]], ['format, ['format_ext_parsers]]]], ["exit-style", #[['parse, ['parse_exit_style]]]], ["title", #[['get, ['title]], ['set, ['set_title]]]]];
var $root settings = #[["experienced", 0], ["exit-style", 'none], ["home", $body_cave], ["prompt", 0], ["extended-parsers", []]];
var $thing gender = $gender_neuter;

root method .init_user() {
    password = "*";
    connected_at = 0;
    last_command_at = 0;
    connections = [];
    parsers = [$command_parser, $channel_parser];
    action = "";
    context = #[];
    .set_quota($sys.get_starting('quota));
    $user_db.insert(.name(), this());
    .set_flags([]);
    .move_to($body_cave);
    task_connections = #[];
    formatter = $text_format;
};

root method .uninit_user() {
    var conn;
    
    if (.connected())
        (| (.location()).did_disconnect() |);
    
    // and incase any are lying about
    for conn in (connections)
        (| conn.interface_going_away() |);
    password = 0;
    connections = 0;
    (| $user_db.remove(.name()) |);
    
    // $#Edited: 08 Jan 96 09:25 Lynx ($lynx)
    // $#Edited: 10 Jul 96 01:41 $levi
    // $#Edited: 09 Feb 97 13:47 $brad
};

public method .will_move() {
    arg mover, place;
    
    (> pass(mover, place) <);
    if (place.is($user))
        throw(~user, "Users cannot move into other users!");
    if ((mover.is($user)) && ((mover != this()) && (!($sys.is_system(mover)))))
        throw(~user, "Only administrators can freely move users around.");
};

public method .connected_at() {
    return connected_at;
};

public method .last_command_at() {
    return last_command_at;
};

public method .tell() {
    arg what, @who;
    
    if (!(.connected()))
        return;
    if (monitor != 0) {
        if (listlen(monitor) > 19)
            monitor = [[user(), @stack()[2], what], @delete(monitor, 10)];
        else
            monitor = [[user(), @stack()[2], what], @monitor];
    }
    ._tell(what);
};

public method .set_password() {
    arg str;
    
    (> .perms(sender(), 'manager) <);
    if ((str.length()) < 5)
        throw(~badpasswd, "Passwords must be at least 5 characters long.");
    password = crypt(str);
};

public method .check_password() {
    arg str, @cinfo;
    var match, warn;
    
    (> .perms(caller(), definer(), $login_interface) <);
    
    // no password means always match
    if (!password)
        return 1;
    
    // "*" means never match
    if (password == "*")
        return 0;
    match = match_crypted(password, str);
    
    // keep track of failed attempts, if its from a connection
    if ((!match) && cinfo) {
        if (.connected())
            .tell("<Login> Failed Login Attempt from " + (cinfo[1]));
        else
            failed++;
    }
    
    // update old DES passwords to newer SHA passwords
    if (match && (!match_begin(password, "$2$")))
        password = crypt(str);
    
    // done
    return match;
};

public method .did_move() {
    arg @args;
    
    (| .reset_actions() |);
    (> pass(@args) <);
    if (auto_look != 'no)
        .tell((.location()).get_description(#[['actor, this()], ['exclude, [this()]]]));
};

public method .parsers() {
    .perms(sender(), 'trusts);
    return parsers;
};

protected method .add_parser() {
    arg parser, @over_pr;
    var x, pr;
    
    [(pr ?= parser.priority())] = over_pr;
    
    // does it exist?  If so remove it.
    while (parser in parsers)
        parsers = setremove(parsers, parser);
    for x in [1 .. listlen(parsers)] {
        if (((parsers[x]).priority()) > pr) {
            parsers = insert(parsers, x, parser);
            return;
        }
    }
    parsers += [parser];
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .del_parser() {
    arg parser;
    var keepers;
    
    // removes a parser.  Cannot remove $command_parser (put things in
    // front of it instead).
    if (parser == $command_parser)
        throw(~no, "You must always have the $command_parser.");
    parsers = parsers.setremove(parser);
};

public method .parse_line() {
    arg line;
    var parse, c, r, rval;
    
    (> .perms(caller(), $connection) <);
    set_user();
    
    // if we dont set it, it'll act like normal
    rval = this();
    last_command_at = time();
    catch any {
        task_connections = task_connections.add(task_id(), sender());
        parse = parsers ? (parsers[1]).parse(this(), line, @parsers.subrange(2), $null_parser) : ['failed];
        switch (parse[1]) {
            case 'action:
                r = (| (parse[2]).action(@parse[3]) |);
                if (type(r) in ['list, 'frob, 'string])
                    .ptell(r, #[['type, 'parser], ['action, parse[3]]]);
                else
                    .tell(("Invalid registered action '" + (parse[3])) + "'");
            case 'error:
                .tell(parse[2]);
            case 'match, 'command:
                r = (> (parse[2]).(parse[3])(@parse.subrange(4)) <);
                if (type(r) in ['list, 'frob, 'string])
                    .ptell(r, #[['type, 'parser], ['command, parse[3]]]);
                else
                    rval = r;
            case 'failed:
                for c in (($place_lib.coordinate_shortcuts()).keys()) {
                    if (line.match_template(c)) {
                        .tell(("There is no exit " + line) + " here.");
                        r = 1;
                    }
                }
                if (!r)
                    .tell(("I don't understand " + (line.chop((.linelen()) - 22))) + ".");
            case 'ok:
                // do nothing, probably a null command
            default:
                .tell("Unusual response from the parser: " + toliteral(parse));
        }
    } with {
        if (error() == ~stop) {
            if ((traceback()[1])[2])
                .tell((traceback()[1])[2]);
        } else {
            .tell_traceback(traceback(), line, 0, error());
        }
    }
    catch any
        task_connections = task_connections.del(task_id());
    return rval;
};

public method .login() {
    arg connection;
    var loc, cmd, p, c, last;
    
    if ((sender() != this()) || (definer() != caller()))
        throw(~perm, "Invalid access to private method.");
    task_connections = #[];
    (| .reset_parsers() |);
    for cmd in (.local_commands()) {
        for c in (cmd[2])
            .add_to_local_cache(c[1]);
    }
    (| .reset_help_history() |);
    for p in (parents())
        p.cache_init();
    $user_db.did_connect();
    last = connected_at;
    connected_at = time();
    last_command_at = time();
    loc = .location();
    if (loc == $body_cave) {
        if ((.home()) != $body_cave)
            (| .move_to(.home()) |);
        else
            (| .move_to($world.starting_place()) |);
    } else {
        .tell(.look_cmd("", "", ""));
    }
    $channel_ui._broadcast('Login, (((.namef('titled)) + " has connected (total: ") + ($user_db.total_connected())) + ")");
    (| (.location()).did_connect() |);
    (| .login_notify(connection, last) |);
    (| .edit_sessions_notify() |);
    .hook_events('startup);
    $world.hook_into_event('realm_announce);
    
    // $#Edited: 07 Mar 97 16:29 $miro
};

public method .login_again() {
    arg connection;
    
    if ((sender() != this()) || (definer() != caller()))
        throw(~perm, "Invalid access to private method.");
    last_command_at = time();
    (| .tell(("<Login> " + (((.connections()).length()).n_to_nth())) + " login.") |);
    if (failed) {
        (> .tell(("<Login> ** " + failed) + " failed login attempts **") <);
        (| clear_var('failed) |);
    }
};

public method .logout() {
    arg connection;
    var p;
    
    (| (.location()).did_disconnect() |);
    (| .reset_parsers() |);
    (| .reset_actions() |);
    (| .clear_help_history() |);
    (| $user_db.did_disconnect() |);
    
    // Track how long they are online (random info) -Lynx
    connected_seconds += time() - connected_at;
    
    // set this to -last_command so we know they aren't connected
    // (and using last command will be last_login)
    connected_at = -last_command_at;
    
    // user specific things
    if (!($guest in (.parents()))) {
        (| $housekeeper.did_disconnect() |);
        (| $user_db.last_log_disconnect(this()) |);
    } else {
        (| $user_db.last_log_disconnect($guest) |);
    }
    (| .purge_caches() |);
    for p in (parents())
        p.cache_uninit();
    $channel_ui._broadcast('Login, (((.namef('titled)) + " has disconnected (total: ") + ($user_db.total_connected())) + ")");
    task_connections = #[];
    .set_activity("");
    (| clear_var('monitor) |);
    (| .new_list(this()) |);
    .unhook_events('startup);
    $world.unhook_from_event('realm_announce);
    
    // $#Edited: 07 Mar 97 16:29 $miro
};

public method .connections() {
    return connections;
};

public method .connected() {
    return connections ? 1 : 0;
};

protected method .who_cmd() {
    arg cmdstr, com, @line;
    var who, opts, opt, args, all;
    
    (> .perms(caller(), 'command) <);
    
    // just the basic who listing
    who = [];
    if (!(line[1])) {
        args = [$user_db.connected(), "Connected Users"];
    } else if (((line[1])[1]) == "@") {
        args = ._who_at_place((line[1]).subrange(2));
    } else {
        args = $parse_lib.getopt(line[1], [["a?ll"], ["p?rogrammers"], ["a?dmins"], ["s?hort"]]);
        opts = args[2];
        args = args[1];
        if ((opt = "a?ll" in (opts.slice(1))))
            all = (opts[opt])[3];
        if ((opt = "p?rogrammers" in (opts.slice(1))))
            args = ._who_programmers(args, all);
        else if ((opt = "a?dmins" in (opts.slice(1))))
            args = ._who_admins(args, all);
        else if ((opt = "s?hort" in (opts.slice(1))))
            return ._who_short();
        else
            args = ._who_is(@line);
    }
    if (!args)
        return "Ack, nobody to list?";
    .tell($code_lib.generate_listing(@args));
};

protected method .quit_cmd() {
    arg @args;
    
    (> .perms(caller(), 'command) <);
    return 'disconnect;
};

protected method .inventory_cmd() {
    arg @args;
    var i;
    
    (> .perms(caller(), 'command) <);
    if (.contents()) {
        .tell("Carrying:");
        for i in (.contents())
            .tell(" " + (i.name()));
    } else {
        .tell("You are empty-handed.");
    }
    
    // $# Edited 05 Nov 1995 13:54 Lynx ($lynx)
};

public method .match_env_nice() {
    arg name, @syntax;
    var obj, args, line;
    
    catch any {
        return (> .match_environment(name) <);
    } with {
        if (syntax)
            (> .tell_error(syntax[1], (traceback()[1])[2]) <);
        else
            throw(~stop, (traceback()[1])[2]);
    }
};

public method .linelen() {
    if (cols)
        return cols - 1;
    return 79;
    
    // backwards compatability, older tiny style systems
    // want linelen to actually be cols - 1
};

public method .idle_seconds() {
    return time() - last_command_at;
};

public method .title() {
    arg @args;
    
    return title || "";
};

public method .action() {
    // different from activity, returns a more accurate second to second action
    if (.connected())
        return action || "";
    else
        return "(asleep)";
};

protected method .commands_cmd() {
    arg cmdstr, cmd, args;
    var s, full, o, opt, opts, lcmds, rcmds, len, obj, shorts, m, c, local, remote, short, all;
    
    (> .perms(caller(), 'command) <);
    s = cmd + " [options] <object>";
    opts = [["f?ull"], ["a?ll"], ["l?ocal"], ["r?emote"], ["s?hortcuts"]];
    args = $parse_lib.getopt(args, opts);
    o = args[2];
    local = (remote = (short = 1));
    if ((opt = "f?ull" in (o.slice(1))))
        full = (o[opt])[3];
    if ((opt = "a?ll" in (o.slice(1))))
        all = (o[opt])[3];
    if ((opt = "r?emote" in (o.slice(1))))
        remote = (o[opt])[3];
    if ((opt = "s?hortcuts" in (o.slice(1))))
        short = (o[opt])[3];
    if ((opt = "l?ocal" in (o.slice(1))))
        local = (o[opt])[3];
    args = (args[1]).join();
    if ((!args) && (!all)) {
        (| .tell_error(cmd + " [options] <object>") |);
        return "!  Defaults: -f?ull -a?ll +l?ocal +r?emote +s?hortcuts";
    } else {
        args = args || "me";
        obj = (> .match_env_nice(args) <);
    }
    if (!(obj.has_ancestor($has_commands)))
        return "Sorry, that object has no commands.";
    lcmds = (rcmds = #[]);
    shorts = [];
    if (all) {
        if (local)
            lcmds = obj.all_local_commands();
        if (remote)
            rcmds = obj.all_remote_commands();
        if (short)
            shorts = obj.all_shortcuts();
    } else {
        if (local) {
            c = obj.local_commands();
            if (c)
                lcmds = #[[obj, c]];
        }
        if (remote) {
            c = obj.remote_commands();
            if (c)
                rcmds = #[[obj, c]];
        }
        if (short)
            shorts = (obj.shortcuts()).to_list();
    }
    if (full) {
        m = 'format_commands_long;
        len = ((.linelen()) / 3) * 2;
    } else {
        m = 'format_commands_short;
        len = .linelen();
    }
    o = [];
    if (lcmds)
        o += $command_lib.(m)(lcmds, "Local", len);
    if (rcmds)
        o += $command_lib.(m)(rcmds, "Remote", len);
    if (shorts) {
        o += ["Shortcuts:"];
        if (full)
            m = 'unparse_shortcut_full;
        else
            m = 'unparse_shortcut;
        for c in (shorts)
            o += ["  " + $command_lib.(m)(c)];
    }
    return o || ("No commands defined on " + (obj.namef('ref)));
    
    // $#Edited: 05 Feb 97 13:15 $brad
};

public method .activity() {
    arg @noidle;
    var idle;
    
    // different from action, returns a broader version of your doings
    if (!(.connected()))
        return "asleep";
    if (activity)
        return activity;
    if (noidle)
        return "";
    idle = .idle_seconds();
    if (idle < 180)
        return "";
    if (idle < 300)
        return "daydreaming";
    if (idle < 900)
        return "zoned";
    else
        return "long gone";
    
    // $# Edited 28 Oct 1995 20:36 Lynx ($lynx)
};

public method .home() {
    arg @args;
    var home;
    
    if ((home = pass(@args)) == $lost_and_found)
        return $body_cave;
    return home;
};

protected method .rename_cmd() {
    arg cmdstr, cmd, args;
    var obj, name, templates, article, old, oldart, oldts, new, t;
    
    (> .perms(caller(), 'command) <);
    args = args.explode_quoted();
    if ((listlen(args) > 2) && ((args[2]) == "to"))
        args = delete(args, 2);
    if (listlen(args) > 2)
        args = [args[1], sublist(args, 2).join()];
    if ((!args) || (listlen(args) != 2))
        return ("Syntax: `" + cmd) + " \"<object>\" [to] \"<newname>\" [+(proper|unique|normal)]`";
    obj = (> .match_env_nice(args[1]) <);
    catch any {
        name = (> $code_lib.parse_name(sublist(args, 2).join()) <);
        templates = name[2];
        article = (name[1])[2];
        name = (name[1])[1];
        if ((name[1]) == "$") {
            if (((obj.is($user)) || (obj.is($place))) && (!(.is($admin))))
                return "User objnames can only be changed by administrators.";
            name = substr(name, 2);
            if (!(name.valid_ident()))
                return "Object names can only contain a-z, 0-9 and the underscore.";
            name = tosym(name);
            old = obj.namef('xref);
            (> obj.set_objname(name) <);
            return ((("Renamed " + old) + " to ") + obj) + ".";
        } else {
            if (!(obj.has_ancestor($has_name)))
                return ("Object \"" + obj) + "\" cannot have a regular name.";
            oldart = (obj.name('literal))[1];
            oldts = obj.name_templates();
            old = ((((" [" + article) + "] \"") + (obj.name())) + "\"") + (templates ? (" (" + (oldts.to_english())) + ")" : "");
            old = ("\"" + (obj.name())) + "\"";
            obj = (> obj.set_name(name, article) <);
            new = ("\"" + (obj.name())) + "\"";
            if (templates) {
                for t in (templates)
                    obj = (> obj.add_name_template(t) <);
                new += (" (" + ((obj.name_templates()).to_english())) + ")";
                old += (" (" + (oldts.to_english())) + ")";
            }
            if (oldart != ((obj.name('literal))[1])) {
                old = (("[" + oldart) + "] ") + old;
                new = (("[" + ((obj.name('literal))[1])) + "] ") + new;
            }
            return ((("Renamed " + old) + " to ") + new) + ".";
        }
    } with {
        return (traceback()[1])[2];
    }
    
    // $#Edited: 19 Dec 96 09:52 $brandon
};

protected method .audit_cmd() {
    arg cmdstr, cmd, args;
    var who, obj, col, str, out, total, line, syntax, loc, size, full, s, o;
    
    (> .perms(caller(), 'command) <);
    o = $parse_lib.getopt(args, [["f?ull"]]);
    args = (o[1]).join();
    full = (| "f?ull" in ((o[2]).slice(1)) |);
    if (full)
        full = ((o[2])[full])[3];
    who = (| .match_environment(args) |);
    if (!who) {
        who = (| $user_db.search(args) |);
        if (!who)
            return ("Unable to find \"" + args) + "\".";
    }
    if (!(who.managed()))
        return (who.name()) + " does not managed anything.";
    if (full) {
        col = (.linelen()) / 2;
        out = [(((("Objects managed by " + (who.namef('ref))) + ":").pad(col)) + ("bytes".pad(-10))) + " Location"];
        for obj in (who.managed()) {
            if (!valid(obj)) {
                .tell(("  ** invalid object (" + toliteral(obj)) + ") **");
                continue;
            }
            line = ("  " + (obj.namef('xref))).pad(col);
            s = obj.size();
            size = s.to_english();
            line = (line + (size.pad(-(((size.length()) > 10) ? size.length() : 10)))) + " ";
            loc = (obj.has_ancestor($located)) ? ("[" + ((obj.location()).name())) + "]" : "";
            out += [(line + loc).pad(.linelen())];
            total += s;
        }
    } else {
        if ((who != this()) && (!(.is($admin))))
            return "Only admins can get quota usage information from other users.";
        out = [("Quota information on " + (who.namef('ref))) + ":"];
        for obj in (who.managed()) {
            if (valid(obj))
                total += obj.size();
        }
    }
    if ((who == this()) || (.is($admin))) {
        out += [("Total usage: " + ($integer.to_english(total))) + " bytes"];
        size = who.get_quota();
        line = ("Total quota: " + ($integer.to_english(size))) + " bytes";
        out += [line, ("Remaining:   " + ($integer.to_english(size - total))) + " bytes"];
    }
    if (!(who.quota_valid())) {
        if (who == this())
            out += ["*** You are over quota! ***"];
        else
            out += [("*** " + (who.name())) + " is over quota! ***"];
    }
    return out;
};

protected method .login_notify(): forked {
    arg connection, last;
    var l, sub, out;
    
    sub = .subscribed();
    out = [];
    for l in ((sub.keys()).setremove(this())) {
        if ((l.last_received_on()) > ((sub[l])[1]))
            out += [l.mail_name()];
    }
    if (out)
        .tell("<Mail> New mail on lists: " + (out.to_english()));
    if ((.last_received_on()) > (((.subscribed())[this()])[1]))
        .tell("<Mail> You have new mail (use `@help mail` to learn about mail)");
    if (last)
        .tell("<Login> Last connected at " + ($time.format("%A %B %e %I:%M %p %Y", abs(last))));
    if (failed) {
        (| .tell(("<Login> ** " + failed) + " failed login attempts **") |);
        (| clear_var('failed) |);
    }
};

protected method .news_cmd() {
    arg @args;
    var line, x, mail, m, base, length, out;
    
    (> .perms(caller(), 'command) <);
    mail = $mail_list_news.recent_mail();
    base = mail[1];
    mail = mail[2];
    length = mail.length();
    .new_list($mail_list_news);
    out = [($motd.server_name()) + " news:", ""];
    for x in [1 .. length] {
        m = mail[x];
        out += [((((m.has_read(this())) ? "       " : "NEW => ") + (tostr(x + base).pad(-3))) + ") ") + (m.subject())];
    }
    return out + ["", "Use \"@read #\", where # is the news item number, such as \"@read 1\".  All news items can be found on mail list *news.", "---"];
};

protected method .add_command_alias_cmd() {
    arg cmdstr, cmd, input;
    
    (> .perms(caller(), 'command) <);
    input = input.explode_quoted();
    if (listlen(input) == 3)
        input = input.delete(2);
    if (listlen(input) != 2)
        return ("Syntax: `" + cmd) + " \"<alias>\" [to] \"<actual command>\"`";
    catch any
        (> .add_command_alias(@input) <);
    with
        return (traceback()[1])[2];
    return strfmt("New command alias %d => %d added.", @input);
};

protected method .del_command_alias_cmd() {
    arg cmdstr, com, template;
    
    (> .perms(caller(), 'command) <);
    template = (template.explode_quoted())[1];
    catch ~aliasnf
        (> .del_command_alias(template) <);
    with
        return ("No command alias found matching \"" + template) + "\".";
    return ("Deleted command alias \"" + template) + "\".";
};

protected method .command_aliases_cmd() {
    arg cmdstr, com, what;
    var aliases, a, line, str, num, out, left, right;
    
    (> .perms(caller(), 'command) <);
    if (!what)
        what = this();
    else
        what = (> .match_env_nice(what) <);
    if ((what != this()) && (!(what.is_writable_by(this()))))
        return ("You are not allowed to read the command aliases on " + (what.namef('ref))) + ".";
    out = [("--- Command aliases on " + (what.namef('ref))) + ":"];
    aliases = what.command_aliases();
    if (aliases) {
        for a in (aliases) {
            str = a[1];
            num = 0;
            while ("*" in str) {
                num++;
                left = str.subrange(1, ("*" in str) - 1);
                right = str.subrange(("*" in str) + 1);
                str = ((left + "%") + tostr(num)) + right;
            }
            out += [strfmt("  %30d => %d", str, $command_lib.format_relation(a[2]))];
        }
    } else {
        out += ["  <none>"];
    }
    return out + ["---"];
};

protected method ._tell() {
    arg what, @args;
    var line, conn, type, f;
    
    switch (type(what)) {
        case 'frob:
            what = $parse_lib.filter_ctext(what, #[['formatter, formatter]]);
        case 'string:
            if (content_type == 'html)
                what = (((what.replace("&", "&amp;")).replace("<", "&lt;")).replace(">", "&gt;")) + "<br>";
    
            //           if (content_type == 'wrapped) {
            //              what = strsub(what, "\\", "\\\\");
            //              what = str_to_buf(what.wrap_line(.linelen(), " ") + "\n");
            //          }
        case 'list:
            for line in (what)
                ._tell(line);
            return;
        case 'buffer:
            throw(~nobuf, "You are not allowed to send buffers.");
    }
    conn = (| .task_connection() |);
    if (conn && (!global_tell)) {
        conn.write(what);
    } else {
        for conn in (connections)
            (| conn.write(what) |);
    }
};

private method .registered_cmd() {
    arg @args;
    
    return ("Registered names: " + ((registered || []).to_english("none"))) + ".";
    
    // $#Edited: 25 Nov 96 16:26 $brandon
};

private method .unregister_name_cmd() {
    arg cmd, cmdstr, name;
    
    catch any
        (> .unregister_name(name) <);
    with
        return (traceback()[1])[2];
    return [("Unregistered alternate name \"" + name) + "\".", ("Registered names: " + ((registered || []).to_english("none"))) + "."];
    
    // $#Edited: 25 Nov 96 16:26 $brandon
};

public method .tell_traceback() {
    arg traceback, @args;
    var tt, name, eargs, error, str;
    
    // tt = tell_traceback || ['verbose, 0, "! "];
    [(str ?= ""), (eargs ?= 0), (error ?= 0)] = args;
    tt = ['verbose, -1, "! "];
    traceback = $parse_lib.traceback(traceback, tt[2], tt[3], error);
    if (args)
        name = (| $list.to_english($list.mmap(args, 'namef, 'ref)) |);
    if (!name)
        name = "Object";
    .tell((traceback[1]).replace("%O", name));
    .tell(traceback.subrange(2));
    
    // $#Edited: 10 Dec 96 18:00 $brandon
};

public method .set_tell_traceback() {
    arg which, @lines;
    
    .perms(sender(), 'manager);
    if (!(which in ['verbose, 'brief, 'none]))
        throw(~type, "Which style must either be 'verbose, 'brief, or 'none.");
    if (lines && (type(lines[1]) != 'integer))
        throw(~type, "You must specify the max lines as an integer.");
    if (!lines)
        lines = 0;
    else
        lines = lines[1];
    tell_traceback = [which, lines];
};

public method .namef() {
    arg type;
    var str;
    
    switch (type) {
        case 'doing:
            str = .activity('noidle);
            if (str)
                return (((.name()) + " (") + str) + ")";
            return .name();
        case 'nactivity, 'activity:
            str = .activity();
            if (str)
                return (((.name()) + " (") + str) + ")";
            return .name();
        case 'titled:
            str = .title();
            if (str)
                return (((.name()) + " (") + str) + ")";
            return .name();
        default:
            return (> pass(type) <);
    }
    
    // $# Edited 28 Oct 1995 21:06 Lynx ($lynx)
};

protected method .password_cmd(): nooverride {
    arg cmdstr, com, args;
    var syn, c, curr, new, verify;
    
    (> .perms(caller(), 'command) <);
    syn = com + " [<old password> [<new password>]]";
    args = explode(args);
    c = .task_connection();
    if (!args) {
        c.local_echo_off();
        while ((!curr) && (curr != "@abort"))
            curr = (.prompt("Current Password (@abort to abort): ")).trim();
        c.local_echo_on();
    } else {
        curr = args[1];
    }
    if (!(.check_password(curr)))
        return "Invalid Password";
    if (listlen(args) < 2) {
        c.local_echo_off();
        while (1) {
            while ((!new) && (new != "@abort"))
                new = (.prompt("New Password (@abort to abort): ")).trim();
            while ((!verify) && (verify != "@abort"))
                verify = (.prompt("Retype New Password (@abort to abort): ")).trim();
            if (new == verify)
                break;
            .tell("Passwords do not match!");
            new = (verify = 0);
        }
        c.local_echo_on();
    } else if (listlen(args) == 2) {
        new = args[2];
    } else {
        .tell_error(syn);
    }
    catch any
        .set_password(new);
    with
        .tell_error(syn, (traceback()[1])[2]);
    .tell("Password changed.");
};

root method .set_title() {
    arg name, definer, value;
    
    if (strlen(value) > 30)
        throw(~type, "Titles must be under 30 characters.");
    title = value;
};

public method .match_context() {
    arg str;
    
    return context[str];
};

public method .context() {
    return context;
};

public method .match_environment() {
    arg str;
    var match, gend;
    
    if ((!str) && (match = (| context['last] |))) {
        if (!valid(match))
            context = context.del('last);
        else
            return match;
    }
    if ((match = (| (.remembered())[str] |))) {
        if (!valid(match))
            .del_remembered(str);
        else
            return match;
    }
    match = (> pass(str) <);
    if (match.has_ancestor($thing)) {
        gend = (| match.gender() |);
        if (gend)
            context = context.add(gend.pronoun('po), match);
    }
    context = context.add('last, match);
    return match;
};

public method .non_terminated_tell() {
    arg text;
    var conn;
    
    if (.get_setting("prompt", $user)) {
        conn = (| .task_connection() |);
        if (conn && (!global_tell)) {
            conn.write(text, 'non_terminated);
        } else {
            for conn in (connections)
                (| conn.write(text, 'non_terminated) |);
        }
    } else {
        .tell(text);
    }
};

public method .set_name() {
    arg new_name, @ignore;
    var old_name, part, sname;
    
    (> .perms(sender(), 'manager) <);
    
    // so it doesnt bomb on .set_objname
    if ((> $user_db.valid_name(new_name) <))
        old_name = .name();
    catch any {
        (> pass(new_name, 'prop) <);
        if (new_name in (registered || []))
            .unregister_name(new_name);
        if (!(| $user_db.key_changed(old_name, new_name) |))
            $user_db.insert(new_name, this());
        if (old_name != new_name) {
            sname = new_name.strip();
            (> .set_objname(tosym("user_" + sname)) <);
        }
    } with {
        (| pass(old_name, 'prop) |);
        rethrow(error());
    }
};

public method .find_object_nice() {
    arg str, @args;
    var match;
    
    catch any {
        match = .find_object(str, @args);
    } with {
        .tell("!  " + ((traceback()[1])[2]));
        throw(~stop, "");
    }
    return match;
};

public method .find_object() {
    arg str, @args;
    var trace, match;
    
    // comprehensive matching method.
    // args define what to match.
    if (!args)
        args = ['environment];
    while (args) {
        switch (args[1]) {
            case 'environment:
                match = (| .match_environment(str) |);
            case 'user:
                match = (| $user_db.search(str) |);
            case 'grasp:
                match = (| $object_lib.to_dbref(str) |);
        }
        if (match)
            return match;
        args = args.delete(1);
    }
    throw(~objnf, ("No object found by the reference \"" + str) + "\".");
};

protected method .age_cmd() {
    arg cmdstr, com, obj;
    var time, gender, out;
    
    (> .perms(caller(), 'command) <);
    time = obj.created_on();
    if (obj.is($thing))
        gender = (obj.gender()).pronoun('psc);
    else
        gender = "It";
    out = [((obj.name()) + " was created on ") + ($time.format("%A %B %e %Y", time)), ((gender + " is ") + ($time.elapsed(time() - time, 'long))) + " old."];
    if (obj.is($user))
        out += [((gender + " has logged ") + ($time.elapsed(obj.connected_seconds(), 'long))) + " online."];
    return out;
};

protected method .new_cmd() {
    arg cmdstr, cmd, args;
    var match, name, parent, line, set, nprog, new, t;
    
    (> .perms(caller(), 'command) <);
    if ((match = match_template(args, "* named *"))) {
        name = match[3];
        args = match[1];
    } else {
        name = "";
    }
    catch any
        parent = (> .match_env_nice(args) <);
    with
        return (traceback()[1])[2];
    if (!(parent.is($physical)))
        return ((parent.namef('ref)).capitalize()) + " is not a VR object, you can only create new objects from VR objects (try @spawn).";
    if (name) {
        catch any
            name = (> $code_lib.parse_name(name) <);
        with
            return (traceback()[1])[2];
    }
    
    // spawn from the first parent, add the others
    catch any {
        new = (> parent.new() <);
        if (new.is($located))
            new = (> new.move_to(this()) <);
        if (name) {
            new = (> new.set_name(@name[1]) <);
            for t in (name[2])
                new = (> new.add_name_template(t) <);
        }
        return (("You create \"" + (new.namef('ref))) + "\"") + ((new.name_templates()) ? (" (" + ((new.name_templates()).to_english())) + ")" : "");
    } with {
        .tell((traceback()[1])[2]);
        if (valid(new)) {
            line = new.namef('xref);
            catch ~isfrob
                (> new.destroy() <);
            with
                (> new.discard() <);
            if (valid(new))
                return ("Unable to destroy new object " + line) + ".";
            else
                return ("Sucessfully destroyed new object " + line) + ".";
        }
    }
};

protected method .description_cmd() {
    arg cmdstr, cmd, str;
    var args, obj, desc, long;
    
    (> .perms(caller(), 'command) <);
    if ((args = match_template(str, "* as *"))) {
        obj = (> .match_env_nice(args[1]) <);
        desc = ((args[3]).trim()).unquote();
    } else {
        obj = (> .match_env_nice(str) <);
        if ((desc = .read()) == 'aborted)
            return;
    }
    if (!desc)
        return "You must specify a description.";
    catch any
        obj.set_prose(desc);
    with
        return (traceback()[1])[2];
    return ("Description for " + (obj.namef('ref))) + " set.";
};

protected method .status_cmd() {
    arg cmdstr, com, @args;
    var line, s, x, out, utime, stime, nosys;
    
    (> .perms(caller(), 'command) <);
    s = $sys.status();
    for x in [1 .. s.length()] {
        if ((s[x]) == (-1))
            nosys++;
    }
    out = [("--- " + ($motd.server_name())) + " status report ---"];
    if ($sys.dirty())
        out += ["System is:        dirty, will do normal backup."];
    else
        out += ["System is:        clean, will skip backup."];
    utime = ((strsub($time.to_english(s[1]), " and", ",") + " and ") + ((s[2]) / 1000)) + " milliseconds";
    stime = ((strsub($time.to_english(s[3]), " and", ",") + " and ") + ((s[4]) / 1000)) + " milliseconds";
    out += ["System lag:       " + ($lag_watcher.lag()), "Next dbref:       " + ($sys.next_objnum()), "Driver:           " + ($sys.server_info('driver_version, 'long)), "Core:             " + ($sys.server_info('core_version, 'long)), ("Started:          " + ($time.to_english(time() - ($sys.server_info('startup_time))))) + " ago", ("Backup:     last: " + ($time.to_english(time() - (s[21])))) + " ago", ("            next: " + ($time.to_english((s[22]) - time()))) + " from now", "        interval: " + ($time.to_english(s[20]))];
    if (!nosys)
        out += ["CPU time used:    user: " + utime, "                  system: " + stime, ((("Page:             " + (s[9])) + " reclaims ") + (s[10])) + " faults", ((("Context switches: " + (s[17])) + " voluntary ") + (s[18])) + " involuntary", "Signals:          " + (s[16])];
    return out;
};

public method .del_command_alias() {
    arg alias;
    
    (> .perms(sender()) <);
    (> pass(alias) <);
    if ((!(.command_aliases())) && ($command_aliases_parser in (.parsers()))) {
        .tell("Removing $command_aliases_parser from your list of parsers.");
        .del_parser($command_aliases_parser);
    }
};

public method .add_command_alias() {
    arg alias, actual;
    
    (> .perms(sender()) <);
    (> pass(alias, actual) <);
    if ((.command_aliases()) && (!($command_aliases_parser in (.parsers())))) {
        .tell("Adding $command_aliases_parser to your list of parsers..");
        .add_parser($command_aliases_parser);
    }
};

public method .logout_connection() {
    arg connection;
    
    if ((sender() != this()) || (definer() != caller()))
        throw(~perm, "Invalid access to private method.");
    .tell(("<Login> " + ((((.connections()).length()) + 1).n_to_nth())) + " logout.");
};

protected method .rehash_cmd() {
    arg cmdstr, cmd;
    var c, p;
    
    (> .perms(caller(), 'command) <);
    .tell("Rehashing your command caches...");
    pause();
    
    // purge first 
    (| .purge_caches() |);
    
    // let the parents know we are "going away"
    for p in (parents())
        p.cache_uninit();
    
    // now rehash, hand-pick our own commands
    for cmd in (.local_commands()) {
        for c in (cmd[2])
            .add_to_local_cache(c[1]);
    }
    
    // let the parents know we are back
    for p in (parents())
        p.cache_init();
};

public method .description() {
    arg flags;
    var c, contents, ctext, pronoun, lines, p, br;
    
    pronoun = (.gender()).pronoun('psc);
    if (connections)
        lines = [((pronoun + " is ") + ((.activity()) || "awake")) + "."];
    else
        lines = [(pronoun + " is asleep, and was last connected ") + ($time.format("%d %B %y %H:%M", abs(connected_at)))];
    if ((contents = .contents())) {
        lines += [pronoun + " is holding:"];
        for c in (contents)
            lines += ["  " + (c.name())];
    }
    return (> pass(flags) <) + lines;
};

protected method ._who_at_place() {
    arg str;
    var place, thing, who, args;
    
    // This should actually be done with a global place dictionary and
    // a local place dictionary for each user.
    place = $place.match_descendants(str);
    if (!place) {
        .tell(("I do not know where \"" + str) + "\" is.");
        return 0;
    }
    who = [];
    for thing in (place.contents()) {
        if (thing.has_ancestor($user))
            who += [thing];
    }
    if (!who) {
        .tell(("Nobody is in " + (place.name())) + ".");
        return 0;
    }
    args = [who, "Users in " + (place.name())];
    args = [@args, [['namef, 'titled], ['idle_time]]];
    args = [@args, ["Name", "Times (idle)"], [1, 1]];
    return args;
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

protected method ._who_is() {
    arg @args;
    var person, p, who;
    
    who = [];
    args = ($string.explode_english_list(@args)) || [];
    for p in (args) {
        catch any {
            person = $user_db.search(p);
        } with {
            switch (error()) {
                case ~ambig:
                    .tell(((("The name \"" + p) + "\" can match any of: ") + ($list.to_english($list.mmap((traceback()[1])[3], 'namef)))) + ".");
                default:
                    .tell(("I don't know who \"" + p) + "\" is.");
            }
            continue;
        }
        who += [person];
    }
    if (!who)
        return 0;
    return [who, ((who.length()) == 1) ? "User" : "Users"];
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

protected method ._who_programmers() {
    arg args, all;
    var out, progs, p, x, t;
    
    progs = [];
    if (args && (!all)) {
        for p in (args) {
            x = $user_db.search(p);
            if (!x)
                .tell(("I don't know who \"" + p) + "\" is.");
            else
                progs += [x];
        }
        t = (("Programmer" + (progs.length())) == 1) ? "" : "s";
    } else if (all) {
        t = "All Programmers";
        progs = $programmer.descendants();
        progs = progs.setremove($admin);
    } else {
        t = "Connected Programmers";
        for p in ($user_db.connected()) {
            if (p.has_ancestor($programmer))
                progs += [p];
        }
    }
    if (!progs)
        return 0;
    return [progs, t];
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

protected method ._who_admins() {
    arg args, all;
    var out, admins, a, x, t;
    
    admins = [];
    if (args && (!all)) {
        for a in (args) {
            x = $user_db.search(a);
            if (!x)
                .tell(("I don't know who \"" + a) + "\" is.");
            else
                admins += [x];
        }
        t = (("Admin" + (admins.length())) == 1) ? "" : "s";
    } else if (all) {
        t = "All Admins";
        admins = $sys.admins();
    } else {
        t = "Connected Admins";
        for a in ($user_db.connected()) {
            if (a.has_ancestor($admin))
                admins += [a];
        }
    }
    if (!admins)
        return 0;
    return [admins, t];
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

protected method ._who_short() {
    var user, tmp, who, namestr, total;
    
    who = [];
    total = ($user_db.connected()).length();
    .tell((("Currently connected users (total: " + tostr(total)) + ((total == 1) ? " person" : " people")) + "):");
    for user in ($user_db.connected()) {
        namestr = (((((" " + (user.name())) + " (") + ($time.elapsed(user.connected_at()))) + " ") + ($time.dhms(user.idle_seconds()))) + ")";
        who += [namestr];
        if (tmp < ((namestr.length()) + 2))
            tmp = (namestr.length()) + 2;
    }
    .tell($list.columnize(who, (.linelen()) / (tmp + 1), " ", .linelen()));
    
    // $# Edited 05 Nov 1995 13:56 Lynx ($lynx)
    // $#Edited: 30 Nov 96 21:22 $miro
};

protected method .remember_cmd() {
    arg cmdstr, cmd, what, as, str;
    
    (> .perms(caller(), 'command) <);
    .add_remembered(what, str);
    return ((("Remembering " + (what.namef('xref))) + " as \"") + str) + "\".";
};

protected method .forget_place() {
    arg place;
    
    if (type(place) != 'objnum)
        throw(~type, "Place must be submitted as an object.");
    remembered_places = remembered_places.setremove(place);
};

protected method .remembered_cmd() {
    arg cmdstr, cmd, args;
    var item, out;
    
    (> .perms(caller(), 'command) <);
    if (!(.remembered()))
        return .tell("You do not remember anything.");
    out = [];
    for item in (.remembered())
        out += [(("  " + (item[1])) + " is ") + ((item[2]).namef('xref))];
    return ["Remembered Items:"] + (out.lcolumnize());
};

protected method .forget_cmd() {
    arg cmdstr, cmd, str;
    var what;
    
    (> .perms(caller(), 'command) <);
    what = (| remembered[str] |);
    if (!what)
        return ("You don't remember what \"" + str) + "\" is...";
    .del_remembered(str);
    return ((("Forgetting " + (what.namef('xref))) + " as \"") + str) + "\".";
};

public method .idle_time() {
    arg @args;
    var idle;
    
    [(args ?= 'dhms)] = args;
    idle = .idle_seconds();
    if ((connected_at < 0) || (idle < 30))
        return "";
    switch (args) {
        case 'dhms:
            return $time.dhms(idle, 'long);
        case 'elapsed:
            return $time.elapsed(idle);
        case 'seconds:
            return idle;
    }
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .tell_error() {
    arg syntax, @problem;
    var problem, line, sprefix, prefix, length;
    
    // arg 1 == syntax
    // arg 2 == problem lines
    length = .linelen();
    if (syntax)
        .tell(("=> Syntax: `" + syntax) + "`");
    if (problem) {
        for line in (problem) {
            if (type(line) == 'string)
                line = line.wrap_lines(length, "!  ", 1);
            .tell(line);
        }
    }
    throw(~stop, "");
};

protected method .whereis_cmd() {
    arg cmdstr, cmd, who;
    var user, u;
    
    (> .perms(caller(), 'command) <);
    who = (who && (who.explode_english_list())) || [];
    if (who && ((who[1]) == "is"))
        who = who.delete(1);
    if (!who)
        return "You must specify somebody.";
    for user in [1 .. who.length()] {
        u = (| $user_db.search(who[user]) |);
        if (!u) {
            .tell(("I don't know who \"" + (who[user])) + "\" is.");
            who = who.replace(user, 0);
        } else {
            who = who.replace(user, u);
        }
    }
    for user in (who) {
        if (user)
            .tell(((user.namef('nactivity)) + " is in ") + ((user.location()).name()));
    }
};

public method .connected_time() {
    arg @args;
    
    [(args ?= 'dhms)] = args;
    if (connected_at < 0)
        return "Last on: " + ctime(abs(connected_at));
    switch (args) {
        case 'dhms:
            return $time.dhms(time() - connected_at, 'long);
        case 'elapsed:
            return $time.elapsed(time() - connected_at);
        case 'seconds:
            return time() - connected_at;
    }
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

protected method .name_templates_cmd() {
    arg cmdstr, com, obj;
    
    (> .perms(caller(), 'command) <);
    if (!(obj.has_ancestor($has_name)))
        return (obj.name()) + " is not descended from $has_name!";
    return (("Name templates for " + (obj.namef('ref))) + ": ") + ((obj.name_templates()).to_english("none"));
};

public method .connection_going_away() {
    arg addr, port;
    var con, line;
    
    catch any {
        (> .perms(caller(), $connection) <);
        for con in (connections) {
            if (!valid(con))
                connections = connections.setremove(con);
        }
        con = sender() in connections;
        connections = connections.setremove(sender());
        if (!connections)
            .logout(sender());
        else
            .logout_connection(sender());
        line = ((((((("DISCONNECT " + tostr(con)) + " (") + ((.parents())[1])) + "): ") + this()) + " <") + addr) + ">";
        (| $sys.log(line) |);
    } with {
        $sys.log($parse_lib.traceback(traceback()));
    }
};

public method .read() {
    arg @args;
    var text, output, head, tail;
    
    if (!(.connections()))
        return 'not_connected;
    if ((.task_connection()).is_reading_block())
        return 'engaged;
    if (args.length())
        head = args[1];
    else
        head = "Receiving input.  Enter \".\" to finish or \"@abort\" to abort.";
    if ((args.length()) > 1)
        tail = args[2];
    else
        tail = "** Aborted **; Text thrown away.";
    if (head)
        .tell(head);
    output = (.task_connection()).start_reading_block('multiple);
    if ((output == 'aborted) && tail)
        .tell(tail);
    return output;
};

public method .read_line() {
    arg @args;
    var line, abort_msg, head, con;
    
    if (!(.connections()))
        return 'not_connected;
    con = .task_connection();
    if (con.is_reading_block())
        return 'engaged;
    [(head ?= ""), (abort_msg ?= "** Aborted **")] = args;
    if (head)
        .tell(head);
    line = con.start_reading_block('one);
    if ((line == 'aborted) && abort_msg)
        .tell(abort_msg);
    return line[1];
};

public method .prompt() {
    arg prompt, @abort_msg;
    
    .non_terminated_tell(prompt);
    return (> .read_line("", @abort_msg) <);
};

protected method .ways_cmd() {
    arg cmdstr, cmd;
    var exits, e, line, out;
    
    (> .perms(caller(), 'command) <);
    exits = (.location()).visible_exits();
    if (!exits)
        return "There are no visible exits from this room.";
    
    // come up with some settings to configure how to display exits
    // for now they can deal with the following
    out = [("Visible exits from " + ((.location()).name())) + ":"];
    for e in (exits)
        out += [((("  " + (e.name())) + ((e.name_templates()) ? (" (" + ((e.name_templates()).to_english())) + ")" : "")) + " to ") + ((e.dest()).name())];
    return out + ["---"];
};

public method .set_objname(): nooverride {
    arg new_objname;
    
    if ((caller() != $user) && (!(sender() in ($sys.system()))))
        throw(~perm, "User objnames can only be changed by $user.");
    (> pass(new_objname) <);
};

protected method .context_cmd() {
    arg @args;
    var out;
    
    (> .perms(caller(), 'command) <);
    out = ["Last thing: " + ((| (context['last]).name() |) || "(nothing)")];
    out += ["Last it:    " + ((| (context["it"]).name() |) || "(nothing)")];
    out += ["Last her:   " + ((| (context["her"]).name() |) || "(nothing)")];
    out += ["Last him:   " + ((| (context["him"]).name() |) || "(nothing)")];
    return out;
    
    // $#Edited: 30 Nov 96 20:00 $miro
};

private method .register_name_cmd() {
    arg cmd, cmdstr, name;
    
    catch any
        (> .register_name(name) <);
    with
        return (traceback()[1])[2];
    return [("Registered alternate name \"" + name) + "\".", ("Registered names: " + (registered.to_english("none"))) + "."];
    
    // $#Edited: 25 Nov 96 16:26 $brandon
};

private method .unregister_name() {
    arg old;
    
    registered = setremove(registered || [], old);
    if (!registered)
        (| clear_var('registered) |);
    (| $user_db.remove(old) |);
    
    // $#Edited: 25 Nov 96 16:19 $brandon
};

private method .register_name() {
    arg new;
    
    if (!(new in (registered || []))) {
        (> $user_db.valid_name(new) <);
        (> $user_db.insert(new, this()) <);
        if (registered)
            registered += [new];
        else
            registered = [new];
    }
};

protected method .look_cmd() {
    arg cmdstr, cmd, args;
    var m, obj, desc, flags, loc, prep, line, exam;
    
    (> .perms(caller(), 'command) <);
    
    // flags that are always the same
    flags = #[['actor, this()], ['examine, match_begin(cmd, "e")], ['exclude, [this()]]];
    
    // Because we do some non-environment things, we parse look ourselves.
    // some times I critically catch things and sometimes I let the catch
    // statement catch them, this is because of how I want the errors to look.
    catch any {
        if ((m = match_template(args, "in|on *"))) {
            obj = (> .match_environment(m[2]) <);
            flags = (flags.add('type, m[1])).add_elem('exclude, obj);
            return obj.get_description(flags);
        } else {
            if ((m = match_template(args, "at *")))
                args = m[2];
            if (!args) {
                obj = .location();
                return obj.get_description(flags.add_elem('exclude, obj));
            } else if ((m = match_template(args, "* in|on *"))) {
                prep = m[2];
                catch any
                    loc = (> .match_environment(m[3]) <);
                with
                    return (traceback()[1])[2];
                obj = (| loc.match_environment(m[1]) |);
                if (!obj) {
                    return (> loc.get_detail(m[1]) <);
                } else if ((m = match_template(args, "det?ail *"))) {
                    desc = (| loc.get_detail(m[2]) |);
                    if (!desc)
                        return strfmt("No detail %d %l %l.", m[2], prep, loc.name());
                    return desc;
                } else {
                    return obj.get_description(flags.add_elem('exclude, obj));
                }
            } else if ((m = match_template(args, "det?ail *"))) {
                return (> (.location()).get_detail(m[2]) <);
            } else {
                obj = (> .match_environment(args) <);
                return obj.get_description(flags.add_elem('exclude, obj));
            }
        }
    } with {
        line = (traceback()[1])[2];
        if (error() in [~ambig, ~nodetail])
            return line;
        desc = (| (.location()).get_detail(args) |);
        if (!desc)
            return line;
        return desc;
    }
};

protected method .walk_path() {
    arg @path;
    var p, exit, exits, e, l, oal;
    
    if (!path)
        throw(~badpath, "Walk nowhere?");
    oal = .get_auto_look();
    .set_auto_look($user, "", 0);
    catch any {
        for p in (path) {
            // did we actually move?
            l = .location();
            exits = l.exits();
            if (!(exit = find e in (exits) where (e.match_name(p))))
                .tell((("No exit \"" + p) + "\" from ") + (l.name()));
            else
                (exits[exit]).invoke();
            pause();
        }
        .set_auto_look(0, 0, oal);
    } with {
        .set_auto_look(0, 0, oal);
        rethrow(error());
    }
};

public method .set_content_type() {
    arg name, definer, value;
    var sets;
    
    switch (value) {
        case "text/html":
            content_type = 'html;
            formatter = $html_format;
        case "text/wrapped":
            content_type = 'wrapped;
            formatter = $wrapped_text_format;
        case "text/plain":
            content_type = 'plain;
            formatter = $text_format;
    }
};

public method .evaluator() {
    return evaluator;
};

protected method .get_cmd() {
    arg cmdstr, cmd, what;
    var ol, l, isuser;
    
    (> .perms(caller(), 'command) <);
    ol = what.location();
    if (ol == this()) {
        return ("You already have " + (what.name())) + ".";
    } else if (what == this()) {
        return "Ewww, its all twisty.";
    } else {
        l = .location();
        if (l != ol) {
            isuser = ol.is($user);
            if ((| ol.location() |) != l)
                return ("You are not in " + (what.location())) + ".";
        }
        catch any {
            (> what.move_to(this()) <);
        } with {
            if (error() == ~locked) {
                if (isuser)
                    ol.tell((((.name()) + " tried to take ") + (what.name())) + " from you.");
                return (((what.name()) + " is locked to ") + ((what.lock()).lock_name('thing))) + ".";
            } else {
                return (traceback()[1])[2];
            }
        }
        if (isuser)
            ol.tell((((.name()) + " takes ") + (what.name())) + " from you.");
        l.announce((((.name()) + " takes ") + (what.name())) + ".", this(), ol);
        if (l != ol) {
            if (!isuser)
                l.announce((((.name()) + " takes ") + (what.name())) + ".");
            return ((("You take " + (what.name())) + " from ") + (ol.name())) + ".";
        }
        return ("You take " + (what.name())) + ".";
    }
};

protected method .drop_cmd() {
    arg cmdstr, cmd, what;
    
    (> .perms(caller(), 'command) <);
    if (!(what in (.contents()))) {
        return ("You don't have " + (what.name())) + ".";
    } else {
        catch any {
            (> what.move_to(.location()) <);
            .tell(("You drop " + (what.name())) + ".");
            (| (.location()).announce((((.name()) + " drops ") + (what.name())) + ".", this(), what) |);
        } with {
            return (traceback()[1])[2];
        }
    }
    
    // $# Edited 05 Nov 1995 14:10 Lynx ($lynx)
};

protected method .set_cols() {
    arg name, definer, value, @args;
    
    if ((value == 80) || (!value))
        (| clear_var('cols) |);
    else
        cols = value;
};

protected method .take_from_cmd() {
    arg cmdstr, cmd, what, p, loc;
    var c, obj, l, wl;
    
    (> .perms(caller(), 'command) <);
    if (loc == this())
        return ("You already have " + (what.name())) + ".";
    for c in (loc.contents()) {
        if (c.match_name(what))
            obj = c;
    }
    if (!obj)
        return ((.name()) + " does not have ") + what;
    if ((obj == this()) || (obj == loc))
        return "Ewww, its all twisty.";
    catch any {
        l = .location();
        wl = loc.location();
        (> obj.move_to(this()) <);
        if (l != wl)
            wl.announce(((((((((.name()) + " ") + cmd) + "s ") + (obj.name())) + " ") + p) + " ") + (loc.name()), this());
        l.announce(((((((((.name()) + " ") + cmd) + "s ") + (obj.name())) + " ") + p) + " ") + (loc.name()), this());
        return ((((((("You " + cmd) + " ") + (obj.name())) + " ") + loc) + " ") + (loc.name())) + ".";
    } with {
        switch (error()) {
            case ~locked:
                if (loc.is($user))
                    loc.tell((((.name()) + " tried to take ") + (obj.name())) + " from you.");
                return (((obj.name()) + " is locked to ") + ((obj.lock()).lock_name('thing))) + ".";
            default:
                return (traceback()[1])[2];
        }
    }
    
    // $# Edited 05 Nov 1995 13:58 Lynx ($lynx)
};

public method .set_activity() {
    arg str;
    
    (> .perms(sender()) <);
    activity = str;
};

public method .is_tellable_by() {
    arg caller, sender;
    
    return (sender == this()) || (caller in [$place, $user, $programmer, $admin, $mail_ui, $help_ui]);
};

protected method .go_cmd() {
    arg cmdstr, cmd, path;
    var m;
    
    (> .perms(caller(), 'command) <);
    if ((m = match_template(path, "to *")))
        return cmd + " to support is pending completion.";
    path = path.explode_quoted();
    catch any
        .walk_path(@path);
    with
        .tell((traceback()[1])[2]);
    if (auto_look != 'no)
        .tell((.location()).get_description(#[['actor, this()], ['exclude, [this()]]]));
    return "You arrive";
};

public method .ptell() {
    arg what, flags;
    
    if (!(.is_tellable_by(caller(), sender())))
        throw(~perm, "Only allowed objects may call protected tell.");
    
    // switch (flags['type]) {
    ._tell(what);
};

public method .connection_starting() {
    arg addr, port;
    var line, c;
    
    (> .perms(caller(), $connection) <);
    
    // shutoff our connection's timeout
    sender().set_timeout(0);
    
    // cleanup our connections list
    for c in (connections) {
        if (!valid(c))
            connections = connections.setremove(c);
    }
    connections = [sender()].union(connections);
    if ((connections.length()) == 1)
        (| .login(sender()) |);
    else
        (| .login_again(sender()) |);
    line = ("CONNECT " + tostr(sender() in connections)) + " (";
    line = (line + ((.parents())[1])) + "): ";
    line = (((line + this()) + " <") + (sender().address())) + "> ";
    (| $sys.log(line) |);
};

protected method .reset_parsers() {
    var p, list;
    
    parsers = [];
    list = (.get_setting("extended-parsers", $user)) || [];
    for p in ((.get_base_parsers()) + list)
        .add_parser(p);
};

public method .connected_seconds() {
    return connected_seconds;
};

protected method .add_trustee_cmd() {
    arg cmdstr, cmd, args;
    var syn, obj, trustee;
    
    (> .perms(caller(), 'command) <);
    trustee = args[1];
    args = args[2];
    if (args && ((args[1]) == "to"))
        args = delete(args, 1);
    obj = (> .match_env_nice(args.join()) <);
    catch any {
        (> obj.add_trusted(trustee) <);
        return [(("Added trustee " + (trustee.namef('ref))) + " to ") + (obj.namef('ref)), (((obj.namef('ref)) + " now trusts: ") + ((((obj.trusted('literal)).compress()).mmap('namef, 'ref)).to_english("nobody"))) + "."];
    } with {
        return (traceback()[1])[2];
    }
    
    // $#Edited: 18 Jul 96 14:56 $levi
};

protected method .del_trustee_cmd() {
    arg cmdstr, cmd, args;
    var syn, obj, trustee;
    
    (> .perms(caller(), 'command) <);
    trustee = args[1];
    args = args[2];
    if (args && ((args[1]) == "from"))
        args = delete(args, 1);
    obj = (> .match_env_nice(args.join()) <);
    catch any {
        (> obj.del_trusted(trustee) <);
        return [(("Removed trustee " + (trustee.namef('ref))) + " from ") + (obj.namef('ref)), (((obj.namef('ref)) + " now trusts: ") + ((((obj.trusted('literal)).compress()).mmap('namef, 'ref)).to_english("nobody"))) + "."];
    } with {
        .tell((traceback()[1])[2]);
    }
};

protected method .add_writer_cmd() {
    arg cmdstr, cmd, args;
    var syn, obj, writer;
    
    (> .perms(caller(), 'command) <);
    args = (args.replace(" to ", " ")).explode();
    if ((!args) || ((args.length()) != 2))
        .tell_error(cmd + " <writer> [to] <object>");
    writer = .match_env_nice(args[1]);
    obj = .match_env_nice(args[2]);
    catch any {
        obj.add_writer(writer);
        return [(("Sucessfully added writer " + (writer.namef('xref))) + " to ") + (obj.namef('xref)), ("New writers list: " + ((((obj.writers('literal)).compress()).mmap('namef, 'xref)).to_english())) + "."];
    } with {
        .tell((traceback()[1])[2]);
    }
};

protected method .del_writer_cmd() {
    arg cmdstr, cmd, args;
    var syn, obj, writer;
    
    (> .perms(caller(), 'command) <);
    args = (args.replace(" from ", " ")).explode();
    if ((!args) || ((args.length()) != 2))
        .tell_error(cmd + " <writer> [from] <object>");
    writer = .match_env_nice(args[1]);
    obj = .match_env_nice(args[2]);
    catch any {
        obj.del_writer(writer);
        return [(("Sucessfully removed writer " + (writer.namef('xref))) + " from ") + (obj.namef('xref)), ("New writers list: " + ((((obj.writers('literal)).compress()).mmap('namef, 'xref)).to_english())) + "."];
    } with {
        .tell((traceback()[1])[2]);
    }
};

protected method .writes_cmd() {
    arg cmdstr, cmd, what;
    
    (> .perms(caller(), 'command) <);
    return [(what.namef('ref)) + " is a writer on:"] + (._list_objects(what.writes(), 'writers));
};

protected method .managed_cmd() {
    arg cmdstr, cmd, args;
    var manager, managed, obj, out, len;
    
    (> .perms(caller(), 'command) <);
    manager = (| .match_environment(args) |);
    if (!manager) {
        manager = (| $user_db.search(args) |);
        if (!manager)
            return ("Unable to find \"" + args) + "\".";
    }
    managed = manager.managed();
    if (!managed)
        return (manager.namef('ref)) + " does not manage any objects.";
    out = [(manager.namef('ref)) + " manages:"];
    len = (.linelen()) / 2;
    for obj in (managed)
        out += [(("  " + ((obj.namef('xref)).pad(len))) + " ") + ($object_lib.see_perms(obj, ["", ""]))];
    return out;
};

protected method .add_name_template_cmd() {
    arg cmdstr, cmd, args;
    var obj, template;
    
    (> .perms(caller(), 'command) <);
    args = args.explode_quoted();
    if ((listlen(args) > 2) && ((args[2]) == "to"))
        args = delete(args, 2);
    if (listlen(args) > 2)
        args = [args[1], sublist(args, 2).join()];
    if ((!args) || (listlen(args) != 2))
        return ("Syntax: `" + cmd) + " \"<template>\" [to] \"<object>\"`";
    obj = (> .match_env_nice(args[2]) <);
    template = args[1];
    if (!(obj.has_ancestor($has_name)))
        return obj + " cannot have regular names.";
    catch any
        obj = (> obj.add_name_template(template) <);
    with
        return (traceback()[1])[2];
    return ((((("Added name template \"" + template) + "\" to ") + (obj.namef('ref))) + ", templates: ") + ((obj.name_templates()).to_english())) + ".";
};

protected method .add_remembered() {
    arg what, name;
    
    remembered = (remembered || #[]).add(name, what);
};

protected method .del_remembered() {
    arg name;
    
    remembered = (remembered || #[]).del(name);
    if (!remembered)
        clear_var('remembered);
};

public method .remembered() {
    return remembered || #[];
};

protected method .get_from_cmd() {
    arg cmdstr, cmd, what, p, loc;
    var c, obj, l, wl, str;
    
    (> .perms(caller(), 'command) <);
    if (loc == this())
        return ("You already have " + (what.name())) + ".";
    for c in (loc.contents()) {
        if (c.match_name(what))
            obj = c;
    }
    if (!obj) {
        if (loc.is($place))
            return ("No \"" + what) + "\" in your environment.";
        else
            return ((loc.name()) + " does not have ") + what;
    }
    if ((obj == this()) || (obj == loc))
        return "Ewww, its all twisty.";
    if (loc.is($place))
        return .get_cmd(cmdstr, cmd, obj);
    catch any {
        l = .location();
        (> obj.move_to(this()) <);
        str = (((" " + (obj.name())) + " ") + p) + " ";
        wl = loc.location();
        .tell(((("You " + cmd) + str) + (loc.name())) + ".");
        (| loc.tell((((((.name()) + " ") + cmd) + "s") + str) + "you.") |);
        cmd += "s";
        str = (str + (loc.name())) + " ";
        if (l != wl)
            wl.announce((((.name()) + " ") + cmd) + str, this(), loc);
        l.announce((((.name()) + " ") + cmd) + str, this(), loc);
        return;
    } with {
        switch (error()) {
            case ~locked:
                if (loc.is($user))
                    loc.tell((((((.name()) + " tried to take ") + (obj.name())) + " ") + p) + " you.");
                return (((obj.name()) + " is locked to ") + ((obj.lock()).lock_name('thing))) + ".";
            default:
                return (traceback()[1])[2];
        }
    }
    
    // $# Edited 05 Nov 1995 13:58 Lynx ($lynx)
};

protected method .give_to_cmd() {
    arg cmdstr, cmd, what, p, loc;
    var c, obj, l, wl, str;
    
    (> .perms(caller(), 'command) <);
    if (!(what in (.contents())))
        return ("You don't have " + (what.name())) + ".";
    if (what == this())
        return "Give yourself away?  Interesting...";
    if (what == loc)
        return ((("Uhh, you cannot give " + ((what.gender()).pronoun('po))) + " to ") + ((what.gender()).pronoun('pr))) + ".";
    if (loc.is($place))
        return .drop_cmd(cmdstr, cmd, what);
    catch any {
        l = .location();
        wl = loc.location();
        (> what.move_to(loc) <);
        str = (((" " + (what.name())) + " ") + p) + " ";
        .tell(((("You " + cmd) + str) + (loc.name())) + ".");
        (| loc.tell((((((.name()) + " ") + cmd) + "s") + str) + "you.") |);
        cmd += "s";
        str = (str + (loc.name())) + " ";
        if (l != wl)
            wl.announce((((.name()) + " ") + cmd) + str, this(), loc);
        l.announce((((.name()) + " ") + cmd) + str, this(), loc);
    } with {
        .tell_traceback(traceback());
        return (traceback()[1])[2];
    }
};

public method .task_connections() {
    return task_connections;
};

public method .task_connection() {
    return task_connections[task_id()];
};

protected method .set_global_tell() {
    arg @args;
    
    if ((args[3]) == 0)
        clear_var('global_tell);
    else
        global_tell = 1;
    
    // $# Edited 20 Oct 1995 13:52 Lynx ($lynx)
};

public method .get_global_tell() {
    arg @args;
    
    return global_tell;
};

public method .match_name() {
    arg str;
    var m, n;
    
    if ((m = pass(str)))
        return m;
    for n in (registered || []) {
        if ((m = match_begin(n, str)))
            return m;
    }
    return 0;
};

protected method .discard_cmd() {
    arg cmdstr, cmd, target;
    var msg, s, name;
    
    (> .perms(caller(), 'command) <);
    if ((cmdstr.trim()) == "discard") {
        s = .prompt(("Are you sure you want to discard " + (target.name())) + "? ");
        if (!(s in ["yes", "y"]))
            return ("Ok, not discarding " + (target.name())) + ".";
    }
    if (((target.location()) != this()) && (!(target.is($exit))))
        return ("You are not holding " + (target.name())) + ".";
    name = target.name();
    if (type(target) == 'frob) {
        catch ~perm
            target.discard();
        with
            return (traceback()[1])[2];
    } else if ((target.manager()) == this()) {
        target.destroy();
    } else {
        target.move_to($trash);
        msg = $mail_message.new_mail();
        msg.set_subject("Discarded Object");
        msg.set_text([(((((((target.name()) + " has been discarded by ") + (.name())) + ". It currently exists in ") + ($trash.namef('ref))) + ", and will be destroyed in 15 days.  You may retrieve it with the command `@move ") + target) + " to me`."]);
        (| msg.send(target.manager()) |);
    }
    return ("Discarding " + name) + ".";
};

public method ._list_objects() {
    arg objs, multi, @args;
    var line, obj, c2, name, fmt, out, c1;
    
    if (!objs) {
        out = ["** None **"];
    } else {
        c2 = ((| sender().linelen() |) || 79) / 10;
        c1 = c2 * 4;
        fmt = "%3L%*L %*L %*L";
        out = [strfmt(fmt, "#", c1, "Name", c2, "Flags", c2, "Size") + "Manager"];
        for obj in (objs) {
            line = strfmt(fmt, obj.(multi)(@args).length(), c1, obj.namef('xref), c2, $object_lib.see_perms(obj, ["", ""]), c2, obj.size());
            name = (obj.manager()).namef('xref);
            if ((name.length()) > c1)
                name = name.pad(c1);
            out += [line + name];
        }
    }
    return out;
};

protected method .trusted_by_cmd() {
    arg cmdstr, cmd, what;
    
    (> .perms(caller(), 'command) <);
    return [(what.namef('ref)) + " is trusted by:"] + (._list_objects(what.trusted_by(), 'trusted));
};

protected method .personal_info() {
    return info || #[];
    
    // $#Edited: 01 May 96 17:31 $lynx
};

public method .personal_fields() {
    return #[["real-name", 1], ["email", 1], ["address", 1], ["affiliation", 1], ["position", 1], ["location", 1], ["interests", 1], ["plan", 1], ["projects", 1], ["home-page", 0]];
    
    // $#Edited: 01 May 96 17:33 $lynx
};

protected method .monitor_cmd() {
    arg cmdstr, cmd, @args;
    var e, out, line, len;
    
    (> .perms(caller(), 'command) <);
    if (!(args[1])) {
        if (monitor == 0)
            return "You are not monitoring what you hear.";
        out = [];
        len = .linelen();
        for e in (monitor || []) {
            line = strfmt("%20S %30S ", (e[1]).namef('xref), ((((e[2]) + ".") + (e[4])) + "() line ") + (e[5])) + (e[6]);
            if (strlen(line) > len)
                line = line.chop(len);
            out += [line];
        }
        return out + ["---"];
    }
    if ("on" in args) {
        monitor = [];
        return "You are now monitoring what you hear.";
    } else {
        (| clear_var('monitor) |);
        return "You are no longer monitoring what you hear.";
    }
    
    // $#Edited: 06 May 96 22:09 $lynx
};

protected method .monitor() {
    return monitor;
    
    // $#Edited: 21 Mar 97 20:34 $brandon
};

protected method .examine_cmd() {
    arg cmdstr, cmd, args;
    var obj, opts, i, chop, out, m, cmds, c, desc;
    
    (> .perms(caller(), $user) <);
    obj = args[1];
    opts = args[3];
    chop = .linelen();
    c = obj.created_on();
    if ((i = "ch?op" in (opts.slice(1))) && (!((opts[i])[3])))
        chop = 0;
    out = ["Object (@rename):    " + (obj.namef('ref)), "Templates (@ant):    " + ((| (obj.name_templates()).to_english("none") |) || "none"), "Created:             " + (c ? ctime(c) : "(Before Time)"), (("Quota:               " + ((obj.quota()).to_english())) + " bytes") + ((obj.quota_exempt()) ? " ** exempt **" : ""), ("Size:                " + ((obj.size()).to_english())) + " bytes (on disk)", "Perms (@chmod):      " + (((.flags()).prefix("+")).join()), "Manager (@chmanage): " + ($object_lib.get_name(obj.manager(), 'namef, ['ref])), ._exam_sub("Writer", 1, "@aw/@dw", chop, obj, 'writers, 'literal), ._exam_sub("Trusted", 0, "@at/@dt", chop, obj, 'trusted, 'literal), ._exam_sub("Parent", 1, "@ap/@dp", chop, obj, 'parents)];
    if (obj.has_ancestor($located))
        out += ["Location (@move):    " + ($object_lib.get_name(obj.location(), 'namef, ['xref]))];
    if ((desc = (| obj.prose() |)))
        out += ["Description (@describe): ", @(type(desc) == 'frob) ? desc.uncompile() : ((type(desc) == 'list) ? desc : [desc])];
    if ((cmds = (| obj.remote_commands() |)))
        out += $command_lib.format_commands_short(#[[obj, cmds]], "Remote", .linelen());
    if ((cmds = (| obj.local_commands() |)))
        out += $command_lib.format_commands_short(#[[obj, cmds]], "Local", .linelen());
    return out + ((| obj.examine() |) || []);
    
    // $#Edited: 31 Jan 97 22:00 $user_vang
};

protected method ._exam_sub() {
    arg name, plural, cmd, chop, obj, meth, @args;
    var list, line;
    
    list = (| obj.(meth)(@args) |) || [];
    if (!plural)
        line = pad(((name + " (") + cmd) + "):", 21) + (list.to_english("(none)"));
    else if (listlen(list) != 1)
        line = pad(((name + "s (") + cmd) + "):", 21) + (list.to_english("(none)"));
    else
        line = pad(((name + " (") + cmd) + "):", 21) + ((list[1]).namef('ref));
    if (chop)
        line = line.chop(chop);
    return line;
};

protected method .map_cmd() {
    arg cmdstr, cmd;
    var l, obj, pos;
    
    (> .perms(caller(), 'command) <);
    l = .location();
    pos = l.get_setting("map-position", $realm_settings);
    return (| (pos[4]).view(@pos.subrange(1, 3), 20, 79) |) || "This room doesn't have map defined for it.";
};

protected method .finger_cmd() {
    arg cmdstr, cmd, who;
    var out;
    
    (> .perms(caller(), 'command) <);
    out = ([("Information on " + (who.name())) + " (use @set to change):"] + ((who.display_info('no_blanks)).prefix("  "))) + ((.age_cmd("", "", who)).prefix("  "));
    if (who.connected())
        return out + [("  " + (who.name())) + " is currently connected."];
    else
        return out + [(((("  " + (who.name())) + " was last connected at ") + ($time.format("%r", abs(who.connected_at())))) + " ") + ($time.format("%A %B %e %Y", abs(who.connected_at())))];
    
    // $#Edited: 03 Dec 96 01:12 $brad
};

public method .prompt_yesno() {
    arg str, @def;
    var input, rx;
    
    // the second argument is an integer for the default value 
    [(def ?= 1)] = def;
    input = .prompt(str);
    if (match_regexp(input, "^(y|ye|yes)$"))
        return 1;
    if (match_regexp(input, "^(n|no)$"))
        return 0;
    return def;
    
    // $#Edited: 27 Oct 96 16:15 $brandon
    // $#Edited: 30 Nov 96 21:22 $miro
};

protected method .trusts_cmd() {
    arg cmdstr, cmd, what;
    
    (> .perms(caller(), 'command) <);
    return [(what.namef('ref)) + " trusts:"] + (._list_objects(what.trusted('literal), 'trusted_by));
};

protected method .del_name_template_cmd() {
    arg cmdstr, cmd, args;
    var syn, obj, template;
    
    (> .perms(caller(), 'command) <);
    args = args.explode_quoted();
    if ((listlen(args) > 2) && ((args[2]) == "from"))
        args = delete(args, 2);
    if (listlen(args) > 2)
        args = [args[1], sublist(args, 2).join()];
    if ((!args) || (listlen(args) != 2))
        return ("Syntax: `" + cmd) + " \"<template>\" [from] \"<object>\"`";
    obj = (> .match_env_nice(args[2]) <);
    template = args[1];
    if (!(obj.has_ancestor($has_name)))
        return obj + " cannot have regular names.";
    if (!(template in (obj.name_templates())))
        return (((obj.name()) + " does not have the name template \"") + template) + "\"";
    catch any
        obj = (> obj.del_name_template(template) <);
    with
        return (traceback()[1])[2];
    return ((((("Deleted name template \"" + template) + "\" from ") + (obj.namef('ref))) + ", templates: ") + ((obj.name_templates()).to_english("none"))) + ".";
};

protected method .writers_cmd() {
    arg cmdstr, cmd, what;
    
    (> .perms(caller(), 'command) <);
    return [(what.namef('ref)) + " is a writer for:"] + (._list_objects(what.writers('literal), 'writes));
};

protected method .manager_cmd() {
    arg cmdstr, cmd, what;
    
    (> .perms(caller(), 'command) <);
    return (((what.namef('ref)) + " is managed by ") + ((what.manager()).namef('ref))) + ".";
};

protected method .view_detail_cmd() {
    arg cmdstr, cmd, detail;
    
    (> .perms(caller(), 'command) <);
    if ((| (detail = (.location()).get_detail(detail)) |))
        .tell(detail);
    else
        .tell("No such detail on your location.");
    
    // $#Edited: 30 Oct 96 23:38 $miro
};

public method .get_cols() {
    arg @args;
    
    return cols || 80;
};

public method .get_rows() {
    arg @args;
    
    return rows || 19;
    
    // 19 is the number of display rows you have in tf, in
    // visual mode with a default display/terminal.
};

protected method .set_rows() {
    arg name, definer, value, @args;
    
    if ((value == 19) || (!value))
        (| clear_var('rows) |);
    else
        rows = value;
};

public method .get_base_parsers() {
    if (.command_aliases())
        return [$command_aliases_parser, $command_parser, $channel_parser];
    return [$command_parser, $channel_parser];
};

protected method .paste_cmd() {
    arg cmdstr, com, args;
    var obj, text, who, w, target;
    
    (> .perms(caller(), 'command) <);
    if (args) {
        args = args.sed("^to +", "");
        if ("," in args)
            args = args.explode_english_list();
        else
            args = args.explode();
        who = [];
        for w in (args) {
            catch ~ambig, ~namenf {
                target = (> $user_db.search(w) <);
            } with {
                catch any
                    target = (> .match_environment(w) <);
                with
                    .tell((traceback()[1])[2]);
            }
            if (target)
                who = setadd(who, target);
        }
        if (!who)
            return "No valid targets.";
    }
    text = .read();
    if (text == 'aborted)
        return .tell("@paste aborted.");
    else if (!text)
        return .tell("@paste nothing?");
    text = [((" " + (.name())) + " (@paste's) ").center(79, "-", 'both), @text, " + Finis + ".center(79, "-", 'both)];
    if (who) {
        for w in (who)
            (| w.tell(text) |);
        .tell(((((text.length()) - 2) + " lines of text pasted to ") + (who.map_to_english('name))) + ".");
    } else {
        (.location()).announce(text);
        .tell(((text.length()) - 2) + " lines of text pasted");
    }
};

public method .remote_cmd() {
    arg cmdstr, com, who, prep, str;
    var target, line, fstr, wstr, type, bad;
    
    (> .perms(caller(), $user, $robot) <);
    if (str && ((str[1]) == ":")) {
        type = 'emote;
        str = str.subrange(2);
    } else {
        type = 'say;
    }
    who = (> .parse_interaction_reference(who, tostr(type), 'userdb) <);
    if ((bad = filter target in (who) where (type(target) != 'objnum)))
        return ("Unable to find " + (bad.to_english())) + ".";
    .add_interaction('objs, who);
    line = .name();
    if (str && ((str[1]) == ":"))
        str = str.subrange(2);
    else
        line += " ";
    if (type == 'emote) {
        line += str;
    } else {
        if (str)
            line += $code_lib.punctuation_type(str);
        else
            line += "say";
        line = ((line + "s, \"") + str) + "\"";
    }
    wstr = (who.mmap('name)).to_english();
    fstr = "[from " + ((.location()).name());
    if ((who.length()) > 1)
        fstr = (fstr + ", to ") + wstr;
    fstr = (fstr + "] ") + line;
    for target in (who) {
        if (!(target.connected()))
            .tell((target.name()) + " is not connected.");
        (| target.directed_tell(fstr, 'remote) |);
    }
    .tell((("[to " + wstr) + "] ") + line);
};

protected method .new_editor_session() {
    arg ref, opts, type;
    var p;
    
    switch (ref[1]) {
        case 'object:
            if (!(| (p = (ref[2]).all_edit_types()) |))
                return "The object is not editable.";
            if (type == "any")
                type = p[1];
            if (!(| (ref[2]).(tosym("edit_" + type))() |))
                return ((("Could not edit " + (ref[2])) + "'s ") + type) + ".";
        default:
            return ("You cannot edit " + (ref[1])) + "s.";
    }
    if (.active_editor())
        return [("Editor invoked with " + ((.active_editor()).session_name())) + ".", "Type 'help' to list available commands."];
    else
        return ["Remote editing invoked."];
    
    // $#Edited: 20 Feb 97 20:01 $miro
};

protected method .set_setting_title() {
    arg definer, name, value, @args;
    
    .set_title(value);
};

public method .test() {
    var x, out;
    
    out = [];
    for x in (.look_cmd("", "look", "me")) {
        if (type(x) == 'frob)
            out += [$parse_lib.filter_ctext(x, #[['formatter, $text_format]])];
        else
            out += [x];
    }
    return out;
    
    // $#Edited: 07 Feb 97 13:24 $brandon
};

public method .get_auto_look() {
    arg @args;
    
    // invert the logic, most people want it on (less clutter this way)
    return !auto_look;
};

protected method .set_auto_look() {
    arg name, definer, value, @args;
    
    // invert the logic, most people want it on (less clutter this way)
    if (value) {
        if (auto_look)
            clear_var('auto_look);
    } else {
        auto_look = 'no;
    }
};

public method .msg_cmd() {
    arg cmdstr, cmd, args;
    var who, branch, name, msg, what, definer, opts, clear;
    
    (> .perms(caller(), 'command) <);
    
    // it niggles the string enough to 'clean' up little mistakes
    [args, opts] = $parse_lib.getopt(args, [["c?lear", 0]]);
    args = join(args).trim();
    clear = "c?lear" in (opts.slice(1));
    if ((what = regexp(args, "^([^:=]+): *(.*)$"))) {
        who = (> .match_env_nice((what[1]).trim()) <);
        args = (what[2]).trim();
    } else {
        who = this();
    }
    if ((what = regexp(args, "^([a-z0-9.-]+) *= *(.*)$"))) {
        name = (what[1]).trim();
        args = (what[2]).trim();
    } else {
        name = args;
        args = "";
    }
    if (!name)
        return ([("-- Messages on " + (who.namef('ref))) + ":"] + (.format_messages(who))) + ["---"];
    name = split(name, " *\. *");
    if (listlen(name) == 1) {
        name = name[1];
        branch = "";
    } else if (listlen(name) == 2) {
        [name, branch] = name;
    } else {
        return ("Invalid Message name \"" + (name.join("."))) + "\"";
    }
    if (!($code_lib.valid_message_id(name)))
        return ("Invalid Message name \"" + name) + "\"";
    if (branch && (!($code_lib.valid_message_id(branch))))
        return ((("Invalid Message branch \"" + name) + ".") + branch) + "\"";
    msg = args.unquote();
    catch any {
        definer = who.msg_definer(name);
        branch ?= "general";
        if (clear)
            who = who.clear_msg(name, branch);
        else
            who = who.set_msg(name, branch, definer, args);
        msg = (who.get_msg(name, definer))[branch];
        if (branch == "general")
            return ["-- Message changed to:", ("  " + name) + " = "].affix(msg.uncompile());
        else
            return ["-- Message changed to:", ((("  " + name) + ".") + branch) + " = "].affix(msg.uncompile());
    } with {
        return (traceback()[1])[2];
    }
};

public method .set_cmd() {
    arg cmdstr, cmd, args;
    var who, branch, name, setting, what, def, opts, clear, showdef;
    
    (> .perms(caller(), 'command) <);
    if ((what = regexp(args, "^ *\+(clear|c) +(.*)"))) {
        clear = 1;
        args = what[2];
    }
    if ((what = regexp(args, "^ *\+(def|definers|d) *= *\$?([a-z0-9_]+) *(.*)"))) {
        if (!(showdef = (| lookup(tosym(what[2])) |)))
            return "Invalid definer $" + (what[2]);
        args = what[3];
    }
    if ((what = regexp(args, "^ *\+(def|definers|d) *(.*)"))) {
        showdef = 1;
        args = what[2];
    }
    if ((what = regexp(args, "^([^:=]+): *(.*)$"))) {
        who = (> .match_env_nice((what[1]).trim()) <);
        args = (what[2]).trim();
    } else {
        who = this();
    }
    if ((what = regexp(args, "^([\@a-z0-9-]+) *= *(.*)$"))) {
        name = (what[1]).trim();
        args = (what[2]).trim();
    } else {
        name = args;
        args = "";
    }
    if (!name)
        return ([("-- Settings on " + (who.namef('ref))) + ":"] + (.format_settings(who, showdef))) + ["---"];
    if (!($code_lib.valid_setting_id(name)))
        return ("Invalid Setting name \"" + name) + "\"";
    setting = args.unquote();
    catch any {
        def = who.setting_definer(name);
        if (clear)
            who = who.clear_setting(name, def);
        else
            who = who.set_setting(name, def, setting);
        setting = who.format_setting(name, def, who.get_setting(name, def));
        return ["-- Setting changed to:", (("  " + name) + " = ") + setting, "--"];
    } with {
        return (traceback()[1])[2];
    }
};

public method .format_settings() {
    arg target, @showdef;
    var sets, out, m, s, value, defs;
    
    if (showdef)
        showdef = showdef[1];
    if (type(showdef) == 'objnum)
        sets = hash s in (showdef.defined_settings()) to ([s[1], showdef]);
    else
        sets = target.all_defined_settings();
    out = sets;
    for s in (sets) {
        catch any
            value = target.format_setting(@s, target.get_setting(@s));
        with
            value = (((traceback()[1])[1]) + ": ") + ((traceback()[1])[2]);
        out = dict_add(out, s[1], value);
    }
    if ((type(showdef) != 'objnum) && showdef) {
        defs = #[];
        for s in (sets)
            defs = defs.setadd_elem(tostr(s[2]), s[1]);
        sets = out;
        out = [];
        for m in (defs) {
            out += [(m[1]) + ":"];
            out += map s in ((m[2]).sort()) to ([(("  " + s) + " = ") + (sets[s])]);
        }
        return out;
    } else if (type(showdef) == 'objnum) {
        return [showdef + ":"] + map s in ((out.keys()).sort()) to ([(("  " + s) + " = ") + (out[s])]);
    } else {
        return map s in ((out.keys()).sort()) to ([(("  " + s) + " = ") + (out[s])]);
    }
};

public method ._tmp_wwmmmww() {
    $world.hook_into_event('realm_announce);
    
    // $#Edited: 07 Mar 97 16:31 $miro
};

public method .date_cmd() {
    arg @args;
    
    .tell($time.format("%I:%M %p %A, %B %d %Y %Z"));
};

public method .registered_names() {
    return registered || [];
    
    // $#Edited: 12 Mar 97 17:37 $brian
};

public method .parse_content_type() {
    arg value, @args;
    var type, types;
    
    types = ["plain", "html", "wrap?ped"];
    for type in (types) {
        if (match_template(value, type) || match_template(value, "text/" + type))
            return "text/" + strsed(type, "[^a-z]", "", "g");
    }
    throw(~check, "Content-type must be one of: " + ((types.prefix("text/")).to_english("", " or ")));
};

public method .parse_ext_parsers() {
    arg value, @args;
    var objs, o, r;
    
    objs = [];
    for o in (value.explode_english_list()) {
        o = o.trim();
        if (!(r = (| $object_lib.to_dbref(o) |))) {
            if (!(r = $user_parsers.match_children(o)))
                throw(~type, ("\"" + o) + "\" is not a child of $user_parsers.");
        }
        objs = setadd(objs, r);
    }
    
    // sorry buddy, no choice--these come from .get_base_parsers()
    for o in ((.get_base_parsers()) + [$command_aliases_parser])
        objs = setremove(objs, o);
    return objs;
};

public method .format_ext_parsers() {
    arg value;
    
    return value.to_english();
};

public method .parse_exit_style() {
    arg value, @args;
    var styles, s;
    
    // verify it is correct
    styles = ["none", "brief", "template?s", "long", "verbose"];
    for s in (styles) {
        if (match_template(value, s))
            return tosym(s.strip("?"));
    }
    throw(~wrong, "Style must be one of: " + (styles.to_english("", " or ")));
};

public method .clear_content_type() {
    arg name;
    
    content_type = 'plain;
};

public method .format_content_type() {
    arg value;
    
    return "text/" + value;
};

public method .get_content_type() {
    arg name, definer;
    
    return content_type;
};

protected method .set_closable() {
    arg name, definer, value;
    
    closable = value;
};


new object $guest: $user;

var $root child_index = 46;
var $root inited = 1;
var $root owned = [$guest];
var $root manager = $guest;
var $root quota = 75000;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core, 'command_cache];
var $root managed = [$guest];
var $location contents = [];
var $located location = $body_cave;
var $located obvious = 1;
var $user password = "*";
var $user connected_at = 0;
var $user last_command_at = 0;
var $user connections = [];
var $user modes = #[];
var $user formatter = $mail_list;
var $user parsers = [$command_parser];
var $user context = #[['last, $body_cave]];
var $user task_connections = #[];
var $command_aliases command_aliases = [];
var $mail_list letters = #[];
var $mail_list letters_index = #[];
var $mail_list senders = 1;
var $mail_list readers = 1;
var $mail_list notify = [$guest];
var $mail_list last_letter = 0;
var $mail_list mail = [];
var $mail_ui subscribed = #[[$guest, [791485891, 0]]];
var $mail_ui current = #[['location, 0], ['list, $guest]];
var $described prose = [];
var $has_name name = ['prop, "Generic Guest Object", "Generic Guest Object"];
var $has_commands local = #[];
var $channel_ui channel_dict = #[];
var $channel_ui active_channels = #[];
var $command_cache local_cache = #[["@quit", ["@quit"]], ["i", ["i?nventory"]], ["in", ["i?nventory"]], ["inv", ["i?nventory"]], ["inve", ["i?nventory"]], ["inven", ["i?nventory"]], ["invent", ["i?nventory"]], ["invento", ["i?nventory"]], ["inventor", ["i?nventory"]], ["inventory", ["i?nventory"]], ["@audit", ["@audit"]], ["@who", ["@who"]], ["@del-command-a", ["@del-command-a?lias|@dca?lias"]], ["@del-command-al", ["@del-command-a?lias|@dca?lias"]], ["@del-command-ali", ["@del-command-a?lias|@dca?lias"]], ["@del-command-alia", ["@del-command-a?lias|@dca?lias"]], ["@del-command-alias", ["@del-command-a?lias|@dca?lias"]], ["@dca", ["@del-command-a?lias|@dca?lias"]], ["@dcal", ["@del-command-a?lias|@dca?lias"]], ["@dcali", ["@del-command-a?lias|@dca?lias"]], ["@dcalia", ["@del-command-a?lias|@dca?lias"]], ["@dcalias", ["@del-command-a?lias|@dca?lias"]], ["@command-a", ["@command-a?liases|@ca?liases"]], ["@command-al", ["@command-a?liases|@ca?liases"]], ["@command-ali", ["@command-a?liases|@ca?liases"]], ["@command-alia", ["@command-a?liases|@ca?liases"]], ["@command-alias", ["@command-a?liases|@ca?liases"]], ["@command-aliase", ["@command-a?liases|@ca?liases"]], ["@command-aliases", ["@command-a?liases|@ca?liases"]], ["@ca", ["@command-a?liases|@ca?liases"]], ["@cal", ["@command-a?liases|@ca?liases"]], ["@cali", ["@command-a?liases|@ca?liases"]], ["@calia", ["@command-a?liases|@ca?liases"]], ["@calias", ["@command-a?liases|@ca?liases"]], ["@caliase", ["@command-a?liases|@ca?liases"]], ["@caliases", ["@command-a?liases|@ca?liases"]], ["@add-command-a", ["@add-command-a?lias|@aca?lias"]], ["@add-command-al", ["@add-command-a?lias|@aca?lias"]], ["@add-command-ali", ["@add-command-a?lias|@aca?lias"]], ["@add-command-alia", ["@add-command-a?lias|@aca?lias"]], ["@add-command-alias", ["@add-command-a?lias|@aca?lias"]], ["@aca", ["@add-command-a?lias|@aca?lias"]], ["@acal", ["@add-command-a?lias|@aca?lias"]], ["@acali", ["@add-command-a?lias|@aca?lias"]], ["@acalia", ["@add-command-a?lias|@aca?lias"]], ["@acalias", ["@add-command-a?lias|@aca?lias"]], ["@com", ["@com?mands"]], ["@comm", ["@com?mands"]], ["@comma", ["@com?mands"]], ["@comman", ["@com?mands"]], ["@command", ["@com?mands"]], ["@commands", ["@com?mands"]], ["@news", ["@news"]], ["@forget", ["@forget"]], ["@whereis", ["@whereis|@where-is"]], ["@where-is", ["@whereis|@where-is"]], ["@ways", ["@ways"]], ["@password", ["@password|@passwd"]], ["@passwd", ["@password|@passwd"]], ["@age", ["@age"]], ["@context", ["@context"]], ["get", ["get|take"]], ["take", ["get|take"]], ["drop", ["drop"]], ["@rename", ["@rename"]], ["@add-writer", ["@add-writer|@aw"]], ["@aw", ["@add-writer|@aw"]], ["@del-writer", ["@del-writer|@dw"]], ["@dw", ["@del-writer|@dw"]], ["@chman", ["@chman?age"]], ["@chmana", ["@chman?age"]], ["@chmanag", ["@chman?age"]], ["@chmanage", ["@chman?age"]], ["@manage", ["@manage?d"]], ["@managed", ["@manage?d"]], ["@remember", ["@remember"]], ["@remembered", ["@remembered"]], ["give", ["give|put"]], ["put", ["give|put"]], ["discard", ["discard"]], ["@writes", ["@writes"]], ["@trusted", ["@trusted?-by"]], ["@trusted-", ["@trusted?-by"]], ["@trusted-b", ["@trusted?-by"]], ["@trusted-by", ["@trusted?-by"]], ["@add-trust", ["@add-trust?ee|@at"]], ["@add-truste", ["@add-trust?ee|@at"]], ["@add-trustee", ["@add-trust?ee|@at"]], ["@at", ["@add-trust?ee|@at"]], ["@del-trust", ["@del-trust?ee|@dt"]], ["@del-truste", ["@del-trust?ee|@dt"]], ["@del-trustee", ["@del-trust?ee|@dt"]], ["@dt", ["@del-trust?ee|@dt"]], ["@monitor", ["@monitor"]], ["@ex", ["@ex?amine"]], ["@exa", ["@ex?amine"]], ["@exam", ["@ex?amine"]], ["@exami", ["@ex?amine"]], ["@examin", ["@ex?amine"]], ["@examine", ["@ex?amine"]], ["@map", ["@map"]], ["@finger", ["@finger|@ustat"]], ["@ustat", ["@finger|@ustat"]], ["@trusts", ["@trusts|@trustee?s"]], ["@trustee", ["@trusts|@trustee?s"]], ["@trustees", ["@trusts|@trustee?s"]], ["@writers", ["@writers"]], ["@manager", ["@manager"]], ["view", ["view"]], ["@desc", ["@desc?ribe|@prose"]], ["@descr", ["@desc?ribe|@prose"]], ["@descri", ["@desc?ribe|@prose"]], ["@describ", ["@desc?ribe|@prose"]], ["@describe", ["@desc?ribe|@prose"]], ["@prose", ["@desc?ribe|@prose"]], ["l", ["l?ook|exam?ine"]], ["lo", ["l?ook|exam?ine"]], ["loo", ["l?ook|exam?ine"]], ["look", ["l?ook|exam?ine"]], ["exam", ["l?ook|exam?ine"]], ["exami", ["l?ook|exam?ine"]], ["examin", ["l?ook|exam?ine"]], ["examine", ["l?ook|exam?ine"]], ["walk", ["walk|go"]], ["go", ["walk|go"]], ["@ant", ["@ant|@add-name-template"]], ["@add-name-template", ["@ant|@add-name-template"]], ["@dnt", ["@dnt|@del-name-template"]], ["@del-name-template", ["@dnt|@del-name-template"]], ["@name-template", ["@name-template?s|@template?s"]], ["@name-templates", ["@name-template?s|@template?s"]], ["@template", ["@name-template?s|@template?s"]], ["@templates", ["@name-template?s|@template?s"]], ["@register", ["@register|@register-name"]], ["@register-name", ["@register|@register-name"]], ["@unregister", ["@unregister|@unregister-name"]], ["@unregister-name", ["@unregister|@unregister-name"]], ["@registered", ["@registered"]], ["@page", ["@page"]], ["@paste", ["@paste?-to"]], ["@paste-", ["@paste?-to"]], ["@paste-t", ["@paste?-to"]], ["@paste-to", ["@paste?-to"]], ["@new", ["@new"]], ["@status", ["@status|@uptime"]], ["@uptime", ["@status|@uptime"]], ["@msg", ["@msg?s|@message?s"]], ["@msgs", ["@msg?s|@message?s"]], ["@message", ["@msg?s|@message?s"]], ["@messages", ["@msg?s|@message?s"]], ["@date", ["@date|@time"]], ["@time", ["@date|@time"]], ["@set", ["@set"]], ["wh", ["wh?isper"]], ["whi", ["wh?isper"]], ["whis", ["wh?isper"]], ["whisp", ["wh?isper"]], ["whispe", ["wh?isper"]], ["whisper", ["wh?isper"]], ["say", ["say"]], ["to", ["to"]], ["emote", ["emote"]], ["quote", ["quote"]], ["spoof", ["spoof"]], ["pose", ["pose"]], ["think", ["think"]], ["wear", ["wear"]], ["remove", ["remove|shed"]], ["shed", ["remove|shed"]], ["@a", ["@a?ction"]], ["@ac", ["@a?ction"]], ["@act", ["@a?ction"]], ["@acti", ["@a?ction"]], ["@actio", ["@a?ction"]], ["@action", ["@a?ction"]], ["@sub", ["@sub?scribed"]], ["@subs", ["@sub?scribed"]], ["@subsc", ["@sub?scribed"]], ["@subscr", ["@sub?scribed"]], ["@subscri", ["@sub?scribed"]], ["@subscrib", ["@sub?scribed"]], ["@subscribe", ["@sub?scribed"]], ["@subscribed", ["@sub?scribed"]], ["@unsub", ["@unsub?scribed"]], ["@unsubs", ["@unsub?scribed"]], ["@unsubsc", ["@unsub?scribed"]], ["@unsubscr", ["@unsub?scribed"]], ["@unsubscri", ["@unsub?scribed"]], ["@unsubscrib", ["@unsub?scribed"]], ["@unsubscribe", ["@unsub?scribed"]], ["@unsubscribed", ["@unsub?scribed"]], ["@mail-list", ["@mail-list?s"]], ["@mail-lists", ["@mail-list?s"]], ["@read", ["@read"]], ["@remove-m", ["@remove-m?ail|@rmm?ail"]], ["@remove-ma", ["@remove-m?ail|@rmm?ail"]], ["@remove-mai", ["@remove-m?ail|@rmm?ail"]], ["@remove-mail", ["@remove-m?ail|@rmm?ail"]], ["@rmm", ["@remove-m?ail|@rmm?ail"]], ["@rmma", ["@remove-m?ail|@rmm?ail"]], ["@rmmai", ["@remove-m?ail|@rmm?ail"]], ["@rmmail", ["@remove-m?ail|@rmm?ail"]], ["@nn", ["@nn|@next-new"]], ["@next-new", ["@nn|@next-new"]], ["@mail", ["@mail"]], ["@send", ["@send"]], ["@create", ["@create"]], ["help", ["help"]], ["page", ["page"]], ["who", ["who"]], ["quit", ["quit"]], ["news", ["news"]], ["@gender", ["@gender"]], ["uptime", ["uptime"]], ["@alias", ["@alias"]], ["@check", ["@check|@paranoid"]], ["@paranoid", ["@check|@paranoid"]], ["@version", ["@version"]], ["@lock", ["@lock"]], ["@unlock", ["@unlock"]], ["@help", ["@help"]], ["@mcp-upload-session", ["@mcp-upload-session"]], ["@cleanup-sessions", ["@cleanup-sessions|@c-s?essions"]], ["@c-s", ["@cleanup-sessions|@c-s?essions"]], ["@c-se", ["@cleanup-sessions|@c-s?essions"]], ["@c-ses", ["@cleanup-sessions|@c-s?essions"]], ["@c-sess", ["@cleanup-sessions|@c-s?essions"]], ["@c-sessi", ["@cleanup-sessions|@c-s?essions"]], ["@c-sessio", ["@cleanup-sessions|@c-s?essions"]], ["@c-session", ["@cleanup-sessions|@c-s?essions"]], ["@c-sessions", ["@cleanup-sessions|@c-s?essions"]], ["@edit", ["@edit"]], ["@desc-c", ["@desc-c?hannel"]], ["@desc-ch", ["@desc-c?hannel"]], ["@desc-cha", ["@desc-c?hannel"]], ["@desc-chan", ["@desc-c?hannel"]], ["@desc-chann", ["@desc-c?hannel"]], ["@desc-channe", ["@desc-c?hannel"]], ["@desc-channel", ["@desc-c?hannel"]], ["@ch", ["@ch?annels"]], ["@cha", ["@ch?annels"]], ["@chan", ["@ch?annels"]], ["@chann", ["@ch?annels"]], ["@channe", ["@ch?annels"]], ["@channel", ["@ch?annels"]], ["@channels", ["@ch?annels"]], ["@join-lock-channel", ["@join-lock-channel|@jlc"]], ["@jlc", ["@join-lock-channel|@jlc"]], ["@leave-lock-channel", ["@leave-lock-channel|@llc"]], ["@llc", ["@leave-lock-channel|@llc"]], ["@use-lock-channel", ["@use-lock-channel|@ulc"]], ["@ulc", ["@use-lock-channel|@ulc"]], ["@add-channel-manager", ["@add-channel-manager|@acm"]], ["@acm", ["@add-channel-manager|@acm"]], ["@del-channel-manager", ["@del-channel-manager|@dcm"]], ["@dcm", ["@del-channel-manager|@dcm"]], ["@add-ch", ["@add-ch?annel|@addcom"]], ["@add-cha", ["@add-ch?annel|@addcom"]], ["@add-chan", ["@add-ch?annel|@addcom"]], ["@add-chann", ["@add-ch?annel|@addcom"]], ["@add-channe", ["@add-ch?annel|@addcom"]], ["@add-channel", ["@add-ch?annel|@addcom"]], ["@addcom", ["@add-ch?annel|@addcom"]], ["@del-ch", ["@del-ch?annel|@delcom"]], ["@del-cha", ["@del-ch?annel|@delcom"]], ["@del-chan", ["@del-ch?annel|@delcom"]], ["@del-chann", ["@del-ch?annel|@delcom"]], ["@del-channe", ["@del-ch?annel|@delcom"]], ["@del-channel", ["@del-ch?annel|@delcom"]], ["@delcom", ["@del-ch?annel|@delcom"]], ["@purge-channel", ["@purge-channel"]], ["@blahblahblah", ["@blahblahblah"]]];
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 1]]]]];
var $command_cache shortcut_cache = [["--*", ['remote_cmd, ["@page ", "", " with ", 1]]], ["-* *", ['remote_cmd, ["@page ", 1, " with ", 2]]], ["|*", ['quote_cmd, ["quote ", 1]]], ["\"*", ['say_cmd, ["say ", 1]]], ["%*", ['think_cmd, ["think ", 1]]], ["!*", ['spoof_cmd, ["spoof ", 1]]], [",*,*", ['esay_cmd, ["esay ", 1, " with ", 2]]], [":*", ['emote_cmd, ["emote ", 1]]], [".*", ['pose_cmd, ["pose ", 1]]], ["''*", ['to_say_cmd, ["to ", "", " say ", 1]]], ["'* *", ['to_say_cmd, ["to ", 1, " say ", 2]]], ["?*", ['help_cmd, ["?", 1]]]];
var $thing gender = $gender_neuter;
var $root settings = #[["home", $body_cave]];

root method .init_guest() {
    .set_title("a guest");
};

protected method .logout() {
    arg connection;
    
    (| pass(connection) |);
    (> .destroy() <);
};

protected method .title_cmd() {
    arg cmdstr, com, str;
    
    (> .perms(caller(), 'command) <);
    .tell("Guests are not allowed to change their titles.");
};


new object $reaper: $user;

var $root manager = $reaper;
var $root quota = 75000;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['core];
var $root managed = [$reaper, $robot];
var $command_aliases command_aliases = [];
var $has_name name = ['prop, "Reaper", "Reaper"];
var $described prose = <$ctext_frob, [["A dark billowing cape covers his luminous and forboding form."], #[]]>;
var $location contents = [];
var $located location = $body_cave;
var $located obvious = 1;
var $body body_parts = #[];
var $user password = "*";
var $user connected_at = 0;
var $user last_command_at = 0;
var $user connections = [];
var $user creation_time = 780375877;
var $user parsers = [$command_parser];
var $user action = "";
var $user formatter = $mail_list;
var $user context = #[['last, $body_cave]];
var $user task_connections = #[];
var $mail_list mail = [];
var $mail_list senders = 1;
var $mail_list notify = [$reaper];
var $mail_ui subscribed = #[[$reaper, [791485891, 0]]];
var $mail_ui current = #[['location, 0], ['list, $reaper]];
var $channel_ui channel_dict = #[];
var $channel_ui active_channels = #[];
var $root owned = [$reaper];
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 1]]]]];
var $command_cache shortcut_cache = [];
var $thing gender = $gender_male;
var $root settings = #[["home", $body_cave]];


new object $no_one: $user;

var $user task_connections = #[];
var $user password = "*";
var $user connected_at = 0;
var $user last_command_at = 0;
var $user connections = [];
var $user creation_time = 759878010;
var $user action = "";
var $user modes = #[];
var $user formatter = $mail_list;
var $user parsers = [$command_parser];
var $user context = #[['last, $body_cave]];
var $root inited = 1;
var $root manager = $no_one;
var $root quota = 75000;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root managed = [$no_one];
var $command_aliases command_aliases = [];
var $location contents = [];
var $located location = $body_cave;
var $located obvious = 1;
var $mail_list letters = #[];
var $mail_list letters_index = #[];
var $mail_list senders = 1;
var $mail_list readers = [$no_one];
var $mail_list notify = [$no_one];
var $mail_list last_letter = 0;
var $mail_list mail = [];
var $mail_ui subscribed = #[[$no_one, [791485891, 0]]];
var $mail_ui current = #[['location, 0], ['list, $no_one]];
var $described prose = [];
var $has_name name = ['prop, "No One", "No One"];
var $channel_ui channel_dict = #[];
var $channel_ui active_channels = #[];
var $root owned = [$no_one];
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 1]]]]];
var $command_cache shortcut_cache = [];
var $thing gender = $gender_neuter;
var $root settings = #[["home", $body_cave]];


new object $player: $user;

var $root child_index = 2;
var $root fertile = 1;
var $root manager = $player;
var $root created_on = 809926794;
var $root inited = 1;
var $root quota = 75000;
var $user password = "*";
var $user connected_at = 0;
var $user last_command_at = 0;
var $user connections = [];
var $user parsers = [$command_parser];
var $user action = "";
var $user context = #[['last, $body_cave]];
var $user formatter = $mail_list;
var $user task_connections = #[];
var $located location = $body_cave;
var $located obvious = 1;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[["@sheet|@score", [["@sheet|@score", "*", "@sheet|@score <any>", 'sheet_cmd, #[[1, ['any, []]]]]]]];
var $player strength = [0, 0];
var $player agility = [0, 0];
var $player appearance = [0, 0];
var $player health = [0, 0];
var $player life = [0, 0];
var $player intellect = [0, 0];
var $player knowledge = [0, 0];
var $player backbone = [0, 0];
var $player charisma = [0, 0];
var $player humanity = [0, 0];
var $player perception = [0, 0];
var $player presence = [0, 0];
var $player source = 0;
var $player dead = 0;
var $player weapons = 0;
var $player identity = 0;
var $player affiliation = 0;
var $player points = 0;
var $player deaths = 0;
var $player encumbrance = 0;
var $player fatigue = 0;
var $player characteristics = 0;
var $has_name name = ['proper, "player", "player"];
var $location contents = [];
var $described prose = [];
var $mail_ui current = #[['location, 0], ['list, $player]];
var $mail_ui subscribed = #[[$player, [813278562, 0]], [$mail_list_news, [813278562, 0]]];
var $mail_list mail = [];
var $mail_list senders = 1;
var $mail_list readers = [$player];
var $mail_list notify = [$player];
var $command_aliases command_aliases = [];
var $channel_ui channel_dict = #[];
var $channel_ui active_channels = #[];
var $root flags = ['core];
var $root managed = [$player];
var $root owned = [$player];
var $command_cache local_cache = #[["@sheet", ["@sheet|@score"]], ["@score", ["@sheet|@score"]]];
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 1]]]]];
var $command_cache shortcut_cache = [];
var $thing gender = $gender_neuter;
var $root settings = #[["home", $body_cave]];

protected method .lower_attribute() {
    arg attribute, difference;
    var new;
    
    new = (get_var(attribute)[1]) - difference;
    set_var(attribute, get_var(attribute).replace(1, new));
};

public method .attribute(): nooverride, synchronized {
    arg attribute;
    
    if (caller() != definer())
        (> .perms(sender(), $storyteller) <);
    return get_var(attribute);
};

root method .init_player(): nooverride, synchronized {
    strength = [0, 0];
    agility = [0, 0];
    appearance = [0, 0];
    health = [0, 0];
    life = [0, 0];
    intellect = [0, 0];
    knowledge = [0, 0];
    backbone = [0, 0];
    charisma = [0, 0];
    humanity = [0, 0];
    perception = [0, 0];
    presence = [0, 0];
    source = [0, 0];
    weapons = [];
};

protected method .raise_attribute() {
    arg attribute, difference;
    var new;
    
    new = (get_var(attribute)[1]) + difference;
    if (new > (get_var(attribute)[2]))
        new = get_var(attribute)[2];
    set_var(attribute, get_var(attribute).replace(1, new));
};

public method .dead() {
    return dead;
};

protected method .sheet_cmd() {
    arg cmdstr, cmd, args;
    var t, out, g;
    
    (> .perms(caller(), 'command) <);
    if (args && (!(.is($storyteller))))
        return "Only storytellers can see other players stats.";
    t = args ? .match_env_nice(args) : this();
    out = [((("Strength:   " + (.format_score(@t.attribute('strength)))) + "Reaction: ") + (tostr(((t.attribute('agility))[1]) / 5).pad(8))) + "Strength Damage:    0", (("Agility:    " + (.format_score(@t.attribute('agility)))) + "Source:   ") + (.format_score(@t.attribute('source))), ((("Appearance: " + (.format_score(@t.attribute('appearance)))) + "Learn:    ") + (tostr(((t.attribute('intellect))[1]) / 3).pad(8))) + "Competancy Level:   0", (("Intellect:  " + (.format_score(@t.attribute('intellect)))) + "                  Advancement Points: ") + tostr(t.attribute('points)), (("Knowledge:  " + (.format_score(@t.attribute('intellect)))) + "Life:     ") + (.format_score(@t.attribute('life))), (((("Presence:   " + (.format_score(@t.attribute('presence)))) + "Health:   ") + (.format_score(@t.attribute('health)))) + "Humanity: ") + (.format_score(@t.attribute('humanity))), "Backbone:   " + (.format_score(@t.attribute('backbone))), (((("Charisma:   " + (.format_score(@t.attribute('charisma)))) + "Deaths:   ") + (tostr(t.attribute('deaths)).pad(8))) + "Encumbrance: ") + tostr(t.attribute('encumbrance)), (("Perception: " + (.format_score(@t.attribute('perception)))) + "                  Fatigue:     ") + tostr(t.attribute('fatigue))];
    return out;
};

public method .set_attribute() {
    arg attribute, value;
    
    (> .perms(sender()) <);
    set_var(attribute, [value, value]);
};

public method .format_score() {
    arg base, cur;
    
    return pad((base == cur) ? tostr(base) : ((cur + "/") + base), 8);
};


new object $storyteller: $player;

var $root manager = $storyteller;
var $located location = $body_cave;
var $root created_on = 809928922;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $player strength = [0, 0];
var $player agility = [0, 0];
var $player appearance = [0, 0];
var $player health = [0, 0];
var $player life = [0, 0];
var $player intellect = [0, 0];
var $player knowledge = [0, 0];
var $player backbone = [0, 0];
var $player charisma = [0, 0];
var $player humanity = [0, 0];
var $player perception = [0, 0];
var $player presence = [0, 0];
var $player source = [0, 0];
var $player weapons = [];
var $user task_connections = #[];
var $user formatter = $mail_list;
var $location contents = [];
var $root managed = [$storyteller];
var $root owned = [$storyteller];
var $user password = "*";
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 1]]]]];
var $command_cache shortcut_cache = [];
var $thing gender = 0;


new object $builder: $user;

var $root inited = 1;
var $root owned = [$builder];
var $root manager = $builder;
var $root quota = 75000;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'command_cache, 'variables];
var $root managed = [$builder];
var $location contents = [];
var $located location = $body_cave;
var $located obvious = 1;
var $user password = "*";
var $user connected_at = 0;
var $user last_command_at = 0;
var $user connections = [];
var $user modes = #[];
var $user formatter = $mail_list;
var $user parsers = [$command_parser];
var $user context = #[['last, $body_cave]];
var $user task_connections = #[];
var $command_aliases command_aliases = [];
var $mail_list letters = #[];
var $mail_list letters_index = #[];
var $mail_list senders = 1;
var $mail_list readers = [];
var $mail_list notify = [$builder];
var $mail_list last_letter = 0;
var $mail_list mail = [];
var $mail_ui subscribed = #[[$builder, [791485891, 0]]];
var $mail_ui current = #[['location, 0], ['list, $builder]];
var $described prose = [];
var $has_name name = ['prop, "Generic Builder", "Generic Builder"];
var $has_commands local = #[["@realm?s", [["@realm?s", "", "@realm?s", 'realms_cmd, #[]]]], ["@mv|@move", [["@mv|@move", "*", "@mv|@move <object:>", 'move_cmd, #[[1, ['object_opt, []]]]]]], ["@child?ren|@kids", [["@child?ren|@kids", "*", "@child?ren|@kids <object>", 'children_cmd, #[[1, ['object, []]]]]]], ["@par?ents", [["@par?ents", "*", "@par?ents <object>", 'parents_cmd, #[[1, ['object, []]]]]]], ["@build", [["@build", "*", "@build <any:-conf?igure>", 'build_cmd, #[[1, ['any_opt, [["conf?igure"]]]]]]]], ["@attach", [["@attach", "* to *", "@attach <any> to <descendant of $place>", 'attach_cmd, #[[1, ['any, []]], [3, ['descendant, [$place]]]]]]], ["@destroy", [["@destroy", "*", "@destroy <list object>", 'destroy_cmd, #[[1, ['list, ['object, []]]]]]]], ["@dig", [["@dig", "*", "@dig <any>", 'dig_cmd, #[[1, ['any, []]]]]]], ["@teleport|@go", [["@teleport|@go", "*", "@teleport|@go <any>", 'teleport_cmd, #[[1, ['any, []]]]]]], ["@def-msg|@def-message", [["@def-msg|@def-message", "*", "@def-msg|@def-message <any>", 'define_msg_cmd, #[[1, ['any, []]]]]]], ["@undef-msg|@undef-message", [["@undef-msg|@undef-message", "*", "@undef-msg|@undef-message <any>", 'undefine_msg_cmd, #[[1, ['any, []]]]]]]];
var $channel_ui channel_dict = #[];
var $channel_ui active_channels = #[];
var $command_cache local_cache = #[["@realm", ["@realm?s"]], ["@realms", ["@realm?s"]], ["@mv", ["@mv|@move"]], ["@move", ["@mv|@move"]], ["@child", ["@child?ren|@kids"]], ["@childr", ["@child?ren|@kids"]], ["@childre", ["@child?ren|@kids"]], ["@children", ["@child?ren|@kids"]], ["@kids", ["@child?ren|@kids"]], ["@par", ["@par?ents"]], ["@pare", ["@par?ents"]], ["@paren", ["@par?ents"]], ["@parent", ["@par?ents"]], ["@parents", ["@par?ents"]], ["@build", ["@build"]], ["@attach", ["@attach"]], ["@destroy", ["@destroy"]], ["@dig", ["@dig"]], ["@teleport", ["@teleport|@go"]], ["@go", ["@teleport|@go"]], ["@def-msg", ["@def-msg|@def-message"]], ["@def-message", ["@def-msg|@def-message"]], ["@undef-msg", ["@undef-msg|@undef-message"]], ["@undef-message", ["@undef-msg|@undef-message"]], ["@quit", ["@quit"]], ["i", ["i?nventory"]], ["in", ["i?nventory"]], ["inv", ["i?nventory"]], ["inve", ["i?nventory"]], ["inven", ["i?nventory"]], ["invent", ["i?nventory"]], ["invento", ["i?nventory"]], ["inventor", ["i?nventory"]], ["inventory", ["i?nventory"]], ["@audit", ["@audit"]], ["@who", ["@who"]], ["@del-command-a", ["@del-command-a?lias|@dca?lias"]], ["@del-command-al", ["@del-command-a?lias|@dca?lias"]], ["@del-command-ali", ["@del-command-a?lias|@dca?lias"]], ["@del-command-alia", ["@del-command-a?lias|@dca?lias"]], ["@del-command-alias", ["@del-command-a?lias|@dca?lias"]], ["@dca", ["@del-command-a?lias|@dca?lias"]], ["@dcal", ["@del-command-a?lias|@dca?lias"]], ["@dcali", ["@del-command-a?lias|@dca?lias"]], ["@dcalia", ["@del-command-a?lias|@dca?lias"]], ["@dcalias", ["@del-command-a?lias|@dca?lias"]], ["@command-a", ["@command-a?liases|@ca?liases"]], ["@command-al", ["@command-a?liases|@ca?liases"]], ["@command-ali", ["@command-a?liases|@ca?liases"]], ["@command-alia", ["@command-a?liases|@ca?liases"]], ["@command-alias", ["@command-a?liases|@ca?liases"]], ["@command-aliase", ["@command-a?liases|@ca?liases"]], ["@command-aliases", ["@command-a?liases|@ca?liases"]], ["@ca", ["@command-a?liases|@ca?liases"]], ["@cal", ["@command-a?liases|@ca?liases"]], ["@cali", ["@command-a?liases|@ca?liases"]], ["@calia", ["@command-a?liases|@ca?liases"]], ["@calias", ["@command-a?liases|@ca?liases"]], ["@caliase", ["@command-a?liases|@ca?liases"]], ["@caliases", ["@command-a?liases|@ca?liases"]], ["@add-command-a", ["@add-command-a?lias|@aca?lias"]], ["@add-command-al", ["@add-command-a?lias|@aca?lias"]], ["@add-command-ali", ["@add-command-a?lias|@aca?lias"]], ["@add-command-alia", ["@add-command-a?lias|@aca?lias"]], ["@add-command-alias", ["@add-command-a?lias|@aca?lias"]], ["@aca", ["@add-command-a?lias|@aca?lias"]], ["@acal", ["@add-command-a?lias|@aca?lias"]], ["@acali", ["@add-command-a?lias|@aca?lias"]], ["@acalia", ["@add-command-a?lias|@aca?lias"]], ["@acalias", ["@add-command-a?lias|@aca?lias"]], ["@com", ["@com?mands"]], ["@comm", ["@com?mands"]], ["@comma", ["@com?mands"]], ["@comman", ["@com?mands"]], ["@command", ["@com?mands"]], ["@commands", ["@com?mands"]], ["@news", ["@news"]], ["@forget", ["@forget"]], ["@whereis", ["@whereis|@where-is"]], ["@where-is", ["@whereis|@where-is"]], ["@ways", ["@ways"]], ["@password", ["@password|@passwd"]], ["@passwd", ["@password|@passwd"]], ["@age", ["@age"]], ["@context", ["@context"]], ["get", ["get|take"]], ["take", ["get|take"]], ["drop", ["drop"]], ["@rename", ["@rename"]], ["@add-writer", ["@add-writer|@aw"]], ["@aw", ["@add-writer|@aw"]], ["@del-writer", ["@del-writer|@dw"]], ["@dw", ["@del-writer|@dw"]], ["@chman", ["@chman?age"]], ["@chmana", ["@chman?age"]], ["@chmanag", ["@chman?age"]], ["@chmanage", ["@chman?age"]], ["@manage", ["@manage?d"]], ["@managed", ["@manage?d"]], ["@remember", ["@remember"]], ["@remembered", ["@remembered"]], ["give", ["give|put"]], ["put", ["give|put"]], ["discard", ["discard"]], ["@writes", ["@writes"]], ["@trusted", ["@trusted?-by"]], ["@trusted-", ["@trusted?-by"]], ["@trusted-b", ["@trusted?-by"]], ["@trusted-by", ["@trusted?-by"]], ["@add-trust", ["@add-trust?ee|@at"]], ["@add-truste", ["@add-trust?ee|@at"]], ["@add-trustee", ["@add-trust?ee|@at"]], ["@at", ["@add-trust?ee|@at"]], ["@del-trust", ["@del-trust?ee|@dt"]], ["@del-truste", ["@del-trust?ee|@dt"]], ["@del-trustee", ["@del-trust?ee|@dt"]], ["@dt", ["@del-trust?ee|@dt"]], ["@monitor", ["@monitor"]], ["@ex", ["@ex?amine"]], ["@exa", ["@ex?amine"]], ["@exam", ["@ex?amine"]], ["@exami", ["@ex?amine"]], ["@examin", ["@ex?amine"]], ["@examine", ["@ex?amine"]], ["@map", ["@map"]], ["@finger", ["@finger|@ustat"]], ["@ustat", ["@finger|@ustat"]], ["@trusts", ["@trusts|@trustee?s"]], ["@trustee", ["@trusts|@trustee?s"]], ["@trustees", ["@trusts|@trustee?s"]], ["@writers", ["@writers"]], ["@manager", ["@manager"]], ["view", ["view"]], ["@desc", ["@desc?ribe|@prose"]], ["@descr", ["@desc?ribe|@prose"]], ["@descri", ["@desc?ribe|@prose"]], ["@describ", ["@desc?ribe|@prose"]], ["@describe", ["@desc?ribe|@prose"]], ["@prose", ["@desc?ribe|@prose"]], ["l", ["l?ook|exam?ine"]], ["lo", ["l?ook|exam?ine"]], ["loo", ["l?ook|exam?ine"]], ["look", ["l?ook|exam?ine"]], ["exam", ["l?ook|exam?ine"]], ["exami", ["l?ook|exam?ine"]], ["examin", ["l?ook|exam?ine"]], ["examine", ["l?ook|exam?ine"]], ["walk", ["walk|go"]], ["go", ["walk|go"]], ["@ant", ["@ant|@add-name-template"]], ["@add-name-template", ["@ant|@add-name-template"]], ["@dnt", ["@dnt|@del-name-template"]], ["@del-name-template", ["@dnt|@del-name-template"]], ["@name-template", ["@name-template?s|@template?s"]], ["@name-templates", ["@name-template?s|@template?s"]], ["@template", ["@name-template?s|@template?s"]], ["@templates", ["@name-template?s|@template?s"]], ["@register", ["@register|@register-name"]], ["@register-name", ["@register|@register-name"]], ["@unregister", ["@unregister|@unregister-name"]], ["@unregister-name", ["@unregister|@unregister-name"]], ["@registered", ["@registered"]], ["@page", ["@page"]], ["@paste", ["@paste?-to"]], ["@paste-", ["@paste?-to"]], ["@paste-t", ["@paste?-to"]], ["@paste-to", ["@paste?-to"]], ["@new", ["@new"]], ["@status", ["@status|@uptime"]], ["@uptime", ["@status|@uptime"]], ["@msg", ["@msg?s|@message?s"]], ["@msgs", ["@msg?s|@message?s"]], ["@message", ["@msg?s|@message?s"]], ["@messages", ["@msg?s|@message?s"]], ["@date", ["@date|@time"]], ["@time", ["@date|@time"]], ["@set", ["@set"]], ["wh", ["wh?isper"]], ["whi", ["wh?isper"]], ["whis", ["wh?isper"]], ["whisp", ["wh?isper"]], ["whispe", ["wh?isper"]], ["whisper", ["wh?isper"]], ["say", ["say"]], ["to", ["to"]], ["emote", ["emote"]], ["quote", ["quote"]], ["spoof", ["spoof"]], ["pose", ["pose"]], ["think", ["think"]], ["wear", ["wear"]], ["remove", ["remove|shed"]], ["shed", ["remove|shed"]], ["@a", ["@a?ction"]], ["@ac", ["@a?ction"]], ["@act", ["@a?ction"]], ["@acti", ["@a?ction"]], ["@actio", ["@a?ction"]], ["@action", ["@a?ction"]], ["@sub", ["@sub?scribed"]], ["@subs", ["@sub?scribed"]], ["@subsc", ["@sub?scribed"]], ["@subscr", ["@sub?scribed"]], ["@subscri", ["@sub?scribed"]], ["@subscrib", ["@sub?scribed"]], ["@subscribe", ["@sub?scribed"]], ["@subscribed", ["@sub?scribed"]], ["@unsub", ["@unsub?scribed"]], ["@unsubs", ["@unsub?scribed"]], ["@unsubsc", ["@unsub?scribed"]], ["@unsubscr", ["@unsub?scribed"]], ["@unsubscri", ["@unsub?scribed"]], ["@unsubscrib", ["@unsub?scribed"]], ["@unsubscribe", ["@unsub?scribed"]], ["@unsubscribed", ["@unsub?scribed"]], ["@mail-list", ["@mail-list?s"]], ["@mail-lists", ["@mail-list?s"]], ["@read", ["@read"]], ["@remove-m", ["@remove-m?ail|@rmm?ail"]], ["@remove-ma", ["@remove-m?ail|@rmm?ail"]], ["@remove-mai", ["@remove-m?ail|@rmm?ail"]], ["@remove-mail", ["@remove-m?ail|@rmm?ail"]], ["@rmm", ["@remove-m?ail|@rmm?ail"]], ["@rmma", ["@remove-m?ail|@rmm?ail"]], ["@rmmai", ["@remove-m?ail|@rmm?ail"]], ["@rmmail", ["@remove-m?ail|@rmm?ail"]], ["@nn", ["@nn|@next-new"]], ["@next-new", ["@nn|@next-new"]], ["@mail", ["@mail"]], ["@send", ["@send"]], ["@create", ["@create"]], ["help", ["help"]], ["page", ["page"]], ["who", ["who"]], ["quit", ["quit"]], ["news", ["news"]], ["@gender", ["@gender"]], ["uptime", ["uptime"]], ["@alias", ["@alias"]], ["@check", ["@check|@paranoid"]], ["@paranoid", ["@check|@paranoid"]], ["@version", ["@version"]], ["@lock", ["@lock"]], ["@unlock", ["@unlock"]], ["@help", ["@help"]], ["@mcp-upload-session", ["@mcp-upload-session"]], ["@cleanup-sessions", ["@cleanup-sessions|@c-s?essions"]], ["@c-s", ["@cleanup-sessions|@c-s?essions"]], ["@c-se", ["@cleanup-sessions|@c-s?essions"]], ["@c-ses", ["@cleanup-sessions|@c-s?essions"]], ["@c-sess", ["@cleanup-sessions|@c-s?essions"]], ["@c-sessi", ["@cleanup-sessions|@c-s?essions"]], ["@c-sessio", ["@cleanup-sessions|@c-s?essions"]], ["@c-session", ["@cleanup-sessions|@c-s?essions"]], ["@c-sessions", ["@cleanup-sessions|@c-s?essions"]], ["@edit", ["@edit"]], ["@desc-c", ["@desc-c?hannel"]], ["@desc-ch", ["@desc-c?hannel"]], ["@desc-cha", ["@desc-c?hannel"]], ["@desc-chan", ["@desc-c?hannel"]], ["@desc-chann", ["@desc-c?hannel"]], ["@desc-channe", ["@desc-c?hannel"]], ["@desc-channel", ["@desc-c?hannel"]], ["@ch", ["@ch?annels"]], ["@cha", ["@ch?annels"]], ["@chan", ["@ch?annels"]], ["@chann", ["@ch?annels"]], ["@channe", ["@ch?annels"]], ["@channel", ["@ch?annels"]], ["@channels", ["@ch?annels"]], ["@join-lock-channel", ["@join-lock-channel|@jlc"]], ["@jlc", ["@join-lock-channel|@jlc"]], ["@leave-lock-channel", ["@leave-lock-channel|@llc"]], ["@llc", ["@leave-lock-channel|@llc"]], ["@use-lock-channel", ["@use-lock-channel|@ulc"]], ["@ulc", ["@use-lock-channel|@ulc"]], ["@add-channel-manager", ["@add-channel-manager|@acm"]], ["@acm", ["@add-channel-manager|@acm"]], ["@del-channel-manager", ["@del-channel-manager|@dcm"]], ["@dcm", ["@del-channel-manager|@dcm"]], ["@add-ch", ["@add-ch?annel|@addcom"]], ["@add-cha", ["@add-ch?annel|@addcom"]], ["@add-chan", ["@add-ch?annel|@addcom"]], ["@add-chann", ["@add-ch?annel|@addcom"]], ["@add-channe", ["@add-ch?annel|@addcom"]], ["@add-channel", ["@add-ch?annel|@addcom"]], ["@addcom", ["@add-ch?annel|@addcom"]], ["@del-ch", ["@del-ch?annel|@delcom"]], ["@del-cha", ["@del-ch?annel|@delcom"]], ["@del-chan", ["@del-ch?annel|@delcom"]], ["@del-chann", ["@del-ch?annel|@delcom"]], ["@del-channe", ["@del-ch?annel|@delcom"]], ["@del-channel", ["@del-ch?annel|@delcom"]], ["@delcom", ["@del-ch?annel|@delcom"]], ["@purge-channel", ["@purge-channel"]], ["@blahblahblah", ["@blahblahblah"]]];
var $command_cache shortcut_cache = [["--*", ['remote_cmd, ["@page ", "", " with ", 1]]], ["-* *", ['remote_cmd, ["@page ", 1, " with ", 2]]], ["|*", ['quote_cmd, ["quote ", 1]]], ["\"*", ['say_cmd, ["say ", 1]]], ["%*", ['think_cmd, ["think ", 1]]], ["!*", ['spoof_cmd, ["spoof ", 1]]], [",*,*", ['esay_cmd, ["esay ", 1, " with ", 2]]], [":*", ['emote_cmd, ["emote ", 1]]], [".*", ['pose_cmd, ["pose ", 1]]], ["''*", ['to_say_cmd, ["to ", "", " say ", 1]]], ["'* *", ['to_say_cmd, ["to ", 1, " say ", 2]]], ["?*", ['help_cmd, ["?", 1]]]];
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 1]]]]];
var $foundation defined_msgs = #[["teleport", #[['branches, ["source", "dest", "actor"]]]]];
var $foundation msgs = #[["teleport", #[["actor", <$ctext_frob, [["You teleport to ", <$generator, ["dest", [], [], 'gen_dest]>, "."], #[['this, $builder]]]>], ["source", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " teleports to ", <$generator, ["dest", [], [], 'gen_dest]>, "."], #[['this, $builder]]]>], ["dest", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " teleports here from ", <$generator, ["source", [], [], 'gen_source]>, "."], #[['this, $builder]]]>]]]];
var $thing gender = $gender_neuter;
var $root settings = #[["home", $body_cave]];

protected method .children_cmd() {
    arg cmdstr, cmd, what;
    
    (> .perms(caller(), 'command) <);
    return [("Children of " + (what.namef('xref))) + ":"] + (._list_objects(what.children(), 'parents));
};

protected method .parents_cmd() {
    arg cmdstr, cmd, what;
    
    (> .perms(caller(), 'command) <);
    return [((("Parent" + ((((.parents()).length()) > 1) ? "s" : "")) + " of ") + (what.namef('ref))) + ":"] + (._list_objects(what.parents(), 'children));
};

protected method .destroy_cmd() {
    arg cmdstr, cmd, objs;
    var name, yes, obj;
    
    (> .perms(caller(), 'command) <);
    cmdstr = cmdstr.trim();
    if ((cmdstr.trim()) in ["@dest", "@destroy"]) {
        yes = .prompt(("Destroy '" + name) + "'? ");
        if (!(yes in ["y", "yes"]))
            return "Ok, aborting..";
    }
    for obj in (objs) {
        catch any {
            name = obj.namef('xref);
            (> obj.destroy() <);
            if (valid(obj))
                .tell(("Unable to destroy " + name) + " immediately.");
            else
                .tell(("Sucessfully destroyed " + name) + ".");
        } with {
            return (traceback()[1])[2];
        }
    }
};

protected method .build_get_location() {
    arg name;
    var dest, m, realm, parent, str;
    
    (> .perms(sender()) <);
    .build_hint(1);
    if (name) {
        if ((m = match_template(name, "to *")))
            name = m[2];
        name = (| $code_lib.parse_name(name) |);
    }
    while (!name) {
        catch any {
            name = (> .build_get_name("Destination: ") <);
            str = (name[1])[1];
            if ((m = regexp(str, "^ *\$([a-z0-9_]+) *(.*)$"))) {
                name = replace(name, 1, replace(name[1], 1, m[2]));
                catch ~namenf, ~symbol {
                    parent = (> lookup(tosym(m[1])) <);
                } with {
                    .tell((traceback()[1])[1]);
                    continue;
                }
                if (!(parent.is($place))) {
                    .tell(("Parent object " + (parent.namef('ref))) + " is not a place!");
                    continue;
                } else if ((!(parent.has_flag('fertile))) && (!(parent.is_writable_by(this())))) {
                    .tell(("Parent object " + (parent.namef('ref))) + " is not fertile!");
                    continue;
                }
            }
        } with {
            if (error() == ~skip) {
                .tell("You cannot skip this step!");
                continue;
            }
            rethrow(error());
        }
    }
    
    // first try to see if it already exists--only do this if they used
    // the direct $dbref too many conflicts otherwise.
    catch any {
        dest = (> $object_lib.to_dbref((name[1])[1]) <);
        (dest.is($place)) || throw(~place, (dest.namef('ref)) + " is not a place.");
        return [dest, 0];
    }
    
    // create it
    .build_hint(2);
    if (!parent)
        dest = (> ($place_lib.get_default('place)).spawn() <);
    else
        dest = (> parent.spawn() <);
    .build_set_name(dest, @name);
    .build_hint(4);
    catch any {
        realm = (> .build_query_realm(dest) <);
    } with {
        if (error() == ~skip)
            return dest;
        .build_cleanup([dest, 1]);
        rethrow(error());
    }
    
    // set the realm
    dest.set_setting_realm($place, "realm", realm);
    
    // okee, done
    return [dest, 1];
};

protected method .build_cmd() {
    arg cmdstr, cmd, args;
    var dest, source, exits, set, str, i;
    
    (> .perms(caller(), 'command) <);
    str = (args[1]).join();
    source = .location();
    args = args[2];
    if (!(| source.will_attach('source) |))
        return "This room is not publicly extendable.";
    
    // Establish the objects
    catch any {
        dest = (> .build_get_location(str) <);
        if (!(| (dest[1]).will_attach('dest) |)) {
            .tell(((dest[1]).name()) + " will not allow you to attach to it!");
            .build_cleanup(dest);
            return "** Build Aborted **";
        }
        exits = (> .build_get_exits(source, dest[1]) <);
        (> .build_attach_exit(exits[1], source, dest[1]) <);
        (> .build_attach_exit(exits[2], dest[1], source) <);
    } with {
        if (dest)
            .build_cleanup(dest);
        if (exits) {
            if (exits[1])
                .build_cleanup([exits[1], 1]);
            if (exits[2])
                .build_cleanup([exits[2], 1]);
        }
        if (error() == ~abort)
            return "** Build Aborted **";
        return [(traceback()[1])[2], "** Build Aborted **"];
    }
    .tell(("Completed building to " + ((dest[1]).name())) + ".");
    if ((i = "conf?igure" in (args.slice(1)))) {
        if (!((args[i])[3]))
            return "Skipping post-configuration.";
    }
    .tell("post-configuration..");
    
    // Flesh them out      
    set = #[['named_name, 1]];
    if (dest[2])
        (> (dest[1]).configure(set) <);
    if (exits[1])
        (> (exits[1]).configure(set) <);
    if (exits[2])
        (> (exits[2]).configure(set) <);
    return "Completed post-configuration.";
    
    // $#Edited: 19 Feb 97 02:36 $miro
};

protected method .build_hint() {
    arg n;
    
    (> .perms(sender()) <);
    if ((| .get_setting("experienced", $user) |))
        return;
    .tell($place_lib.build_hint(n));
};

protected method .attach_cmd() {
    arg cmdstr, cmd, source, prep, dest;
    var exit;
    
    (> .perms(caller(), 'command) <);
    if (!source) {
        source = .location();
    } else {
        catch any
            source = (> .match_environment(source_str) <);
        with
            return (traceback()[1])[2];
        if (!(source.is($place)))
            return (source.namef('ref)) + " is not a descendant of $place.";
    }
    catch ~abort, ~skip
        exit = (> .build_query_exit(dest, source) <);
    with
        return "Aborted.";
    catch any {
        exit.attach(source, dest);
        exit.configure(#[['named_name, 1]]);
    } with {
        .tell("Ack, unable to attach exit because:");
        .tell("  " + ((traceback()[1])[2]));
        (| exit.destroy() |);
        return;
    }
    return ("Successfully attached exit " + (exit.name())) + ".";
};

protected method .realms_cmd() {
    arg cmdstr, cmd;
    var x, realms;
    
    (> .perms(caller(), 'command) <);
    realms = ($place_lib.known_realms()).union($realm.descendants());
    .tell(["Realms:", ""] + ((realms.mmap('name)).prefix("    ")));
    
    // $#Edited: 15 Feb 97 19:53 $miro
};

protected method .move_cmd() {
    arg cmdstr, cmd, args;
    var what, dest, loc, fromto;
    
    (> .perms(caller(), 'command) <);
    what = args[1];
    args = args[2];
    if (args && ((args[1]) == "to"))
        args = delete(args, 1);
    if (!args)
        return ("You have to move " + (what.namef('ref))) + " somewhere.";
    dest = (> .match_env_nice(args.join()) <);
    catch any {
        loc = what.location();
        fromto = ((" from " + ((| loc.name() |) || $nowhere)) + " to ") + (dest.name());
        (| what.tell(((("You are suddenly yanked" + fromto) + " by ") + (.name())) + ".") |);
        (> what.move_to(dest) <);
    
        // hook into messages eventually
        (| loc.announce((what.name()) + " suddenly disappears.") |);
        (| dest.announce((what.name()) + " suddenly appears.", what) |);
        return (("You move " + (what.name())) + fromto) + ".";
    } with {
        (| what.tell(("You feel as if " + (.name())) + " was incapable of moving you, you did not go anywhere.") |);
        return (traceback()[1])[2];
    }
};

protected method .build_cleanup() {
    arg @what;
    var obj;
    
    (> .perms(caller(), definer()) <);
    for obj in (what) {
        if (valid(obj[1]) && (obj[2])) {
            .tell(("Destroying " + ((obj[1]).name())) + "...");
            (| (obj[1]).destroy() |);
        }
    }
};

protected method .build_query_exit() {
    arg source, dest, @args;
    var exit, line, name, def, from, str, m, parent;
    
    from = "from " + (source.name());
    line = (("Exit " + from) + " to ") + (dest.name());
    if (args) {
        def = args[1];
        line += (" [" + def) + "] ";
    } else {
        line += ": ";
    }
    while (!exit) {
        catch ~skip
            name = (> .build_get_name(line, def) <);
        with
            return 0;
        if (((name[1])[1]) == "@none")
            return 0;
        catch any
            exit = (> .build_generate_exit(name, source, dest) <);
        with
            .tell((traceback()[1])[2]);
    }
    return exit;
};

protected method .build_set_name() {
    arg obj, name, templates;
    var t, x;
    
    catch any {
        obj = obj.set_name(@name);
    } with {
        .tell("Unable to set name; " + ((traceback()[1])[2]));
        .tell("Setting name as " + (obj.objname()));
        obj = obj.set_name(tostr(obj.objname()));
    }
    for t in (templates)
        obj = obj.add_name_template(t);
    return obj;
};

protected method .build_prompt() {
    arg prompt, @def;
    var name, ans;
    
    [(def ?= "")] = def;
    while (!ans) {
        ans = .prompt(prompt);
        if (ans == "@skip")
            throw(~skip, "Skipped");
        if (ans == "@abort")
            throw(~abort, "Aborted");
        if (!ans) {
            if (!def)
                continue;
            ans = def;
        }
    }
    return ans;
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

protected method .build_get_name() {
    arg prompt, @def;
    var name, out;
    
    .build_hint(3);
    while (!out) {
        name = (> .build_prompt(prompt, @def) <);
        if (!(out = (| $code_lib.parse_name(name) |)))
            .tell("Invalid name.");
    }
    return out;
};

protected method .build_query_realm() {
    arg there;
    var line, realm, r, prompt;
    
    prompt = ((("What realm is " + (there.name())) + " in? [") + (((.location()).realm()).name())) + "] ";
    while (!realm) {
        line = (> .build_prompt(prompt, tostr((.location()).realm())) <);
        if (!line) {
            realm = (.location()).realm();
        } else if (line == "@realms") {
            r = ($place_lib.known_realms()).union($realm.descendants());
            .tell(["Realms:", ""] + ((realms.mmap('name)).prefix("    ")));
        } else {
            realm = $place_lib.match_realm(line);
            if (!realm) {
                .tell(("Unknown realm \"" + line) + "\", try @realms.");
            } else if (!(realm.is($realm))) {
                .tell((realm.namef('ref)) + " is not a realm, try @realms.");
                realm = 0;
            }
        }
    }
    return realm;
    
    // $#Edited: 15 Feb 97 19:53 $miro
    // $#Edited: 19 Feb 97 02:23 $miro
};

protected method .build_get_exits() {
    arg source, dest;
    var eleave, earrive, opp, t;
    
    // Get the exits
    catch any {
        eleave = (> .build_query_exit(source, dest) <);
        if (eleave) {
            // try really hard to figure this out
            if (!(opp = $place_lib.opposite_direction(eleave.name()))) {
                for t in (eleave.name_templates()) {
                    t = strsed(t, "[^a-z]+", "", "g");
                    if ((opp = $place_lib.opposite_direction(eleave.name())))
                        break;
                }
            }
            if (opp) {
                opp = strsed(explode(opp, "|")[1], "[^a-z]+", "", "g");
                earrive = (> .build_query_exit(dest, source, opp) <);
            } else {
                earrive = (> .build_query_exit(dest, source) <);
            }
        }
    } with {
        if (eleave) {
            .build_cleanup([eleave, 1]);
            if (earrive)
                .build_cleanup([earrive, 1]);
        }
        rethrow(error());
    }
    return [eleave, earrive];
};

protected method .build_attach_exit() {
    arg exit, source, dest;
    var line;
    
    catch any {
        exit.attach(source, dest);
    } with {
        $brandon.tell_traceback(traceback());
        .tell(("Unable to attach " + (exit.name())) + " because: ");
        .tell("  " + ((traceback()[1])[2]));
        line = .prompt("Continue building? ");
        if (line in ["no", "n"])
            throw(~abort, "Aborted");
    }
};

public method .dig_cmd() {
    arg cmdstr, cmd, args;
    var m, syn, name, dest, dnew, parent, name, lname, aname, leave, arrive, loc;
    
    (> .perms(caller(), 'command) <);
    syn = ["Syntax: `@dig <new place>` OR", "        `@dig <leaving exit>[;<arriving exit>] to <objref or new place>`", "You may also want to try @build."];
    if (!args)
        return syn;
    loc = .location();
    
    // are they essentially just @spawn'ing?
    if (!(m = match_template(args, "* to *"))) {
        if ((args[1]) == "$")
            return syn;
        if (!(name = (> $code_lib.parse_name(args) <)))
            return "Invalid name.";
        [parent, dest] = (> .build_parse_name((name[1])[1], $place) <);
        name = replace(name, 1, replace(name[1], 1, dest));
        catch any
            dest = (> parent.spawn() <);
        with
            return (traceback()[1])[2];
        .build_set_name(dest, @name);
        dest.set_realm(loc.realm());
        return ("New place created " + (dest.namef('ref))) + ".";
    }
    
    // can we extend from this room?
    if (!(| loc.will_attach('source) |))
        return "This room is not publicly extendable.";
    
    // do some basic parsing before we needlessly create anything
    [args, m, name] = m;
    [lname, (aname ?= "")] = split(args, " *; *");
    if ((!lname) || (!name))
        return syn;
    
    // create or parse the destination first
    if ((name[1]) == "$") {
        if (!(dest = (| lookup(tosym(substr(name, 2))) |)))
            return "Invalid object name.";
        if (!(dest.is($place)))
            return ("Destination " + (dest.namef('ref))) + " is not a place.";
    } else {
        if (!(name = (> $code_lib.parse_name(name) <)))
            return "Invalid name.";
        [parent, dest] = (> .build_parse_name((name[1])[1], $place) <);
        name = replace(name, 1, replace(name[1], 1, dest));
        catch any
            dest = (> parent.spawn() <);
        with
            return (traceback()[1])[2];
        .build_set_name(dest, @name);
        dest.set_realm(loc.realm());
        .tell(("Created new place " + (dest.namef('ref))) + ".");
        dnew = 1;
    }
    
    // now parse and attach the exits
    // first the leaving exit..
    if (!(name = (| $code_lib.parse_name(lname) |)))
        return ("Invalid exit name '" + lname) + "'";
    catch ~stop {
        leave = (> .build_generate_exit(name, loc, dest) <);
        (> .build_attach_exit(leave, loc, dest) <);
        .tell((("Attached exit " + (leave.name())) + " from ") + (loc.name()));
    } with {
        .tell((traceback()[1])[2]);
        return .build_cleanup([dest, dnew]);
    }
    
    // now the (optional) arrival exit
    if (aname) {
        if (!(name = (| $code_lib.parse_name(aname) |)))
            return ("Invalid exit name '" + cname) + "'";
        catch ~stop {
            arrive = (> .build_generate_exit(name, dest, loc) <);
            (> .build_attach_exit(arrive, dest, loc) <);
            .tell((("Attached exit " + (arrive.name())) + " from ") + (dest.name()));
        } with {
            .tell((traceback()[1])[2]);
    
            // thirty second leeway guess to if we created it or not
            // ... what I do to keep from wrapping
            dnew = dnew.or(((leave.created_on()) > (time() - 30)) ? 2 : 0);
            return .build_cleanup([dest, dnew.and(1)], [leave, dnew.and(2)]);
        }
    }
    
    // $#Edited: 19 Feb 97 02:23 $miro
};

public method .teleport_cmd() {
    arg cmdstr, com, dest;
    var loc, p;
    
    (> .perms(caller(), 'command) <);
    if (!dest) {
        .tell("Specify a destination.");
        return;
    }
    if (dest == "home")
        loc = .home();
    else
        loc = (| .match_environment(dest) |);
    
    // if we have still not found a location...
    if (!loc) {
        catch any {
            loc = $place_db.search(dest);
        } with {
            switch (error()) {
                case ~ambig:
                    .tell("Several rooms match that name: " + ((((traceback()[1])[3]).mmap('namef)).to_english()));
                case ~namenf:
                    .tell(("Unable to find place \"" + dest) + "\".");
                    return;
                default:
                    return (traceback()[1])[2];
            }
        }
    }
    if (!loc) {
        .tell(("Unable to find place \"" + dest) + "\".");
        return;
    }
    if (loc == (.location())) {
        .tell("You are already there!");
        return;
    }
    if (!(.teleport(loc)))
        .tell("Sorry.");
    
    // $#Moved 12 Feb 97 11:01 from $programmer.teleport_cmd() by $brandon
};

protected method .build_generate_exit() {
    arg pname, source, dest;
    var parent, exit, name;
    
    name = pname[1];
    [parent, exit] = (> .build_parse_name(name[1], $exit) <);
    name = replace(name, 1, exit);
    pname = replace(pname, 1, name);
    exit = (| source.match_environment(exit) |);
    if (exit) {
        if (exit.is($exit))
            throw(~stop, (((name[1]) + " is already an exit from ") + (source.name())) + ".");
        if (exit.source())
            throw(~stop, (exit.namef('ref)) + " is alread linked.");
        return exit;
    }
    catch any
        exit = (> parent.new() <);
    with
        throw(~stop, "Unable to create exit: " + ((traceback()[1])[2]));
    return .build_set_name(exit, @pname);
};

protected method .build_parse_name() {
    arg str, class;
    var m, parent, what;
    
    if ((m = regexp(str, "^ *\$([a-z0-9_]+) *: *(.*)$"))) {
        parent = m[1];
        what = m[2];
        if (parent) {
            catch ~namenf, ~symbol
                parent = (> lookup(tosym(parent)) <);
            with
                throw(~stop, ("The object '$" + parent) + "' is not valid.");
            if (!(parent.is(class)))
                throw(~stop, ((("Parent object " + parent) + " is not ") + ((class.objname()).add_indefinite())) + "!");
        }
    } else {
        what = str;
    }
    if (!parent)
        parent = $place_lib.get_default(class.objname());
    return [parent, what];
};

protected method .teleport() {
    arg dest;
    var m, source, vars;
    
    source = .location();
    if (!(| .move_to(dest) |))
        return 0;
    vars = #[["$actor", this()], ["actor", .name()], ["$source", source], ["source", source.name()], ["$dest", dest], ["dest", dest.name()]];
    m = .eval_message("teleport", $builder, vars);
    dest.announce(m);
    source.announce(m);
};

protected method .define_msg_cmd() {
    arg cmdstr, cmd, args;
    var what, opts, def, o, i, br, ref, compiler, defopts, eval;
    
    (> .perms(caller(), 'command) <);
    defopts = [["b?ranches", 1], ["c?ompiler", 1], ["e?valuator", 1]];
    [args, opts] = $parse_lib.getopt(args, defopts);
    args = join(args);
    what = split(args, " *: *");
    if (listlen(what) != 2)
        return "Invalid message reference " + args;
    [def, what] = what;
    what = what.trim();
    if (match_regexp(what, "[=.]"))
        return ("You cannot set the default with " + cmd) + ".";
    def = (> .match_env_nice(def) <);
    if (!(def.is_writable_by(this())))
        return ("You cannot define messages on " + (def.namef('ref))) + ".";
    if (type(def) == 'frob)
        return "You cannot define messages on a frob.";
    catch any {
        (> def.define_msg(what) <);
        ref = (def + ":") + what;
        .tell(("Message " + ref) + " defined.");
    } with {
        return (traceback()[1])[2];
    }
    o = opts.slice(1);
    if ((i = "b?ranches" in o)) {
        br = (((opts[i])[4]).trim()).split(" *, *");
        catch any {
            def.set_msg_attr(what, 'branches, br);
            .tell("Message branches defined:");
            for i in (br)
                .tell((("  " + ref) + ".") + i);
        } with {
            .tell((traceback()[1])[2]);
        }
    }
    if ((i = "e?valuator" in o)) {
        eval = (opts[i])[4];
        if (!eval) {
            .tell("No evaluator specified with +evaluator=??");
        } else {
            eval = (> .match_env_nice(eval) <);
            if (!(eval.is($evaluator)))
                return "Invalid evaluator object: " + evaluator;
            catch any {
                def.set_msg_attr(what, 'evaluator, eval);
                .tell((("Set evaluator for " + ref) + " to ") + eval);
            } with {
                .tell((traceback()[1])[2]);
            }
        }
    }
    if ((i = "c?ompiler" in o)) {
        compiler = (opts[i])[4];
        if (!compiler) {
            .tell("No compiler specified with +compiler=??");
        } else {
            compiler = (> .match_env_nice(compiler) <);
            if (!(compiler.is($compiler)))
                .tell("Invalid compiler object: " + compiler);
            catch any {
                def.set_msg_attr(what, 'compiler, compiler);
                .tell((("Set compiler for " + ref) + " to ") + compiler);
            } with {
                .tell((traceback()[1])[2]);
            }
        }
    }
};

protected method .undefine_msg_cmd() {
    arg cmdstr, cmd, args;
    var what, opts, def;
    
    (> .perms(caller(), 'command) <);
    
    // it niggles the string enough to 'clean' up little mistakes
    [args, opts] = $parse_lib.getopt(args, [["b?ranches", 1], ["c?ompiler", 1]]);
    args = join(args);
    what = split(args, " *: *");
    if (listlen(what) != 2)
        return "Invalid message reference " + args;
    [def, what] = what;
    what = what.trim();
    def = (> .match_env_nice(def) <);
    if (!(def.is_writable_by(this())))
        return ("You cannot define messages on " + (def.namef('ref))) + ".";
    catch any {
        (> def.undefine_msg(what) <);
        .tell(((("Message " + def) + ":") + what) + " undefined.");
    } with {
        return (traceback()[1])[2];
    }
};

public method .format_messages() {
    arg target, @what;
    var messages, out, b, branches, m;
    
    messages = target.all_msgs();
    out = [];
    for m in ((messages.keys()).sort()) {
        branches = messages[m];
        if (branches.contains("general")) {
            out += [("  " + m) + " = "].affix((branches["general"]).uncompile());
            branches = dict_del(branches, "general");
        }
        for b in ((branches.keys()).sort())
            out += [((("  " + m) + ".") + b) + " = "].affix((branches[b]).uncompile());
    }
    return out;
};


new object $programmer: $builder;

var $root inited = 1;
var $root owned = [$programmer];
var $root manager = $programmer;
var $root quota = 75000;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'command_cache, 'variables];
var $root managed = [$programmer];
var $location contents = [];
var $located location = $body_cave;
var $located obvious = 1;
var $user password = "*";
var $user connected_at = 0;
var $user last_command_at = 0;
var $user connections = [];
var $user modes = #[];
var $user formatter = $mail_list;
var $user parsers = [$command_parser];
var $user context = #[['last, $body_cave]];
var $user task_connections = #[];
var $programmer eval_prefix = 0;
var $programmer eval_tick_offset = 0;
var $programmer eval_offset = 0;
var $command_aliases command_aliases = [];
var $mail_list letters = #[];
var $mail_list letters_index = #[];
var $mail_list senders = 1;
var $mail_list readers = [];
var $mail_list notify = [$programmer];
var $mail_list last_letter = 0;
var $mail_list mail = [];
var $mail_ui subscribed = #[[$programmer, [791485891, 0]]];
var $mail_ui current = #[['location, 0], ['list, $programmer]];
var $described prose = [];
var $has_name name = ['prop, "Generic Programmer", "Generic Programmer"];
var $has_commands local = #[["@id", [["@id", "*", "@id <any>", 'id_cmd, #[[1, ['any, []]]]]]], ["@which", [["@which", "*", "@which <any>", 'which_cmd, #[[1, ['any, []]]]]]], ["@eval", [["@eval", "*", "@eval <any>", 'eval_cmd, #[[1, ['any, []]]]]]], ["@add-c?ommand|@ac", [["@add-c?ommand|@ac", "*", "@add-c?ommand|@ac <any>", 'add_command_cmd, #[[1, ['any, []]]]]]], ["@del-c?ommand|@dc", [["@del-c?ommand|@dc", "*", "@del-c?ommand|@dc <any>", 'del_command_cmd, #[[1, ['any, []]]]]]], ["@join", [["@join", "*", "@join <any>", 'join_cmd, #[[1, ['any, []]]]]]], ["@chpar?ents", [["@chpar?ents", "*", "@chpar?ents <any>", 'chparents_cmd, #[[1, ['any, []]]]]]], ["@add-s?hortcut|@as", [["@add-s?hortcut|@as", "*", "@add-s?hortcut|@as <any>", 'add_shortcut_cmd, #[[1, ['any, []]]]]]], ["@del-m?ethod|@delm?ethod|@dm", [["@del-m?ethod|@delm?ethod|@dm", "*", "@del-m?ethod|@delm?ethod|@dm <objref>", 'del_method_cmd, #[[1, ['objref, []]]]]]], ["@rehash", [["@rehash", "", "@rehash", 'rehash_cmd, #[]]]], ["@trace-method|@trace", [["@trace-method|@trace", "*", "@trace-method|@trace <objref>", 'trace_method_cmd, #[[1, ['objref, []]]]]]], ["@ledit", [["@ledit", "*", "@ledit <objref: +e?dited>", 'local_edit_cmd, #[[1, ['objref_opt, [["e?dited"]]]]]]]], ["@d?isplay", [["@d?isplay", "*", "@d?isplay <objref: +c?hop +g?enerations=1 +d?efiners=1>", 'display_cmd, #[[1, ['objref_opt, [["c?hop"], ["g?enerations", "1"], ["d?efiners", "1"]]]]]]]], ["@program", [["@program", "*", "@program <objref: +w?arnings +e?dited=1 +a?ccess=1 +f?lags=1>", 'program_cmd, #[[1, ['objref_opt, [["w?arnings"], ["e?dited", "1"], ["a?ccess", "1"], ["f?lags", "1"]]]]]], ["@program", "* with *", "@program <objref: +w?arnings +e?dited=1 +a?ccess=1 +f?lags=1> with <any>", 'program_cmd, #[[1, ['objref_opt, [["w?arnings"], ["e?dited", "1"], ["a?ccess", "1"], ["f?lags", "1"]]]], [3, ['any, []]]]]]], ["@del-v?ariable|@dv", [["@del-v?ariable|@dv", "*", "@del-v?ariable|@dv <objref>", 'del_var_cmd, #[[1, ['objref, []]]]]]], ["@show", [["@show", "*", "@show <objref: +c?hop>", 'show_cmd, #[[1, ['objref_opt, [["c?hop"]]]]]]]], ["@mv|@move|@cp|@copy", [["@mv|@move|@cp|@copy", "*", "@mv|@move|@cp|@copy <objref:+c?omment=1>", 'move_cmd, #[[1, ['objref_opt, [["c?omment", "1"]]]]]]]], ["@del-s?hortcut|@ds", [["@del-s?hortcut|@ds", "*", "@del-s?hortcut|@ds <any>", 'del_shortcut_cmd, #[[1, ['any, []]]]]]], ["@add-p?arent|@ap", [["@add-p?arent|@ap", "*", "@add-p?arent|@ap <any>", 'add_parent_cmd, #[[1, ['any, []]]]]]], ["@del-p?arent|@dp", [["@del-p?arent|@dp", "*", "@del-p?arent|@dp <any>", 'del_parent_cmd, #[[1, ['any, []]]]]]], ["@grep", [["@grep", "*", "@grep <any:+d?escend +f?ull +l?ist +r?eplace-with=1>", 'grep_cmd, #[[1, ['any_opt, [["d?escend"], ["f?ull"], ["l?ist"], ["r?eplace-with", "1"]]]]]]]], ["@chmod|@mmod|@omod|@chflag?s", [["@chmod|@mmod|@omod|@chflag?s", "*", "@chmod|@mmod|@omod|@chflag?s <any>", 'chmod_cmd, #[[1, ['any, []]]]]]], ["@dump", [["@dump", "*", "@dump <any: +t?extdump +m?ethods +v?ariables +h?eader>", 'dump_cmd, #[[1, ['any_opt, [["t?extdump"], ["m?ethods"], ["v?ariables"], ["h?eader"]]]]]]]], ["@list", [["@list", "*", "@list <objref: +n?umbers +t?extdump>", 'list_cmd, #[[1, ['objref_opt, [["n?umbers"], ["t?extdump"]]]]]]]], ["@add-v?ariable|@av", [["@add-v?ariable|@av", "*", "@add-v?ariable|@av <any>", 'add_var_cmd, #[[1, ['any, []]]]]]], ["@hl?ist|@help-list", [["@hl?ist|@help-list", "*", "@hl?ist|@help-list <any>", 'help_list_cmd, #[[1, ['any, []]]]]]], ["@hw?rite|@help-write", [["@hw?rite|@help-write", "*", "@hw?rite|@help-write <any>", 'help_write_cmd, #[[1, ['any, []]]]]]], ["@spawn", [["@spawn", "*", "@spawn <any>", 'spawn_cmd, #[[1, ['any, []]]]]]], ["@ancestors", [["@ancestors", "*", "@ancestors <any>", 'ancestors_cmd, #[[1, ['any, []]]]]]], ["@nh?n|@new-help|@new-help-node", [["@nh?n|@new-help|@new-help-node", "*", "@nh?n|@new-help|@new-help-node <any:+n?amed=1 +o?bjname=1 +i?ndex=1>", 'new_help_node_cmd, #[[1, ['any_opt, [["n?amed", "1"], ["o?bjname", "1"], ["i?ndex", "1"]]]]]]]], ["@config-set?ting|@configure-set?ting", [["@config-set?ting|@configure-set?ting", "*", "@config-set?ting|@configure-set?ting <any>", 'configure_setting_cmd, #[[1, ['any, []]]]]]], ["@def-set?ting|@define-set?ting", [["@def-set?ting|@define-set?ting", "*", "@def-set?ting|@define-set?ting <any>", 'define_setting_cmd, #[[1, ['any, []]]]]]], ["@undef-set?ting|@undefine-set?ting", [["@undef-set?ting|@undefine-set?ting", "*", "@undef-set?ting|@undefine-set?ting <any>", 'undefine_setting_cmd, #[[1, ['any, []]]]]]], ["@descend?ants", [["@descend?ants", "*", "@descend?ants <objref:+a?ll +r?edundant +o?nly +n?ot>", 'descendants_cmd, #[[1, ['objref_opt, [["a?ll"], ["r?edundant"], ["o?nly"], ["n?ot"]]]]]]]]];
var $has_commands shortcuts = #[[";*", ['eval_cmd, ["eval", 1]]]];
var $root child_index = 2;
var $channel_ui channel_dict = #[];
var $channel_ui active_channels = #[];
var $root defined_settings = #[["match-with", #[['parse, ['parse_match_with]]]], ["match-default", #[]], ["@program-options", #[]], ["@list-options", #[]]];
var $thing gender = $gender_neuter;
var $command_cache local_cache = #[["@id", ["@id"]], ["@which", ["@which"]], ["@eval", ["@eval"]], ["@add-c", ["@add-c?ommand|@ac"]], ["@add-co", ["@add-c?ommand|@ac"]], ["@add-com", ["@add-c?ommand|@ac"]], ["@add-comm", ["@add-c?ommand|@ac"]], ["@add-comma", ["@add-c?ommand|@ac"]], ["@add-comman", ["@add-c?ommand|@ac"]], ["@add-command", ["@add-c?ommand|@ac"]], ["@ac", ["@add-c?ommand|@ac", "@a?ction"]], ["@del-c", ["@del-c?ommand|@dc"]], ["@del-co", ["@del-c?ommand|@dc"]], ["@del-com", ["@del-c?ommand|@dc"]], ["@del-comm", ["@del-c?ommand|@dc"]], ["@del-comma", ["@del-c?ommand|@dc"]], ["@del-comman", ["@del-c?ommand|@dc"]], ["@del-command", ["@del-c?ommand|@dc"]], ["@dc", ["@del-c?ommand|@dc"]], ["@join", ["@join"]], ["@chpar", ["@chpar?ents"]], ["@chpare", ["@chpar?ents"]], ["@chparen", ["@chpar?ents"]], ["@chparent", ["@chpar?ents"]], ["@chparents", ["@chpar?ents"]], ["@add-s", ["@add-s?hortcut|@as"]], ["@add-sh", ["@add-s?hortcut|@as"]], ["@add-sho", ["@add-s?hortcut|@as"]], ["@add-shor", ["@add-s?hortcut|@as"]], ["@add-short", ["@add-s?hortcut|@as"]], ["@add-shortc", ["@add-s?hortcut|@as"]], ["@add-shortcu", ["@add-s?hortcut|@as"]], ["@add-shortcut", ["@add-s?hortcut|@as"]], ["@as", ["@add-s?hortcut|@as"]], ["@del-m", ["@del-m?ethod|@delm?ethod|@dm"]], ["@del-me", ["@del-m?ethod|@delm?ethod|@dm"]], ["@del-met", ["@del-m?ethod|@delm?ethod|@dm"]], ["@del-meth", ["@del-m?ethod|@delm?ethod|@dm"]], ["@del-metho", ["@del-m?ethod|@delm?ethod|@dm"]], ["@del-method", ["@del-m?ethod|@delm?ethod|@dm"]], ["@delm", ["@del-m?ethod|@delm?ethod|@dm"]], ["@delme", ["@del-m?ethod|@delm?ethod|@dm"]], ["@delmet", ["@del-m?ethod|@delm?ethod|@dm"]], ["@delmeth", ["@del-m?ethod|@delm?ethod|@dm"]], ["@delmetho", ["@del-m?ethod|@delm?ethod|@dm"]], ["@delmethod", ["@del-m?ethod|@delm?ethod|@dm"]], ["@dm", ["@del-m?ethod|@delm?ethod|@dm"]], ["@rehash", ["@rehash"]], ["@trace-method", ["@trace-method|@trace"]], ["@trace", ["@trace-method|@trace"]], ["@ledit", ["@ledit"]], ["@d", ["@d?isplay"]], ["@di", ["@d?isplay"]], ["@dis", ["@d?isplay"]], ["@disp", ["@d?isplay"]], ["@displ", ["@d?isplay"]], ["@displa", ["@d?isplay"]], ["@display", ["@d?isplay"]], ["@program", ["@program"]], ["@del-v", ["@del-v?ariable|@dv"]], ["@del-va", ["@del-v?ariable|@dv"]], ["@del-var", ["@del-v?ariable|@dv"]], ["@del-vari", ["@del-v?ariable|@dv"]], ["@del-varia", ["@del-v?ariable|@dv"]], ["@del-variab", ["@del-v?ariable|@dv"]], ["@del-variabl", ["@del-v?ariable|@dv"]], ["@del-variable", ["@del-v?ariable|@dv"]], ["@dv", ["@del-v?ariable|@dv"]], ["@show", ["@show"]], ["@mv", ["@mv|@move|@cp|@copy", "@mv|@move"]], ["@move", ["@mv|@move|@cp|@copy", "@mv|@move"]], ["@cp", ["@mv|@move|@cp|@copy"]], ["@copy", ["@mv|@move|@cp|@copy"]], ["@del-s", ["@del-s?hortcut|@ds"]], ["@del-sh", ["@del-s?hortcut|@ds"]], ["@del-sho", ["@del-s?hortcut|@ds"]], ["@del-shor", ["@del-s?hortcut|@ds"]], ["@del-short", ["@del-s?hortcut|@ds"]], ["@del-shortc", ["@del-s?hortcut|@ds"]], ["@del-shortcu", ["@del-s?hortcut|@ds"]], ["@del-shortcut", ["@del-s?hortcut|@ds"]], ["@ds", ["@del-s?hortcut|@ds"]], ["@add-p", ["@add-p?arent|@ap"]], ["@add-pa", ["@add-p?arent|@ap"]], ["@add-par", ["@add-p?arent|@ap"]], ["@add-pare", ["@add-p?arent|@ap"]], ["@add-paren", ["@add-p?arent|@ap"]], ["@add-parent", ["@add-p?arent|@ap"]], ["@ap", ["@add-p?arent|@ap"]], ["@del-p", ["@del-p?arent|@dp"]], ["@del-pa", ["@del-p?arent|@dp"]], ["@del-par", ["@del-p?arent|@dp"]], ["@del-pare", ["@del-p?arent|@dp"]], ["@del-paren", ["@del-p?arent|@dp"]], ["@del-parent", ["@del-p?arent|@dp"]], ["@dp", ["@del-p?arent|@dp"]], ["@grep", ["@grep"]], ["@chmod", ["@chmod|@mmod|@omod|@chflag?s"]], ["@mmod", ["@chmod|@mmod|@omod|@chflag?s"]], ["@omod", ["@chmod|@mmod|@omod|@chflag?s"]], ["@chflag", ["@chmod|@mmod|@omod|@chflag?s"]], ["@chflags", ["@chmod|@mmod|@omod|@chflag?s"]], ["@dump", ["@dump"]], ["@list", ["@list"]], ["@add-v", ["@add-v?ariable|@av"]], ["@add-va", ["@add-v?ariable|@av"]], ["@add-var", ["@add-v?ariable|@av"]], ["@add-vari", ["@add-v?ariable|@av"]], ["@add-varia", ["@add-v?ariable|@av"]], ["@add-variab", ["@add-v?ariable|@av"]], ["@add-variabl", ["@add-v?ariable|@av"]], ["@add-variable", ["@add-v?ariable|@av"]], ["@av", ["@add-v?ariable|@av"]], ["@hl", ["@hl?ist|@help-list"]], ["@hli", ["@hl?ist|@help-list"]], ["@hlis", ["@hl?ist|@help-list"]], ["@hlist", ["@hl?ist|@help-list"]], ["@help-list", ["@hl?ist|@help-list"]], ["@hw", ["@hw?rite|@help-write"]], ["@hwr", ["@hw?rite|@help-write"]], ["@hwri", ["@hw?rite|@help-write"]], ["@hwrit", ["@hw?rite|@help-write"]], ["@hwrite", ["@hw?rite|@help-write"]], ["@help-write", ["@hw?rite|@help-write"]], ["@spawn", ["@spawn"]], ["@ancestors", ["@ancestors"]], ["@nh", ["@nh?n|@new-help|@new-help-node"]], ["@nhn", ["@nh?n|@new-help|@new-help-node"]], ["@new-help", ["@nh?n|@new-help|@new-help-node"]], ["@new-help-node", ["@nh?n|@new-help|@new-help-node"]], ["@config-set", ["@config-set?ting|@configure-set?ting"]], ["@config-sett", ["@config-set?ting|@configure-set?ting"]], ["@config-setti", ["@config-set?ting|@configure-set?ting"]], ["@config-settin", ["@config-set?ting|@configure-set?ting"]], ["@config-setting", ["@config-set?ting|@configure-set?ting"]], ["@configure-set", ["@config-set?ting|@configure-set?ting"]], ["@configure-sett", ["@config-set?ting|@configure-set?ting"]], ["@configure-setti", ["@config-set?ting|@configure-set?ting"]], ["@configure-settin", ["@config-set?ting|@configure-set?ting"]], ["@configure-setting", ["@config-set?ting|@configure-set?ting"]], ["@def-set", ["@def-set?ting|@define-set?ting"]], ["@def-sett", ["@def-set?ting|@define-set?ting"]], ["@def-setti", ["@def-set?ting|@define-set?ting"]], ["@def-settin", ["@def-set?ting|@define-set?ting"]], ["@def-setting", ["@def-set?ting|@define-set?ting"]], ["@define-set", ["@def-set?ting|@define-set?ting"]], ["@define-sett", ["@def-set?ting|@define-set?ting"]], ["@define-setti", ["@def-set?ting|@define-set?ting"]], ["@define-settin", ["@def-set?ting|@define-set?ting"]], ["@define-setting", ["@def-set?ting|@define-set?ting"]], ["@undef-set", ["@undef-set?ting|@undefine-set?ting"]], ["@undef-sett", ["@undef-set?ting|@undefine-set?ting"]], ["@undef-setti", ["@undef-set?ting|@undefine-set?ting"]], ["@undef-settin", ["@undef-set?ting|@undefine-set?ting"]], ["@undef-setting", ["@undef-set?ting|@undefine-set?ting"]], ["@undefine-set", ["@undef-set?ting|@undefine-set?ting"]], ["@undefine-sett", ["@undef-set?ting|@undefine-set?ting"]], ["@undefine-setti", ["@undef-set?ting|@undefine-set?ting"]], ["@undefine-settin", ["@undef-set?ting|@undefine-set?ting"]], ["@undefine-setting", ["@undef-set?ting|@undefine-set?ting"]], ["@descend", ["@descend?ants"]], ["@descenda", ["@descend?ants"]], ["@descendan", ["@descend?ants"]], ["@descendant", ["@descend?ants"]], ["@descendants", ["@descend?ants"]], ["@realm", ["@realm?s"]], ["@realms", ["@realm?s"]], ["@child", ["@child?ren|@kids"]], ["@childr", ["@child?ren|@kids"]], ["@childre", ["@child?ren|@kids"]], ["@children", ["@child?ren|@kids"]], ["@kids", ["@child?ren|@kids"]], ["@par", ["@par?ents"]], ["@pare", ["@par?ents"]], ["@paren", ["@par?ents"]], ["@parent", ["@par?ents"]], ["@parents", ["@par?ents"]], ["@build", ["@build"]], ["@attach", ["@attach"]], ["@destroy", ["@destroy"]], ["@dig", ["@dig"]], ["@teleport", ["@teleport|@go"]], ["@go", ["@teleport|@go"]], ["@def-msg", ["@def-msg|@def-message"]], ["@def-message", ["@def-msg|@def-message"]], ["@undef-msg", ["@undef-msg|@undef-message"]], ["@undef-message", ["@undef-msg|@undef-message"]], ["@quit", ["@quit"]], ["i", ["i?nventory"]], ["in", ["i?nventory"]], ["inv", ["i?nventory"]], ["inve", ["i?nventory"]], ["inven", ["i?nventory"]], ["invent", ["i?nventory"]], ["invento", ["i?nventory"]], ["inventor", ["i?nventory"]], ["inventory", ["i?nventory"]], ["@audit", ["@audit"]], ["@who", ["@who"]], ["@del-command-a", ["@del-command-a?lias|@dca?lias"]], ["@del-command-al", ["@del-command-a?lias|@dca?lias"]], ["@del-command-ali", ["@del-command-a?lias|@dca?lias"]], ["@del-command-alia", ["@del-command-a?lias|@dca?lias"]], ["@del-command-alias", ["@del-command-a?lias|@dca?lias"]], ["@dca", ["@del-command-a?lias|@dca?lias"]], ["@dcal", ["@del-command-a?lias|@dca?lias"]], ["@dcali", ["@del-command-a?lias|@dca?lias"]], ["@dcalia", ["@del-command-a?lias|@dca?lias"]], ["@dcalias", ["@del-command-a?lias|@dca?lias"]], ["@command-a", ["@command-a?liases|@ca?liases"]], ["@command-al", ["@command-a?liases|@ca?liases"]], ["@command-ali", ["@command-a?liases|@ca?liases"]], ["@command-alia", ["@command-a?liases|@ca?liases"]], ["@command-alias", ["@command-a?liases|@ca?liases"]], ["@command-aliase", ["@command-a?liases|@ca?liases"]], ["@command-aliases", ["@command-a?liases|@ca?liases"]], ["@ca", ["@command-a?liases|@ca?liases"]], ["@cal", ["@command-a?liases|@ca?liases"]], ["@cali", ["@command-a?liases|@ca?liases"]], ["@calia", ["@command-a?liases|@ca?liases"]], ["@calias", ["@command-a?liases|@ca?liases"]], ["@caliase", ["@command-a?liases|@ca?liases"]], ["@caliases", ["@command-a?liases|@ca?liases"]], ["@add-command-a", ["@add-command-a?lias|@aca?lias"]], ["@add-command-al", ["@add-command-a?lias|@aca?lias"]], ["@add-command-ali", ["@add-command-a?lias|@aca?lias"]], ["@add-command-alia", ["@add-command-a?lias|@aca?lias"]], ["@add-command-alias", ["@add-command-a?lias|@aca?lias"]], ["@aca", ["@add-command-a?lias|@aca?lias"]], ["@acal", ["@add-command-a?lias|@aca?lias"]], ["@acali", ["@add-command-a?lias|@aca?lias"]], ["@acalia", ["@add-command-a?lias|@aca?lias"]], ["@acalias", ["@add-command-a?lias|@aca?lias"]], ["@com", ["@com?mands"]], ["@comm", ["@com?mands"]], ["@comma", ["@com?mands"]], ["@comman", ["@com?mands"]], ["@command", ["@com?mands"]], ["@commands", ["@com?mands"]], ["@news", ["@news"]], ["@forget", ["@forget"]], ["@whereis", ["@whereis|@where-is"]], ["@where-is", ["@whereis|@where-is"]], ["@ways", ["@ways"]], ["@password", ["@password|@passwd"]], ["@passwd", ["@password|@passwd"]], ["@age", ["@age"]], ["@context", ["@context"]], ["get", ["get|take"]], ["take", ["get|take"]], ["drop", ["drop"]], ["@rename", ["@rename"]], ["@add-writer", ["@add-writer|@aw"]], ["@aw", ["@add-writer|@aw"]], ["@del-writer", ["@del-writer|@dw"]], ["@dw", ["@del-writer|@dw"]], ["@chman", ["@chman?age"]], ["@chmana", ["@chman?age"]], ["@chmanag", ["@chman?age"]], ["@chmanage", ["@chman?age"]], ["@manage", ["@manage?d"]], ["@managed", ["@manage?d"]], ["@remember", ["@remember"]], ["@remembered", ["@remembered"]], ["give", ["give|put"]], ["put", ["give|put"]], ["discard", ["discard"]], ["@writes", ["@writes"]], ["@trusted", ["@trusted?-by"]], ["@trusted-", ["@trusted?-by"]], ["@trusted-b", ["@trusted?-by"]], ["@trusted-by", ["@trusted?-by"]], ["@add-trust", ["@add-trust?ee|@at"]], ["@add-truste", ["@add-trust?ee|@at"]], ["@add-trustee", ["@add-trust?ee|@at"]], ["@at", ["@add-trust?ee|@at"]], ["@del-trust", ["@del-trust?ee|@dt"]], ["@del-truste", ["@del-trust?ee|@dt"]], ["@del-trustee", ["@del-trust?ee|@dt"]], ["@dt", ["@del-trust?ee|@dt"]], ["@monitor", ["@monitor"]], ["@ex", ["@ex?amine"]], ["@exa", ["@ex?amine"]], ["@exam", ["@ex?amine"]], ["@exami", ["@ex?amine"]], ["@examin", ["@ex?amine"]], ["@examine", ["@ex?amine"]], ["@map", ["@map"]], ["@finger", ["@finger|@ustat"]], ["@ustat", ["@finger|@ustat"]], ["@trusts", ["@trusts|@trustee?s"]], ["@trustee", ["@trusts|@trustee?s"]], ["@trustees", ["@trusts|@trustee?s"]], ["@writers", ["@writers"]], ["@manager", ["@manager"]], ["view", ["view"]], ["@desc", ["@desc?ribe|@prose"]], ["@descr", ["@desc?ribe|@prose"]], ["@descri", ["@desc?ribe|@prose"]], ["@describ", ["@desc?ribe|@prose"]], ["@describe", ["@desc?ribe|@prose"]], ["@prose", ["@desc?ribe|@prose"]], ["l", ["l?ook|exam?ine"]], ["lo", ["l?ook|exam?ine"]], ["loo", ["l?ook|exam?ine"]], ["look", ["l?ook|exam?ine"]], ["exam", ["l?ook|exam?ine"]], ["exami", ["l?ook|exam?ine"]], ["examin", ["l?ook|exam?ine"]], ["examine", ["l?ook|exam?ine"]], ["walk", ["walk|go"]], ["go", ["walk|go"]], ["@ant", ["@ant|@add-name-template"]], ["@add-name-template", ["@ant|@add-name-template"]], ["@dnt", ["@dnt|@del-name-template"]], ["@del-name-template", ["@dnt|@del-name-template"]], ["@name-template", ["@name-template?s|@template?s"]], ["@name-templates", ["@name-template?s|@template?s"]], ["@template", ["@name-template?s|@template?s"]], ["@templates", ["@name-template?s|@template?s"]], ["@register", ["@register|@register-name"]], ["@register-name", ["@register|@register-name"]], ["@unregister", ["@unregister|@unregister-name"]], ["@unregister-name", ["@unregister|@unregister-name"]], ["@registered", ["@registered"]], ["@page", ["@page"]], ["@paste", ["@paste?-to"]], ["@paste-", ["@paste?-to"]], ["@paste-t", ["@paste?-to"]], ["@paste-to", ["@paste?-to"]], ["@new", ["@new"]], ["@status", ["@status|@uptime"]], ["@uptime", ["@status|@uptime"]], ["@msg", ["@msg?s|@message?s"]], ["@msgs", ["@msg?s|@message?s"]], ["@message", ["@msg?s|@message?s"]], ["@messages", ["@msg?s|@message?s"]], ["@date", ["@date|@time"]], ["@time", ["@date|@time"]], ["@set", ["@set"]], ["wh", ["wh?isper"]], ["whi", ["wh?isper"]], ["whis", ["wh?isper"]], ["whisp", ["wh?isper"]], ["whispe", ["wh?isper"]], ["whisper", ["wh?isper"]], ["say", ["say"]], ["to", ["to"]], ["emote", ["emote"]], ["quote", ["quote"]], ["spoof", ["spoof"]], ["pose", ["pose"]], ["think", ["think"]], ["wear", ["wear"]], ["remove", ["remove|shed"]], ["shed", ["remove|shed"]], ["@a", ["@a?ction"]], ["@act", ["@a?ction"]], ["@acti", ["@a?ction"]], ["@actio", ["@a?ction"]], ["@action", ["@a?ction"]], ["@sub", ["@sub?scribed"]], ["@subs", ["@sub?scribed"]], ["@subsc", ["@sub?scribed"]], ["@subscr", ["@sub?scribed"]], ["@subscri", ["@sub?scribed"]], ["@subscrib", ["@sub?scribed"]], ["@subscribe", ["@sub?scribed"]], ["@subscribed", ["@sub?scribed"]], ["@unsub", ["@unsub?scribed"]], ["@unsubs", ["@unsub?scribed"]], ["@unsubsc", ["@unsub?scribed"]], ["@unsubscr", ["@unsub?scribed"]], ["@unsubscri", ["@unsub?scribed"]], ["@unsubscrib", ["@unsub?scribed"]], ["@unsubscribe", ["@unsub?scribed"]], ["@unsubscribed", ["@unsub?scribed"]], ["@mail-list", ["@mail-list?s"]], ["@mail-lists", ["@mail-list?s"]], ["@read", ["@read"]], ["@remove-m", ["@remove-m?ail|@rmm?ail"]], ["@remove-ma", ["@remove-m?ail|@rmm?ail"]], ["@remove-mai", ["@remove-m?ail|@rmm?ail"]], ["@remove-mail", ["@remove-m?ail|@rmm?ail"]], ["@rmm", ["@remove-m?ail|@rmm?ail"]], ["@rmma", ["@remove-m?ail|@rmm?ail"]], ["@rmmai", ["@remove-m?ail|@rmm?ail"]], ["@rmmail", ["@remove-m?ail|@rmm?ail"]], ["@nn", ["@nn|@next-new"]], ["@next-new", ["@nn|@next-new"]], ["@mail", ["@mail"]], ["@send", ["@send"]], ["@create", ["@create"]], ["help", ["help"]], ["page", ["page"]], ["who", ["who"]], ["quit", ["quit"]], ["news", ["news"]], ["@gender", ["@gender"]], ["uptime", ["uptime"]], ["@alias", ["@alias"]], ["@check", ["@check|@paranoid"]], ["@paranoid", ["@check|@paranoid"]], ["@version", ["@version"]], ["@lock", ["@lock"]], ["@unlock", ["@unlock"]], ["@help", ["@help"]], ["@mcp-upload-session", ["@mcp-upload-session"]], ["@cleanup-sessions", ["@cleanup-sessions|@c-s?essions"]], ["@c-s", ["@cleanup-sessions|@c-s?essions"]], ["@c-se", ["@cleanup-sessions|@c-s?essions"]], ["@c-ses", ["@cleanup-sessions|@c-s?essions"]], ["@c-sess", ["@cleanup-sessions|@c-s?essions"]], ["@c-sessi", ["@cleanup-sessions|@c-s?essions"]], ["@c-sessio", ["@cleanup-sessions|@c-s?essions"]], ["@c-session", ["@cleanup-sessions|@c-s?essions"]], ["@c-sessions", ["@cleanup-sessions|@c-s?essions"]], ["@edit", ["@edit"]], ["@desc-c", ["@desc-c?hannel"]], ["@desc-ch", ["@desc-c?hannel"]], ["@desc-cha", ["@desc-c?hannel"]], ["@desc-chan", ["@desc-c?hannel"]], ["@desc-chann", ["@desc-c?hannel"]], ["@desc-channe", ["@desc-c?hannel"]], ["@desc-channel", ["@desc-c?hannel"]], ["@ch", ["@ch?annels"]], ["@cha", ["@ch?annels"]], ["@chan", ["@ch?annels"]], ["@chann", ["@ch?annels"]], ["@channe", ["@ch?annels"]], ["@channel", ["@ch?annels"]], ["@channels", ["@ch?annels"]], ["@join-lock-channel", ["@join-lock-channel|@jlc"]], ["@jlc", ["@join-lock-channel|@jlc"]], ["@leave-lock-channel", ["@leave-lock-channel|@llc"]], ["@llc", ["@leave-lock-channel|@llc"]], ["@use-lock-channel", ["@use-lock-channel|@ulc"]], ["@ulc", ["@use-lock-channel|@ulc"]], ["@add-channel-manager", ["@add-channel-manager|@acm"]], ["@acm", ["@add-channel-manager|@acm"]], ["@del-channel-manager", ["@del-channel-manager|@dcm"]], ["@dcm", ["@del-channel-manager|@dcm"]], ["@add-ch", ["@add-ch?annel|@addcom"]], ["@add-cha", ["@add-ch?annel|@addcom"]], ["@add-chan", ["@add-ch?annel|@addcom"]], ["@add-chann", ["@add-ch?annel|@addcom"]], ["@add-channe", ["@add-ch?annel|@addcom"]], ["@add-channel", ["@add-ch?annel|@addcom"]], ["@addcom", ["@add-ch?annel|@addcom"]], ["@del-ch", ["@del-ch?annel|@delcom"]], ["@del-cha", ["@del-ch?annel|@delcom"]], ["@del-chan", ["@del-ch?annel|@delcom"]], ["@del-chann", ["@del-ch?annel|@delcom"]], ["@del-channe", ["@del-ch?annel|@delcom"]], ["@del-channel", ["@del-ch?annel|@delcom"]], ["@delcom", ["@del-ch?annel|@delcom"]], ["@purge-channel", ["@purge-channel"]], ["@blahblahblah", ["@blahblahblah"]]];
var $command_cache shortcut_cache = [[";*", ['eval_cmd, ["eval", 1]]], ["--*", ['remote_cmd, ["@page ", "", " with ", 1]]], ["-* *", ['remote_cmd, ["@page ", 1, " with ", 2]]], ["|*", ['quote_cmd, ["quote ", 1]]], ["\"*", ['say_cmd, ["say ", 1]]], ["%*", ['think_cmd, ["think ", 1]]], ["!*", ['spoof_cmd, ["spoof ", 1]]], [",*,*", ['esay_cmd, ["esay ", 1, " with ", 2]]], [":*", ['emote_cmd, ["emote ", 1]]], [".*", ['pose_cmd, ["pose ", 1]]], ["''*", ['to_say_cmd, ["to ", "", " say ", 1]]], ["'* *", ['to_say_cmd, ["to ", 1, " say ", 2]]], ["?*", ['help_cmd, ["?", 1]]]];
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 1]]]]];
var $root settings = #[["match-default", "*"], ["home", $body_cave], ["@list-options", ""], ["@program-options", ""], ["match-with", 'match_pattern], ["extended-parsers", []]];

protected method .eval_cmd() {
    arg cmdstr, com, str;
    var result, adjust, vars, v, evalp, times, line, reg, obj, definer, ref, debug;
    
    (> .perms(caller(), 'command) <);
    evalp = .eval_prefix();
    vars = (evalp.keys()).join(", ");
    v = (evalp.values()).join();
    
    // clean it up
    str = strsed(str, "^;*", "");
    
    // perform escape substitution
    if (str && ((str[1]) == "|"))
        str = substr(str, 2);
    else
        str = .eval_subs(str);
    
    // check for debug flags
    if ((reg = regexp(str, "^(trace|debug|profile) *;*(.*)$"))) {
        [debug, str] = reg;
        debug = #[["trace", 'trace], ["debug", 'debug], ["profile", 'profile]][debug];
    } else {
        debug = 0;
    }
    
    // who are we evaluating as
    if ((reg = regexp(str, "^ *as +([^; ]+)"))) {
        ref = $parse_lib.ref(reg[1]);
        obj = ref[2];
        definer = ref[3];
        str = strsed(str, "^ *as +([^; ]+)[ ;]+", "");
        if ((!(definer.is_writable_by(this()))) || (!(obj.is_writable_by(this()))))
            return ("You do not have permission to evaluate on " + (reg[1])) + ".";
    } else {
        obj = (definer = this());
    }
    
    // are we just adjusting our offset?
    if (!str) {
        result = (> .evaluate(((("var " + vars) + ";") + v) + "return (> 1 <);", obj, definer, 'no_offset) <);
        result = replace(result[1], 1, ((result[1])[1]) - 1);
        if (eval_offset)
            line = strfmt("adjusted by %s ticks and %s.%6{0}r seconds.", (eval_offset[1]) - (result[1]), (eval_offset[2]) - (result[2]), abs((eval_offset[3]) - (result[3])));
        else
            line = strfmt("set to %s ticks and %s.%6{0}r seconds.", @result);
        eval_offset = result;
        return "Eval offset " + line;
    }
    
    // format it, use heuristics
    if (match_begin(str, "var") && (reg = regexp(str, "var ([^;]+)"))) {
        str = strsed(str, "var ([^;]+);", "");
        str = ((((("var " + vars) + ", ") + (reg.join(","))) + ";") + v) + str;
    } else if ("return" in str) {
        str = ((("var " + vars) + ";") + v) + str;
    } else {
        str = strsed(str, " *;* *$", "");
        str = ((((("var " + vars) + ";") + v) + "return (> ") + str) + " <);";
    }
    if (debug)
        [times, result, debug] = (> .evaluate(str, obj, definer, debug) <);
    else
        [times, result] = (> .evaluate(str, obj, definer) <);
    
    // Display the errors, or the result.
    if ((result[1]) == 'errors) {
        .tell(result[2]);
    } else {
        if (type(result[2]) == 'objnum)
            .tell("=> " + ((| (result[2]).namef('xref) |) || (result[2])));
        else
            .tell("=> " + toliteral(result[2]));
        if (debug)
            .tell(debug);
        line = strfmt("[ seconds: %l.%6{0}r; operations: %s", times[2], times[3], times[1]);
        if (times[2])
            line += (" (" + ((times[1]) / (times[2]))) + " ticks per second)";
        return line + " ]";
    }
    
    // $#Edited: 17 Dec 96 15:11 $miro
};

protected method .program_cmd() {
    arg cmdstr, com, args, @more;
    var ref, o, i, ops, ign, ed, fl, meth, ex, acc, warn, errs, code, line, errs, code;
    
    (> .perms(caller(), 'command) <);
    ops = args[3];
    ref = args[1];
    
    // verify what we have is correct
    if (!(meth = (| tosym(ref[4]) |))) {
        ign++;
        .tell(("The method name '" + (((ref[4]) == 0) ? "" : (ref[4]))) + "' is not acceptable.");
    }
    if ((!ign) && ((ref[3]) && (!((ref[3]).is_writable_by(this()))))) {
        ign++;
        .tell(("You cannot program on " + ((ref[3]).namef('ref))) + ".");
    }
    if ((!ign) && ((| (ref[3]).find_method(meth) |) == (ref[3])))
        ex++;
    
    // ok, go on with options
    o = ops.slice(1);
    if ((i = "e?dited" in o)) {
        if (!((ops[i])[3])) {
            if (!($sys.is_admin(this()))) {
                ign++;
                .tell("Only admins can shut off edited comments.");
            }
        } else {
            ed = 1;
        }
    } else {
        ed = 1;
    }
    if (ed) {
        ed = (("// $#Edited: " + ($time.format("%d %h %y %H:%M"))) + " ") + this();
        if (i && ((ops[i])[4]))
            ed += ": " + ((ops[i])[4]);
    }
    if ((i = "f?lags" in o))
        fl = $parse_lib.parse_method_flags((ops[i])[4]);
    else if (ex)
        fl = (ref[3]).method_flags(meth);
    else
        fl = [];
    if ((i = "a?ccess" in o))
        acc = $parse_lib.parse_method_access((ops[i])[4]);
    else if (ex)
        acc = (ref[3]).method_access(meth);
    else
        acc = 'public;
    if ((i = "w?arnings" in o))
        warn = (ops[i])[4];
    else
        warn = 1;
    
    // now get on with it already
    if (ign)
        line = "Ignoring input until \".\" or \"@abort\"";
    else if (ex)
        line = ((((("Reprogramming " + acc) + " method ") + (ref[3])) + ".") + meth) + "()";
    else
        line = ((((("Programming " + acc) + " method ") + (ref[3])) + ".") + meth) + "()";
    if (fl)
        line += (" [" + (fl.to_english())) + "]";
    code = more ? more.subrange(2) : (.read(("-- " + line) + " --"));
    if (type(code) == 'symbol) {
        switch (code) {
            case 'aborted:
                return;
            case 'engaged:
                return "Sorry, you are already reading on this connection.";
            default:
                return "Unknown response from the read parser: " + code;
        }
    }
    if (ign)
        return "Finished ignoring input.";
    if (ed)
        code += [ed];
    catch any {
        if ((errs = (ref[3]).add_method(code, meth)))
            return errs;
        (> (ref[3]).set_method_flags(meth, fl) <);
        (> (ref[3]).set_method_access(meth, acc) <);
        if ((line = (> $code_lib.verify_code(code, meth, warn) <)))
            .tell(line);
        return ((((("Method " + (ref[3])) + ".") + meth) + "() ") + (ex ? "re" : "")) + "compiled";
    } with {
        return (traceback()[1])[2];
    }
    
    // $#Edited: 29 Nov 96 14:31 $brandon
};

protected method .show_cmd() {
    arg cmdstr, com, args;
    var show, match, i, chop, f, obj, out;
    
    (> .perms(caller(), 'command) <);
    if (((args[1])[1]) == 'object)
        show = ['method, 'variable];
    else if ((args[1])[5])
        show = [(args[1])[1], (args[1])[5]];
    else
        show = [(args[1])[1]];
    if ((i = "c?hop" in ((args[3]).slice(1))))
        chop = ((args[3])[i])[3];
    else
        chop = 1;
    if ((args[1])[4])
        f = (args[1])[4];
    else
        f = .get_setting("match-default", $programmer);
    match = .get_setting("match-with", $programmer);
    obj = (args[1])[3];
    .tell([((("Object:  " + obj) + " [") + ((obj.size()).to_english())) + " bytes]", "Parents: " + ((obj.parents()).join(", "))]);
    if ('method in show) {
        if (!(obj.has_flag('methods, this())))
            .tell("  ** No permission to list methods **");
        else
            .tell(._show_methods(obj, f, match, chop));
    }
    if ('variable in show) {
        if (!(obj.has_flag('variables, this())))
            .tell("  ** No permission to show variables **");
        else
            .tell(._show_variables(obj, f, match, chop));
    }
};

protected method ._move_method() {
    arg remove, fobj, fname, tobj, tname, comment;
    var code, line, result;
    
    if ((fobj == tobj) && remove) {
        if ((| tobj.find_method(tname) |) == tobj)
            tobj.del_method(tname);
        return (> fobj.rename_method(fname, tname) <);
    }
    code = (> fobj.list_method(fname) <);
    if (comment) {
        line = (((((((("// $#" + (remove ? "Moved" : "Copied")) + " ") + ($time.format("%d %h %y %H:%M"))) + " from ") + fobj) + ".") + fname) + "() by ") + this();
        if (type(comment) == 'string)
            line += ": " + comment;
        code += [line];
    }
    if ((> tobj.add_method(code, tname) <))
        throw(~compile, "Error encountered upon moving method!");
    if (remove)
        (> fobj.del_method(fname) <);
};

protected method .del_method_cmd() {
    arg cmdstr, cmd, objref;
    var name, obj;
    
    (> .perms(caller(), 'command) <);
    if (!(objref[4]))
        return .tell(("No method specified to delete from " + (objref[3])) + ".");
    if (!(| (name = tosym(objref[4])) |))
        return .tell(("Invalid method name \"" + (objref[4])) + "\".");
    catch any {
        (> (objref[3]).del_method(name) <);
        .tell(((("Method " + (objref[3])) + ".") + name) + "() deleted.");
    } with {
        if (error() == ~methodnf)
            .tell(((("Method " + (objref[3])) + ".") + name) + "() does not exist.");
        else
            .tell((traceback()[1])[2]);
    }
};

protected method .move_cmd() {
    arg cmdstr, cmd, args;
    var src, dest, comment, i, how;
    
    (> .perms(caller(), 'command) <);
    
    // is this actually @copy|@cp?
    how = match_begin(cmd, "@c") ? 'copy : 'move;
    
    // drop back to $builder.move_cmd if it is just an object
    if (((args[1])[1]) == 'object) {
        if (how == 'copy)
            return "You cannot copy objects!";
        return (> pass(cmdstr, cmd, [(args[1])[2], args[2], args[3]]) <);
    }
    
    // options
    if ((i = "c?omment" in ((args[3]).slice(1))))
        comment = (((args[3])[i])[4]) || (((args[3])[i])[3]);
    else
        comment = 1;
    
    // move|copy a method or var
    src = args[1];
    args = args[2];
    if ((args[1]) == "to")
        args = delete(args, 1);
    if (!args)
        return ((("You have to " + how) + " ") + (what.namef('ref))) + " somewhere.";
    catch ~objnf
        dest = (> $parse_lib.ref(args.join()) <);
    with
        return (traceback()[1])[2];
    if ((dest[1]) == 'object)
        dest = [src[1], dest[2], dest[3], src[4], 0];
    if ((src[1]) != (dest[1]))
        return ((((("You cannot " + how) + " a ") + (src[1])) + " to a ") + (dest[1])) + ".";
    if (!(src[4]))
        return ("Invalid " + (src[1])) + " reference, no name specified.";
    if (!(dest[4]))
        dest = replace(dest, 4, src[4]);
    if (((src[3]) == (dest[3])) && ((src[4]) == (dest[4])))
        return ((("Why do you want to " + how) + " the ") + (src[1])) + " to itself?";
    catch ~symbol {
        src = replace(src, 4, (> tosym(src[4]) <));
        dest = replace(dest, 4, (> tosym(dest[4]) <));
    } with {
        return ("You cannot specify wildcards in the " + (src[1])) + " name.";
    }
    if ((how == 'move) && (!((src[3]).is_writable_by(this()))))
        return ("You do not have permission to move from " + (src[3])) + ".";
    if (!((dest[3]).is_writable_by(this())))
        return ((("You do not have permission to " + how) + " to ") + (src[3])) + ".";
    catch any
        (> .(tosym("_move_" + (src[1])))(how == 'move, src[3], src[4], dest[3], dest[4], comment) <);
    with
        return (traceback()[1])[2];
    return ((((("You " + how) + " ") + ($parse_lib.buildref(@src))) + " to ") + ($parse_lib.buildref(@dest))) + ".";
    
    // $#Edited: 18 Jul 96 14:56 $levi
};

protected method .list_cmd() {
    arg cmdstr, cmd, args;
    var i, pattern, ref, methods, s, def, method, opts, str, m, d, out, type;
    
    (> .perms(caller(), 'command) <);
    if ((opts = .get_setting("@list-options", $programmer))) {
        opts = $parse_lib.getopt(opts, [["n?umbers"], ["t?extdump"]]);
        opts = union(args[3], opts[2]);
    } else {
        opts = args[3];
    }
    if ((i = (| "n?umbers" in (opts.slice(1)) |)) && ((opts[i])[3]))
        type = 'numbered;
    else if ((i = (| "t?extdump" in (opts.slice(1)) |)) && ((opts[i])[3]))
        type = 'textdump;
    else
        type = 'normal;
    ref = args[1];
    if ((ref[1]) == 'variable)
        return ((("The reference " + (ref[3])) + ",") + ((ref[4]) || "")) + " is not for a method.";
    if ((ref[1]) == 'object)
        return ("The reference " + (ref[3])) + " is not for a method.";
    def = (| (ref[2]).find_method(tosym(ref[4])) |);
    if (def) {
        pattern = ref[4];
        methods = [tosym(ref[4])];
    } else {
        if (ref[4])
            pattern = ref[4];
        else
            pattern = .get_setting("match-default", $programmer);
        def = ref[3];
        m = .get_setting("match-with", $programmer);
        methods = [];
        for method in (def.methods()) {
            if (tostr(method).(m)(pattern))
                methods += [method];
        }
        if (!methods)
            return .tell((("No method found matching " + def) + ".") + pattern);
    }
    cmd = .get_setting("@program-options", $programmer);
    out = [];
    for method in (methods)
        out += .format_method(def, method, type, cmd);
    return out;
};

protected method .id_cmd() {
    arg cmdstr, cmd, obj;
    
    (> .perms(caller(), 'command) <);
    obj = .match_env_nice(obj);
    .tell((((((((obj.namef('xref)) + " ") + ($object_lib.see_perms(obj))) + " ") + toliteral(obj.parents())) + " ") + tostr(obj.size())) + " bytes");
};

protected method .dump_cmd() {
    arg cmdstr, cmd, args;
    var opts, objs, o, i, tdfmt, meths, vars, header;
    
    (> .perms(caller(), 'command) <);
    opts = args[2];
    args = args[1];
    o = opts.slice(1);
    (i = "t?extdump" in o) && (tdfmt = (opts[i])[3]);
    (i = "m?ethods" in o) ? (meths = (opts[i])[3]) : (meths = 1);
    (i = "v?ariables" in o) ? (vars = (opts[i])[3]) : (vars = 1);
    (i = "h?eader" in o) ? (header = (opts[i])[3]) : (header = 1);
    if ((!meths) && (!vars))
        return "Perhaps you will want to dump methods and/or vars next time?";
    objs = [];
    for o in (args) {
        catch any
            objs += [(> .match_env_nice(o) <)];
        with
            .tell((traceback()[1])[2]);
    }
    if (!objs)
        return "Dump nothing?";
    if (tdfmt)
        .dump_fmt_textdump(objs, meths, vars, header);
    else
        .dump_fmt_commands(objs, meths, vars, header);
};

public method ._show_methods() {
    arg obj, f, match, chop;
    var methods, types, m, t, out;
    
    types = #[];
    for m in (obj.methods()) {
        if (tostr(m).(match)(f) != 0)
            types = types.add_elem(obj.method_access(m), ((("." + m) + "(") + ((obj.method_info(m))[1])) + ")");
    }
    
    // hard-listing the types guarantee's their order
    out = [];
    for t in (['root, 'driver, 'public, 'protected, 'private, 'frob]) {
        if (!(types.contains(t)))
            continue;
        out += [(((tostr(t).capitalize()) + " methods matching \"") + f) + "\":"];
        for m in (types[t])
            out += ["  " + m];
    }
    return out;
};

protected method .descendants_cmd() {
    arg cmdstr, cmd, args;
    var obj, max, line, opts, i, r, not, only, f;
    
    (> .perms(caller(), 'command) <);
    
    // parse args
    [obj, args, opts] = args;
    if ((obj[1]) != 'object)
        return "Object reference must simply be a dbref.";
    if ((obj[2]) != (obj[3]))
        .tell(("Ignoring specified definer " + (obj[2])) + ".");
    obj = obj[3];
    only = (not = []);
    max = 1;
    if ((i = "o?nly" in (opts.slice(1)))) {
        only = map f in (((opts[i])[4]).split(" *, *")) to (f.to_symbol());
        opts = delete(opts, i);
    }
    if ((i = "n?ot" in (opts.slice(1)))) {
        not = map f in (((opts[i])[4]).split(" *, *")) to (f.to_symbol());
        opts = delete(opts, i);
    }
    if ((i = "r?edundant" in (opts.slice(1)))) {
        r = (opts[i])[3];
        opts = delete(opts, i);
    }
    if ((i = "a?ll" in (opts.slice(1)))) {
        if ((opts[i])[3])
            max = 0;
        opts = delete(opts, i);
    }
    if (opts) {
        if ((max = find i in (opts) where ((i[2]).is_numeric()))) {
            max = toint((opts[max])[2]);
            if (max < 1)
                return "Maximum levels must be greater than zero.";
        }
    }
    
    // do it
    line = ("-- Descendants of " + obj) + " [";
    .tell((line + (((obj.parents()).mmap('objname)).to_english())) + "]");
    if (max) {
        line = (max + " level") + ((max > 1) ? "s" : "");
        max++;
    } else {
        line = "all levels";
    }
    if (r)
        line += ", redundant entries";
    .tell("-- " + line);
    if (only)
        .tell("-- only objects with flag(s): +" + (only.join(" +")));
    if (not)
        .tell("-- not objects with flag(s): +" + (not.join(" +")));
    return [obj.format_descendants("", #[], 0, max, only, not, r), "--"];
};

protected method .chparents_cmd() {
    arg cmdstr, cmd, args;
    var syn, p, x, obj, parents, match;
    
    (> .perms(caller(), 'command) <);
    syn = ("Syntax: `" + cmd) + " <child> [to] <parent>, <parent>, ...`";
    if ((match = match_template(args, "* to *"))) {
        obj = match[1];
        parents = match[3];
    } else if ((args = explode(args))) {
        if (listlen(args) == 1)
            return syn;
        obj = args[1];
        parents = sublist(args, 2).join();
    } else {
        return syn;
    }
    obj = (> .match_env_nice(obj) <);
    if (("," in parents) || (" and " in parents))
        parents = parents.explode_english_list();
    else
        parents = parents.explode();
    if (!parents)
        return "No parents to change to.";
    parents = map p in (parents) to ((> .match_env_nice(p) <));
    catch any {
        obj.chparents(@parents);
        return ((("Changed parents for " + obj) + " to ") + (parents.to_english())) + ".";
    } with {
        return (traceback()[1])[2];
    }
};

protected method ._display_methods() {
    arg obj, info, chop, f;
    var type, types, line, out, m, len;
    
    len = .linelen();
    out = [];
    for type in (info.keys()) {
        line = (tostr(type).capitalize()) + " Methods";
        if (f)
            line += (" matching \"" + f) + "\"";
        out += [line + ":"];
        for m in (info[type]) {
            line = strfmt("%5l %4r %l.%l(%l)", $object_lib.parse_method_flags(m[8]), m[6], ((m[1]) != obj) ? m[1] : "", m[2], m[3]);
            if (chop)
                line = line.chop(len);
            out += [line];
            refresh();
        }
    }
    return out;
};

protected method .eval_subs() {
    arg code;
    var idx, ret_code, sub;
    
    ret_code = "";
    while (code) {
        idx = "^" in code;
        if (!idx) {
            return ret_code + code;
        } else if ((idx == (code.length())) || ((code.subrange(idx + 1, 1)) == "^")) {
            ret_code += code.subrange(1, idx);
            code = code.subrange(idx + 1);
            if (code && ((code[1]) == "^"))
                code = code.subrange(2);
        } else {
            if (idx > 1) {
                ret_code += code.subrange(1, idx - 1);
                code = code.subrange(idx + 1);
            } else {
                code = code.subrange(2);
            }
            idx = 1;
            while ((idx <= (code.length())) && (!((code[idx]) in " =.()[]=<>?|&!*+-/';\"")))
                idx++;
            sub = .match_env_nice(code.subrange(1, idx - 1));
            ret_code += sub;
            code = code.subrange(idx);
        }
    }
    return ret_code;
};

public method .eval_prefix() {
    return #[["me", ("me = " + this()) + ";"], ["here", ("here = " + (.location())) + ";"]].union(eval_prefix || #[]);
};

protected method .del_command_cmd() {
    arg cmdstr, cmd, args;
    var ref, t, objref;
    
    (> .perms(caller(), 'command) <);
    args = args.explode_quoted();
    if (listlen(args) > 2) {
        if ((args[2]) == "from")
            args = delete(args, 2);
        t = delete(args, listlen(args)).join();
        objref = args.last();
    } else if (listlen(args) == 2) {
        t = args[1];
        objref = args[2];
    } else {
        return ("Syntax: `" + cmd) + " \"template\" [from] <objref>";
    }
    catch any {
        ref = (> $parse_lib.ref(objref) <);
        if ((ref[1]) != 'method)
            return ("The reference " + objref) + " is not for a method.";
        if ((!(ref[4])) || (!((ref[4]).valid_ident())))
            return ((("Invalid method name " + (ref[3])) + ".") + (ref[4])) + "().";
        if (!(> (ref[2]).del_command(t, tosym(ref[4])) <))
            return strfmt("Command %d is not defined on %s.", t, ref[2]);
    } with {
        return (traceback()[1])[2];
    }
    return strfmt("Command %d removed from %s.%s()", t, ref[3], ref[4]);
    
    // $#Edited: 18 Jul 96 14:56 $levi
};

private method ._which_cmd() {
    arg partial, parent, type, more;
    var p, cmds, cmd, def, matches;
    
    cmds = (| parent.(type)() |) || #[];
    matches = [];
    for def in (cmds.keys()) {
        for cmd in (cmds[def]) {
            if (partial in ((cmd[3]).strip("?")))
                matches += [[more, cmd[3], cmd[4]]];
        }
    }
    return matches;
};

protected method .which_cmd() {
    arg cmdstr, command, str;
    var m, c, l, t, p, s, cmds, def, out, dname, line, lcache, rcache;
    
    (> .perms(caller(), 'command) <);
    if (!str)
        return ("Syntax: `" + command) + " <partial or full template>`";
    m = #[];
    t = (str.explode())[1];
    for p in (.ancestors()) {
        if (p == $has_commands)
            break;
        cmds = ._which_cmd(str, p, 'local_commands, " ");
        cmds += ._which_cmd(str, p, 'remote_commands, "*");
        if (cmds)
            m = m.add(p, cmds);
    }
    if (!m)
        return ("No commands found matching the template \"" + str) + "\".";
    l = (.linelen()) / 2;
    out = [("Commands matching the template \"" + str) + "\":"];
    lcache = .local_cache();
    rcache = .remote_cache();
    for def in (m) {
        dname = (" " + (def[1])) + ".";
        for c in (def[2]) {
            line = ((((c[1]) + ((c[2]).pad(l))) + dname) + tostr(c[3])) + "()";
            s = (((((c[2]).explode())[1]).strip("?")).explode("|"))[1];
            if ((| lcache[s] |) || (| rcache[s] |))
                line = " " + line;
            else
                line = "!" + line;
            out += [line];
        }
    }
    return out;
};

protected method .add_command_cmd() {
    arg cmdstr, cmd, str;
    var ref, t, args, objref;
    
    (> .perms(caller(), 'command) <);
    args = str.explode_quoted();
    if (listlen(args) > 2) {
        if ((args[2]) in ["to", "for"])
            args = delete(args, 2);
        t = delete(args, listlen(args)).join();
        objref = args.last();
    } else if (listlen(args) == 2) {
        t = args[1];
        objref = args[2];
    } else {
        return ("Syntax: `" + cmd) + " \"template\" [to|for] <objref>";
    }
    catch any {
        ref = (> $parse_lib.ref(objref) <);
        if ((ref[1]) != 'method)
            return ("The reference " + objref) + " is not for a method.";
        if ((!(ref[4])) || (!((ref[4]).valid_ident())))
            return ((("Invalid method name " + (ref[3])) + ".") + (ref[4])) + "().";
        (> (ref[2]).add_command(t, tosym(ref[4])) <);
    } with {
        return (traceback()[1])[2];
    }
    return strfmt("Command %d added to %s.%s()", t, ref[3], ref[4]);
    
    // $#Edited: 18 Jul 96 14:56 $levi
};

protected method .join_cmd() {
    arg cmdstr, cmd, who;
    var loc, p, user;
    
    (> .perms(caller(), 'command) <);
    if (!who) {
        .tell("Specify a user to join.");
        return;
    }
    catch any {
        if ((who[1]) in "$#") {
            user = (> $object_lib.to_dbref(who) <);
            if (!(user.has_ancestor($thing)))
                return "You can only join things in the VR.";
        } else {
            user = (> $user_db.search(who) <);
        }
    } with {
        .tell((traceback()[1])[2]);
        return;
    }
    loc = user.location();
    if (loc == (.location())) {
        .tell(("You are already with " + (user.name())) + "!");
        return;
    }
    if (!(.teleport(loc)))
        .tell("Sorry.");
    else
        .tell(("You join " + (user.name())) + ".");
};

protected method .local_edit_cmd() {
    arg cmdstr, cmd, args;
    var ref, edited, code, def, meth, i;
    
    (> .perms(caller(), 'command) <);
    ref = args[1];
    if ((ref[1]) == 'variable)
        return ((("The reference " + (ref[3])) + ",") + ((ref[4]) || "")) + " is not for a method.";
    if ((ref[1]) == 'object)
        return ("The reference " + (ref[3])) + " is not for a method.";
    if ((ref[3]) && (!((ref[3]).is_writable_by(this()))))
        return "You cannot program on that object.";
    if ((!(ref[4])) || (!((ref[4]).valid_ident())))
        return ("The method name '" + (ref[4])) + "' is not acceptable.";
    meth = tosym(ref[4]);
    catch ~methodnf {
        def = (ref[3]).find_method(meth);
        if (!(def.is_writable_by(this())))
            return ("You cannot program on " + def) + ".";
    } with {
        return ((("Method " + (ref[3])) + ".") + meth) + "() not found.";
    }
    if ((i = "e?dited" in ((args[3]).slice(1)))) {
        if (!(((args[3])[i])[3])) {
            if (!($sys.is_admin(this())))
                return "Only admins can shut off edited comments.";
        } else {
            edited = 1;
        }
    } else {
        edited = 1;
    }
    if (edited) {
        edited = (("// $#Edited: " + ($time.format("%d %h %y %H:%M"))) + " ") + this();
        if (i && (((args[3])[i])[4]))
            edited += ": " + (((args[3])[i])[4]);
    }
    catch ~perm
        code = def.list_method(meth);
    with
        return (traceback()[1])[2];
    return ([(((("#$# edit name: " + meth) + " upload: @program ") + def) + ".") + meth] + (code.prefix("    "))) + ["."];
};

protected method .display_cmd() {
    arg cmdstr, cmd, args;
    var opts, slice, what, match, i, chop, f, gen, def, obj, out;
    
    (> .perms(caller(), 'command) <);
    opts = args[3];
    args = args[1];
    chop = 1;
    slice = opts.slice(1);
    if ((i = "c?hop" in slice) && (!((opts[i])[3])))
        chop = 0;
    else
        chop = .linelen();
    def = args[3];
    if ((i = "g?enerations" in slice)) {
        gen = (opts[i])[4];
        if (gen.is_numeric())
            gen = ['generations, toint(gen)];
        else if (gen)
            gen = ['ancestors_to, (> .match_env_nice(gen) <)];
        else
            gen = ['ancestors_to, def];
        def = 0;
    } else {
        gen = ['generations, 1];
    }
    what = [args[1]] + ((| args[5] |) ? [args[5]] : []);
    obj = args[2];
    out = $object_lib.format_object(obj, chop);
    if (!(args[4]))
        f = .get_setting("match-default", $programmer);
    else
        f = args[4];
    match = .get_setting("match-with", $programmer);
    if ('method in what)
        out += ._display_methods(obj, obj.list_methods(gen, def, f, match), chop, f);
    if ('variable in what)
        out += ._display_variables(obj, obj.variable_info(gen, def, f, match), chop, f);
    return out + ["---"];
};

protected method .eval_offset() {
    return eval_offset || #[['mtime, 0], ['time, 0], ['ticks, 0]];
};

protected method .del_var_cmd() {
    arg cmdstr, cmd, ref;
    
    (> .perms(caller(), 'command) <);
    if (((ref[1]) != 'variable) || (!(ref[4])))
        return "Invalid obj,variable reference.";
    catch ~symbol
        (ref[3]).del_var(tosym(ref[4]));
    with
        return (traceback()[1])[2];
    return ((("Object variable " + (ref[3])) + ",") + (ref[4])) + " deleted.";
};

protected method .add_var_cmd() {
    arg cmdstr, cmd, args;
    var ref, value;
    
    (> .perms(caller(), 'command) <);
    if (!args)
        return "Invalid obj,variable reference.";
    ref = (> $parse_lib.ref(args.word(1)) <);
    if (((ref[1]) != 'variable) || (!(ref[4])))
        return "Invalid obj,variable reference.";
    if (" " in args) {
        args = substr(args, (" " in args) + 1);
        if (args && ((args[1]) == "="))
            args = substr(args, (" " in args) + 1);
        if (args) {
            value = .eval([("return " + args) + ";"]);
            if ((value[1]) == 'errors)
                return ("Unable to parse value \"" + args) + "\".";
            value = value[2];
        } else {
            value = 0;
        }
    } else {
        value = 0;
    }
    catch any {
        (> (ref[3]).add_var(tosym(ref[4]), value) <);
    } with {
        if (error() in [~varexists, ~symbol])
            return (traceback()[1])[2];
        rethrow(error());
    }
    return ((((("Object variable " + (ref[3])) + ",") + (ref[4])) + " added with value ") + value) + ".";
};

protected method .add_parent_cmd() {
    arg cmdstr, cmd, args;
    var syn, obj, parent;
    
    (> .perms(caller(), 'command) <);
    args = args.explode();
    if ((listlen(args) > 2) && ((args[2]) == "to"))
        args = delete(args, 2);
    if (listlen(args) != 2)
        return ("Syntax: `" + cmd) + " <parent> [to] <object>`";
    parent = (> .match_env_nice(args[1]) <);
    obj = (> .match_env_nice(args[2]) <);
    catch any {
        (> obj.add_parent(parent) <);
        return ((("Added parent to " + (obj.namef('ref))) + ", parents: ") + ((obj.parents()).to_english())) + ".";
    } with {
        return (traceback()[1])[2];
    }
};

protected method .del_parent_cmd() {
    arg cmdstr, cmd, args;
    var syn, obj, parent;
    
    (> .perms(caller(), 'command) <);
    args = args.explode();
    if ((listlen(args) > 2) && ((args[2]) == "from"))
        args = delete(args, 2);
    if (listlen(args) != 2)
        return ("Syntax: `" + cmd) + " <parent> [from] <object>`";
    if (!args)
        .tell_error(syn);
    parent = (> .match_env_nice(args[1]) <);
    obj = (> .match_env_nice(args[2]) <);
    catch any {
        (> obj.del_parent(parent) <);
        return ((("Deleted parent from " + (obj.namef('ref))) + ", parents: ") + ((obj.parents()).to_english())) + ".";
    } with {
        return (traceback()[1])[2];
    }
};

protected method .trace_method_cmd() {
    arg cmdstr, cmd, ref;
    var method, current, trace, syn, minfo, line, anc, len, out, m;
    
    (> .perms(caller(), 'command) <);
    if ((ref[1]) != 'method)
        return toliteral(cmd) + " requires a full method reference.";
    catch any {
        method = (> tosym(ref[4]) <);
        current = (> (ref[2]).find_method(method) <);
        trace = [];
        while (current) {
            trace += [current];
            current = (| (ref[2]).find_next_method(method, current) |);
        }
    } with {
        if (error() == ~symbol)
            return ("Invalid method name \"" + (ref[4])) + "\".";
        return (traceback()[1])[2];
    }
    .tell(((("Method trace of " + (ref[2])) + ".") + (ref[4])) + "():");
    len = .linelen();
    out = [];
    for anc in (trace.reverse()) {
        m = anc.method_info(method);
        out += [strfmt("%5l %4r %l.%l(%l)", $object_lib.parse_method_flags(m[6]), m[4], anc, method, m[1])];
    }
    return out;
};

public method .evaluate() {
    arg str, obj, definer, @mode;
    var start, end, time, ticks, mtime, times, method, errs, trace;
    
    mode = mode ? mode[1] : 0;
    if (sender() != $eval_parser)
        (> .perms(caller(), $programmer) <);
    method = tosym("tmp_eval_" + time());
    if ((errs = (> definer.add_method([str], method) <)))
        return [[0, 0, 0], ['errors, errs, 0, 0]];
    catch any {
        if (mode in ['trace, 'profile])
            debug_callers(1);
        else if (mode == 'debug)
            debug_callers(2);
        times = [tick(), time(), mtime(), (> obj.(method)() <), mtime(), time(), tick()];
        trace = call_trace();
        debug_callers(0);
    } with {
        debug_callers(0);
        (| definer.del_method(method) |);
        rethrow(error());
    }
    (| definer.del_method(method) |);
    
    // figure up the actual times
    time = (times[6]) - (times[2]);
    ticks = (times[7]) - (times[1]);
    if ((times[5]) > (times[3]))
        mtime = (times[5]) - (times[3]);
    else if (time)
        mtime = ((time * 1000000) + (1000000 - (times[3]))) + (times[5]);
    else
        mtime = (1000000 - (times[5])) + (times[3]);
    
    // offset it?
    if (eval_offset && (mode != 'no_offset)) {
        ticks -= eval_offset[1];
        time -= eval_offset[2];
        mtime -= eval_offset[3];
    }
    if (trace)
        return [[ticks, time, abs(mtime)], ['result, times[4]], $code_lib.generate_debug_listing(trace, mode)];
    return [[ticks, time, abs(mtime)], ['result, times[4]]];
    
    // $#Edited: 17 Dec 96 15:11 $miro
    // $#Edited: 06 Feb 97 23:09 $miro
};

protected method ._list_method() {
    arg obj, method, @args;
    var code, opt, flags, f;
    
    [(args ?= 0), (opt ?= "")] = args;
    code = obj.list_method(method);
    flags = obj.method_flags(method);
    if (args) {
        code = code.numbered_text();
        return ([(((((("-- " + (obj.method_access(method))) + " method ") + obj) + ".") + method) + "()") + (flags ? ": " + (flags.join(", ")) : "")] + code) + ["--"];
    } else {
        return ([$object_lib.format_method_header(obj, method, opt, flags, obj.method_access(method))] + (code.prefix("  "))) + ["."];
    }
    
    // $#Edited: 18 Jul 96 14:56 $levi
    // $#Edited: 30 Nov 96 21:22 $miro
};

protected method ._display_variables() {
    arg obj, info, chop, f;
    var line, i, len, out, fmt;
    
    len = .linelen();
    line = "Object Variables";
    if (f)
        line += (" matching \"" + f) + "\"";
    out = [line];
    for i in (info.reverse()) {
        line = strfmt("  %s,%s: %d", ((i[1]) != obj) ? i[1] : "", i[2], i[3]);
        if (chop)
            line = line.chop(len);
        out += [line];
        refresh();
    }
    return out;
};

public method .parse_methodcmd_options() {
    arg syntax, args, @more;
    var o, opt, opts, out, r, l;
    
    o = ([@more, []][1]) + [["pub?lic"], ["r?oot"], ["dr?iver"], ["pri?vate"], ["pro?tected"], ["no?override"], ["s?yncronized"], ["l?ocked"], ["na?tive"]];
    opts = #[['exists, 0], ['ignore, 0], ['mflags, []], ['mstate, 'public], ['error, 0]].union([@more, #[], #[]][2]);
    args = $parse_lib.getopt(args, o);
    if (!(args[1])) {
        out = [];
        for opt in (o)
            out += ["  +|-" + (opt[1])];
        (> .tell_error(syntax, ["Valid options:"] + (out.lcolumnize())) <);
    }
    r = (| $parse_lib.ref((args[1]).join()) |);
    if (!r) {
        opts = opts.add('error, "Invalid <object>.<method> reference.");
        opts = opts.add('ignore, 1);
    }
    if (!((r[4]).valid_ident())) {
        opts = opts.add('error, (((r[2]) + ".") + tostr(r[4])) + "() is not a valid method reference.");
        opts = opts.add('ignore, 1);
    }
    r = replace(r, 4, tosym(r[4]));
    if ((r[2]) && (!((r[2]).is_writable_by(this())))) {
        opts = opts.add('error, ("You cannot program " + (r[2])) + ".");
        opts = opts.add('ignore, 1);
    }
    if ((| (r[2]).find_method(r[4]) |) == (r[2])) {
        opts = opts.add('mflags, (r[2]).method_flags(r[4]));
        opts = opts.add('mstate, (r[2]).method_access(r[4]));
        opts = opts.add('exists, 1);
    }
    opts = opts.add('object, r[2]);
    opts = opts.add('method, r[4]);
    for opt in (args[2]) {
        switch (opt[1]) {
            case "pub?lic", "r?oot", "dr?iver", "pri?vate", "pro?tected":
                opts = opts.add('mstate, (opt[1]).to_symbol());
            case "no?override", "s?yncronized":
                opts = opts.add('mflags, (opts['mflags]).setadd((opt[1]).to_symbol()));
            case "l?ocked":
                .tell("You cannot set the locked flag on a method.");
            case "n?ative":
                .tell("You cannot set the native flag on a method.");
            default:
                if (!(opt[1])) {
                    .tell(("Unknown option: \"" + (opt[2])) + "\"");
                    .tell("Valid options: " + ((o.slice(1)).to_english()));
                    continue;
                }
                opts = opts.add((opt[1]).to_symbol(), [opt[3], opt[4]]);
        }
    }
    return opts;
};

protected method .chmanage_cmd() {
    arg cmdstr, cmd, args;
    var obj, manager;
    
    (> .perms(caller(), 'command) <);
    args = (args.replace(" to ", " ")).explode();
    if ((!args) || ((args.length()) != 2))
        (> .tell_error(cmd + " <object> [to] <user>") <);
    obj = .match_env_nice(args[1]);
    manager = .match_env_nice(args[2]);
    if ((!(manager.is($user))) && (!(.is($admin))))
        return "Sorry you can only set users as managers.";
    catch any
        (> obj.change_manager(manager) <);
    with
        return (traceback()[1])[2];
    return ((("Manager on " + (obj.namef('xref))) + " changed to ") + (manager.namef('xref))) + ".";
};

protected method .managed_cmd() {
    arg cmdstr, cmd, args;
    var manager, managed, obj, out, len;
    
    (> .perms(caller(), 'command) <);
    manager = (| .match_environment(args) |);
    if (!manager) {
        manager = (| $user_db.search(args) |);
        if (!manager)
            return ("Unable to find \"" + args) + "\".";
    }
    managed = manager.managed();
    if (!managed)
        return (manager.namef('ref)) + " does not manage any objects.";
    out = [(manager.namef('ref)) + " manages:"];
    len = (.linelen()) / 2;
    for obj in (managed) {
        if (!valid(obj)) {
            .tell(("  ** invalid object (" + obj) + ") **");
            continue;
        }
        out += [(("  " + ((obj.namef('xref)).pad(len))) + " ") + ($object_lib.see_perms(obj, ["", ""]))];
    }
    return out;
};

public method .clear_eval() {
    (| clear_var('eval_offset) |);
};

protected method .create_cmd() {
    arg cmdstr, cmd, args;
    var new, parents, obj;
    
    (> .perms(caller(), 'command) <);
    args = (args.replace(" from ", " ")).explode();
    if ((!args) || ((args.length()) < 2))
        .tell_error(cmd + " <object> [from] <parent>[, <parent> ...]");
    new = args[1];
    parents = [];
    for obj in (args.subrange(2))
        parents += [.match_env_nice(obj)];
};

protected method .add_shortcut_cmd() {
    arg cmdstr, cmd, args;
    var ref, syn;
    
    (> .perms(caller(), 'command) <);
    args = args.explode_quoted();
    syn = cmd + " \"<shortcut>\" [to] \"<command>\" [on] \"<object>\"";
    if ((listlen(args) == 5) && (((args[2]) == "to") && ((args[4]) == "on")))
        args = [args[1], args[3], args[5]];
    if (listlen(args) != 3)
        return ("Syntax: `" + syn) + "`";
    ref = (> $parse_lib.ref(args[3]) <);
    if (((ref[1]) != 'method) || ((!(ref[4])) || (!(| tosym(ref[4]) |))))
        return ("Invalid method reference reference \"" + (args[3])) + "\".";
    catch any
        (> (ref[2]).add_shortcut(args[1], args[2], tosym(ref[4])) <);
    with
        return (traceback()[1])[2];
    return strfmt("Added shortcut %d to command %d on %s.%s().", args[1], args[2], ref[2], ref[4]);
};

protected method .new_editor_session() {
    arg ref, opts, type;
    var def, code, name;
    
    switch (ref[1]) {
        case 'variable:
            (> .tell_error("", "Variable editor not yet implemented.") <);
        case 'method:
            def = (| (ref[2]).find_method(tosym(ref[4])) |);
            if (!def) {
                def = ref[3];
                code = [];
            } else {
                code = def.list_method(tosym(ref[4]));
            }
            (> .invoke_editor(this(), '_edit_method_callback, code, [def, tosym(ref[4])]) <);
        default:
            return (> pass(ref, opts, type) <);
    }
    if (.active_editor())
        return [("Editor invoked with " + ((.active_editor()).session_name())) + ".", "Type 'help' to list available commands."];
    else
        return ["Remote editing invoked."];
};

protected method ._edit_method_callback() {
    arg code, client_data;
    var errors;
    
    errors = (client_data[1]).add_method(code, client_data[2]);
    if (errors)
        return errors;
    return "Method compiled.";
    
    // $#Edited: 18 Aug 96 20:07 $jenner
};

protected method .rehash_cmd() {
    arg cmdstr, cmd;
    var c, o, p;
    
    (> .perms(caller(), 'command) <);
    .tell("Rehashing your commands...");
    .purge_caches();
    for p in (parents())
        p.cache_uninit();
    for cmd in (.local_commands()) {
        for c in (cmd[2])
            .add_to_local_cache(c[1]);
    }
    for p in (parents())
        p.cache_init();
    .tell("Done.");
};

public method ._show_variables() {
    arg obj, f, match, chop;
    var parent, out, v, line, len;
    
    out = [];
    len = .linelen();
    for parent in (obj.data()) {
        if (valid(parent[1])) {
            out += [(((parent[1]) + " variables matching \"") + f) + "\":"];
            if ((parent[1]).has_flag('variables, this())) {
                for v in (parent[2]) {
                    if (tostr(v[1]).(match)(f) == 0)
                        continue;
                    line = (("  " + (v[1])) + ": ") + toliteral(v[2]);
                    if (chop)
                        line = line.chop(len);
                    out += [line];
                }
            } else {
                out += ["  ** Permission Denied **"];
            }
        } else {
            out += [($object_lib.get_name(parent[1])) + " Variables:"];
            for v in (parent[2]) {
                if (tostr(v[1]).(match)(f) == 0)
                    continue;
                line = (("  " + (v[1])) + ": ") + toliteral(v[2]);
                if (chop)
                    line = line.chop(len);
                out += [line];
            }
        }
        refresh();
    }
    return out;
    
    // $#Edited: 03 Nov 96 15:36 $brad
    // $#Edited: 03 Nov 96 15:37 $brad
};

public method ._move_variable() {
    arg remove, fobj, fname, tobj, tname, comment;
    var value, line, result, tmp;
    
    value = (> fobj.eval([("return " + fname) + ";"]) <);
    if ((value[1]) != 'result)
        throw(~eval, "An error was encountered upon evaluation.");
    value = value[2];
    (> tobj.add_var(tname, value) <);
    if (remove)
        (> fobj.del_var(fname) <);
};

protected method .del_shortcut_cmd() {
    arg cmdstr, cmd, args;
    var ref, syn;
    
    (> .perms(caller(), 'command) <);
    args = args.explode_quoted();
    if ((listlen(args) == 3) && ((args[2]) == "from"))
        args = delete(args, 2);
    if (listlen(args) != 2)
        return ("Syntax: `" + cmd) + " \"<shortcut>\" [from] <objref>";
    ref = (> $parse_lib.ref(args[2]) <);
    if (((ref[1]) != 'method) || ((!(ref[4])) || (!(| tosym(ref[4]) |))))
        return ("Invalid method reference reference \"" + (args[3])) + "\".";
    catch any
        (> (ref[2]).del_shortcut(args[1]) <);
    with
        return (traceback()[1])[2];
    return strfmt("Deleted shortcut %d from %s.%s().", args[1], ref[2], ref[4]);
};

protected method .grep_cmd() {
    arg cmdstr, cmd, args;
    var more, regexp, from, syn, opts, d, f, l, r, rep, slice, objs, obj, out;
    
    (> .perms(caller(), 'command) <);
    [more, opts] = args;
    if ((more.length()) < 2)
        return ("=> Syntax: `" + cmd) + " [options] <regexp> <object> <object>..";
    regexp = more[1];
    more = more.subrange(2);
    
    // handle the options
    slice = opts.slice(1);
    if ((r = (| "r?eplace-with" in slice |))) {
        rep = (opts[r])[4];
        r = (opts[r])[3];
    }
    if ((d = (| "d?escend" in ((args[2]).slice(1)) |)))
        d = (opts[d])[3];
    if ((l = (| "l?ist" in ((args[2]).slice(1)) |)))
        l = (opts[l])[3];
    if ((f = (| "f?ull" in ((args[2]).slice(1)) |)))
        f = (opts[f])[3];
    
    // now we check for conflicting or incorrect options..
    if (d && (!(.is($admin))))
        return "Only administrators may use the +descend option, talk to one.";
    if (d && ((more.length()) > 1))
        return "+descend can only be used with a single object as the target.";
    if (r && (f || l))
        return "+replace-with option cannot be used with +full or +list.";
    if (f && l)
        return "+full cannot be used with +list.";
    
    // the pause() flushes so we can see the 'Searching for ..'
    // Do this now because .descendants() can lag
    .tell(("Searching for \"" + regexp) + "\"...");
    pause();
    
    // figure out our targets
    if (d) {
        obj = (> .match_env_nice(more[1]) <);
        objs = [obj, @obj.descendants()];
    } else {
        objs = [];
        for obj in (more)
            objs += [(> .match_env_nice(obj) <)];
    }
    
    // call the right grep method
    if (r)
        return (> .grep_replace(regexp, objs, rep) <);
    else if (l)
        return (> .grep_list(regexp, objs) <);
    else if (f)
        return (> .grep_full(regexp, objs) <);
    else
        return (> .grep_brief(regexp, objs) <);
};

protected method .grep_replace() {
    arg regexp, objs, replace;
    var obj, method;
    
    for obj in (objs) {
        if (!valid(obj))
            continue;
        if (!(obj.is_writable_by(this()))) {
            .tell(("You cannot write on " + obj) + ", skipping..");
            continue;
        }
        for method in (obj.methods()) {
            (> .grep_replace_method(obj, method, regexp, replace) <);
            refresh();
        }
        refresh();
    }
    return "Done.";
};

protected method .grep_list() {
    arg regexp, objs;
    var obj, code, x, l, lr, what, loop, method, opt;
    
    opt = .get_setting("@program-options", $programmer);
    for obj in (objs) {
        if (!valid(obj))
            continue;
        if (!(obj.has_flag('code))) {
            .tell(("You cannot read method code on " + obj) + ", skipping..");
            continue;
        }
        for method in (obj.methods()) {
            code = obj.list_method(method);
            for l in (code) {
                if (match_regexp(l, regexp)) {
                    .tell(([$object_lib.format_method_header(obj, method, opt, obj.method_flags(method), obj.method_access(method))] + (code.prefix("  "))) + ["."]);
                    break;
                }
                refresh();
            }
            refresh();
        }
        refresh();
    }
    return "---";
};

protected method .grep_full() {
    arg regexp, objs;
    var obj, method, out, x, l, code;
    
    for obj in (objs) {
        if (!valid(obj))
            continue;
        if (!(obj.has_flag('code))) {
            .tell(("You cannot read method code on " + obj) + ", skipping..");
            continue;
        }
        out = [];
        for method in (obj.methods()) {
            code = obj.list_method(method);
            for x in [1 .. listlen(code)] {
                l = code[x];
                if (match_regexp(l, regexp))
                    out += [(((((obj + ".") + method) + "() line ") + x) + ": ") + l];
                refresh();
            }
            refresh();
        }
        if (out)
            .tell(out);
        refresh();
    }
    return "---";
};

protected method .grep_brief() {
    arg regexp, objs;
    var obj, method, out, x, l, line, lines, code;
    
    for obj in (objs) {
        if (!valid(obj))
            continue;
        if (!(obj.has_flag('code))) {
            .tell(("You cannot read method code on " + obj) + ", skipping..");
            continue;
        }
        out = [];
        for method in (obj.methods()) {
            code = obj.list_method(method);
            lines = [];
            for x in [1 .. listlen(code)] {
                l = code[x];
                if (match_regexp(l, regexp))
                    lines += [x];
                refresh();
            }
            if (lines)
                out += [(((obj + ".") + method) + "(): ") + (lines.to_english())];
            refresh();
        }
        if (out)
            .tell(out);
        refresh();
    }
    return "---";
};

protected method .grep_replace_method() {
    arg obj, method, regexp, replace;
    var code, x, l, lr, errs, what;
    
    code = obj.list_method(method);
    for x in [1 .. listlen(code)] {
        l = code[x];
        if (!match_regexp(l, regexp))
            continue;
        lr = strsed(l, regexp, replace, "g");
        .tell([((((("Change " + obj) + ".") + method) + "() line ") + x) + " from:", "  " + l, "to:", "  " + lr]);
        what = .prompt("? (yes, no, abort, abort-all) [yes] ");
        if ((!what) || (what in ["yes", "y"])) {
            code = replace(code, x, lr);
        } else if (what == "abort") {
            .tell("Aborting method ..");
            return;
        } else if (what == "abort-all") {
            throw(~stop, "Aborting grep replace");
        } else if (!(what in ["no", "n"])) {
            .tell(("Unknown command '" + what) + "', assuming 'no'.");
        }
        refresh();
    }
    if ((errs = obj.add_method(code, method)))
        .tell(((([((("Error in compilation of updated method " + obj) + ".") + method) + "():"] + (errs.prefix("  "))) + ["-- Method code: "]) + (code.prefix("  "))) + ["--"]);
};

protected method .chmod_cmd() {
    arg cmdstr, cmd, args;
    var a, ts, t, opts, b, objs, o, precedence, ref, flags, match, m;
    
    (> .perms(caller(), 'command) <);
    args = args.explode_quoted();
    ts = ["cod?e", "cor?e", "d?river", "fe?rtile", "fo?rked", "fr?ob", "l?ocked", "m?ethods", "na?tive", "no?override", "pri?vate", "pro?tected", "pu?blic", "r?oot", "v?ariables"];
    if (!args)
        return ("=> Syntax: `" + cmd) + " <options> <object> [<object ..]`";
    opts = #[];
    objs = [];
    for a in (args) {
        if (a && ((a[1]) in ["+", "-"])) {
            b = (a[1]) == "+";
            a = substr(a, 2);
            match = 0;
            for t in (ts) {
                if (match_template(a, t)) {
                    opts = dict_add(opts, tosym(t.strip()), b);
                    match++;
                    break;
                }
            }
            if (!match) {
                catch ~symbol
                    opts = dict_add(opts, tosym(a), b);
                with
                    .tell(("Invalid option '" + a) + "' (non-alphanumeric characters)");
            }
        } else {
            objs += [a];
        }
    }
    if (!objs)
        return [("=> Syntax: `" + cmd) + " <options> <object> [<object ..]`", "No objects specified."];
    if (!opts)
        return [("=> Syntax: `" + cmd) + " <options> <object> [<object ..]`", "No options specified."];
    
    // ok, now handle it, keep precedence for their own sake
    for o in (objs) {
        catch any {
            ref = (| $parse_lib.ref(o) |);
        } with {
            .tell((traceback()[1])[2]);
            continue;
        }
        if (!precedence) {
            precedence = ref[1];
        } else if ((ref[1]) != precedence) {
            .tell(((("Item '" + o) + "' is not a ") + precedence) + " reference.");
            .tell("All references must be the same type.");
            continue;
        }
        o = ref[3];
        for a in (dict_keys(opts)) {
            catch any {
                switch (a) {
                    case 'driver, 'private, 'protected, 'public, 'root, 'frob:
                        if (precedence != 'method) {
                            .tell((("Option " + ((opts[a]) ? "+" : "-")) + a) + " is only applicable to methods.");
                            continue;
                        }
                        m = (> tosym(ref[4]) <);
                        (> o.set_method_access(m, a) <);
                        .tell(((("Set " + ($parse_lib.buildref(@ref))) + " access to ") + a) + ".");
                    case 'nooverride, 'locked, 'native, 'forked:
                        if (precedence != 'method) {
                            .tell((("Option " + ((opts[a]) ? "+" : "-")) + a) + " is only applicable to methods.");
                            continue;
                        }
                        m = (> tosym(ref[4]) <);
                        if (opts[a]) {
                            o.set_method_flags(m, setadd(o.method_flags(m), a));
                            .tell((((("Added Method Flag +" + a) + " to ") + ($parse_lib.buildref(@ref))) + ", flags: ") + (((o.method_flags(m)).prefix("+")).join()));
                        } else {
                            o.set_method_flags(m, setremove(o.method_flags(m), a));
                            .tell((((("Removed Method Flag +" + a) + " from ") + ($parse_lib.buildref(@ref))) + ", flags: ") + (((o.method_flags(m)).prefix("+")).join()));
                        }
                    default:
                        if (precedence != 'object) {
                            .tell((("Option " + ((opts[a]) ? "+" : "-")) + a) + " is only applicable to objects.");
                            continue;
                        }
                        if (opts[a]) {
                            o.add_flag(a);
                            .tell((((("Added Object Flag +" + a) + " to ") + (o.namef('ref))) + ", flags: ") + (((o.flags()).prefix("+")).join()));
                        } else {
                            o.del_flag(a);
                            .tell((((("Removed Object Flag +" + a) + " from ") + (o.namef('ref))) + ", flags: ") + (((o.flags()).prefix("+")).join()));
                        }
                }
            } with {
                .tell((traceback()[1])[2]);
            }
        }
        refresh();
    }
};

protected method .dump_fmt_textdump() {
    arg objs, meths, vars, header;
    var data, obj, out, a, v, m;
    
    // this uses .tell() to keep its internal overhead from bloating
    // it could be faster by building a list and printing it all at once
    // but this is nicer on the server (especially when dumping large objects).
    for obj in (objs) {
        refresh();
        if (header)
            .tell([((("object " + obj) + ": ") + ((obj.parents()).join(", "))) + ";", ""]);
        if (vars) {
            catch ~perm {
                data = (> obj.data() <);
                for a in (dict_keys(data)) {
                    refresh();
                    for v in (data[a])
                        .tell(strfmt("var %l %l = %d;", a, @v));
                }
            } with {
                .tell((traceback()[1])[2]);
            }
        }
        .tell("");
        if (meths) {
            catch ~perm {
                for m in ((> obj.methods() <)) {
                    refresh();
                    .tell([""] + (.format_method(obj, m, 'textdump)));
                }
            } with {
                .tell((traceback()[1])[2]);
            }
        }
    }
};

protected method .dump_fmt_commands() {
    arg objs, meths, vars, header;
    var data, obj, out, a, v, m, line, pars, cmdopts;
    
    // this uses .tell() to keep its internal overhead from bloating
    // it could be faster by building a list and printing it all at once
    // but this is nicer on the server (especially when dumping large objects).
    for obj in (objs) {
        refresh();
        if (header) {
            pars = obj.parents();
            line = (((((((";var p, new; if(!(| valid(" + obj) + ") |)) ") + "{ new = ") + (pars[1])) + ".spawn();") + " new.set_objname('") + (obj.objname())) + ");}";
            if (listlen(pars) > 1)
                line += (" obj.chparents(" + join(pars, ",")) + ");";
            .tell(line);
        }
        if (vars) {
            catch ~perm {
                data = (> obj.data() <);
                for a in (dict_keys(data)) {
                    refresh();
                    for v in (data[a]) {
                        if (a == obj)
                            .tell(strfmt("@av %l,%l = %d", obj, @v));
                        .tell(strfmt(";|as %l<%l>;%l = %d;", obj, a, @v));
                    }
                }
            } with {
                .tell((traceback()[1])[2]);
            }
        }
        if (meths) {
            cmdopts = .get_setting("@program-options", $programmer);
            catch ~perm {
                for m in ((> obj.methods() <)) {
                    refresh();
                    .tell(.format_method(obj, m, 'normal, cmdopts));
                }
            } with {
                .tell((traceback()[1])[2]);
            }
        }
    }
};

protected method .format_method() {
    arg obj, method, format, @opts;
    var code, opt, flags, f;
    
    // this needs to be on $programmer ot get the programmers perms
    [(opt ?= "")] = opts;
    code = obj.list_method(method);
    flags = obj.method_flags(method);
    switch (format) {
        case 'textdump:
            return ([(((((((obj.method_access(method)) + " method ") + obj) + ".") + method) + "()") + (flags ? ": " + (flags.join(", ")) : "")) + " {"] + (code.prefix("    "))) + ["};"];
        case 'numbered:
            code = code.numbered_text();
            return ([(((((("-- " + (obj.method_access(method))) + " method ") + obj) + ".") + method) + "()") + (flags ? ": " + (flags.join(", ")) : "")] + code) + ["--"];
        default:
            return ([$object_lib.format_method_header(obj, method, opt, flags, obj.method_access(method))] + (code.prefix("  "))) + ["."];
    }
    
    // $#Edited: 09 Aug 96 10:29 $brandon
    // $#Edited: 30 Nov 96 21:22 $miro
};

protected method .help_write_cmd() {
    arg cmdstr, cmd, str;
    var node, text, errors, ignore;
    
    (> .perms(caller(), 'command) <);
    if (!str) {
        node = .current_node();
    } else {
        catch any {
            node = .parse_help_reference(str);
        } with {
            .tell(("-- " + ((traceback()[1])[2])) + " --");
            .read("-- Ignoring until '.' or @abort --");
            return "Done ignoring.";
        }
    }
    if (!(node.is($help_node))) {
        ignore++;
        .tell((node.namef('ref)) + " is not a descendant of $help_node, ignoring.");
    }
    if (!(node.is_writable_by(this()))) {
        ignore++;
        .tell(("You cannot write help on " + (node.name())) + ", ignoring.");
    }
    text = .read(("-- Enter CML text for " + (node.namef('ref))) + " --");
    if (text == 'aborted)
        return;
    if (ignore)
        return "Done ignoring.";
    node.set_body(text);
    return ("New help text set for " + (node.namef('ref))) + ".";
};

protected method .help_list_cmd() {
    arg cmdstr, cmd, str;
    var node, out;
    
    (> .perms(caller(), 'command) <);
    if (!str)
        node = .current_node();
    else
        node = .parse_help_reference(str);
    if (!(node.is($help_node)))
        return (node.namef('ref)) + " is not a descendant of $help_node.";
    return (["@hwrite " + node] + ((node.body()).uncompile())) + ["."];
    
    // $#Edited: 22 Jul 96 12:03 $jenner
    // $#Copied 10 Nov 96 14:21 from $help_editing_ui.help_list_cmd() by $brandon
    // $#Moved 10 Nov 96 14:23 from $builder.help_list_cmd() by $brandon
};

protected method .new_help_node_cmd() {
    arg cmdstr, cmd, args;
    var new, name, p, parent, i, syn, m, index, opts, objname, o;
    
    (> .perms(caller(), 'command) <);
    syn = ("=> Syntax: `" + cmd) + " [<parent node>] [options]`";
    [args, opts] = args;
    o = opts.slice(1);
    if ((i = "n?amed" in o)) {
        name = (opts[i])[4];
        if (!name)
            return [syn, "Option +n?amed requires a followup argument."];
    }
    if ((i = "o?bjname" in o)) {
        objname = (| ((opts[i])[4]).to_symbol() |);
        if (!objname)
            return [syn, "Option +o?bjname requires a followup argument."];
    }
    
    // now use 'i' as the string rep of 'index'
    if ((i = "i?ndex" in o)) {
        i = (opts[i])[4];
        if (!i)
            return [syn, "Option +i?ndex requires a followup argument."];
    }
    
    // now figure out the parent node
    if (args) {
        p = args[1];
        catch any
            parent = (> .parse_help_reference(p) <);
        with
            return (traceback()[1])[2];
    } else {
        parent = .current_node();
    }
    
    // figure out the index
    if (i) {
        if ((i[1]) in ["$", "#"])
            index = (| $object_lib.to_dbref(i) |);
        else
            index = $help_index.match_children(i);
        if (!index)
            return [syn, ("!  Unable to find index '" + i) + "'"];
        if (!(index.has_ancestor($help_index)))
            return [syn, ("!  '" + (index.namef('ref))) + "' is not a help index."];
    }
    
    // create it
    new = (> parent.spawn() <);
    .tell(((("Created new node " + new) + " from ") + (parent.namef('ref))) + ".");
    
    // change its objname?
    if (objname) {
        catch any {
            (> new.set_objname(objname) <);
            .tell(("Changed node's objname to " + new) + ".");
        } with {
            .tell("set_objname(): " + ((traceback()[1])[2]));
        }
    }
    
    // set its name?
    if (name) {
        catch any {
            (> new.set_name(name) <);
            .tell(("Changed node's name to " + (new.name())) + ".");
        } with {
            .tell("set_name(): " + ((traceback()[1])[2]));
        }
    } else {
        .tell(("No name specified, set it with `@rename " + new) + " to <name>`");
    }
    
    // set its index?
    if (index) {
        catch any {
            (> new.set_index(index) <);
            .tell(("Set node's index to " + (index.namef('ref))) + ".");
        } with {
            .tell("set_index(): " + ((traceback()[1])[2]));
        }
    } else {
        .tell(("No index specified, set it with `@set " + new) + ":index=<index>`");
    }
};

public method .spawn_cmd() {
    arg cmdstr, cmd, args;
    var match, name, parents, p, line, set, nprog, new, t;
    
    (> .perms(caller(), 'command) <);
    if ((match = match_template(args, "* named *"))) {
        name = match[3];
        args = explode(match[1]);
    } else {
        args = args.explode_quoted();
        if (!args)
            return "Spawn from nothing?";
        name = "";
    }
    
    // programmers get additional privs
    nprog = !(.is($programmer));
    parents = [];
    for p in (args) {
        catch any {
            p = (> .match_env_nice(p) <);
        } with {
            .tell((traceback()[1])[2]);
            continue;
        }
        if ((!(p.is($thing))) && nprog) {
            .tell((p.namef('ref)) + " is not a VR object, you may only spawn VR objects.");
            continue;
        }
        if (!(p.has_flag('fertile))) {
            .tell((p.namef('ref)) + " is not a fertile object.");
            continue;
        }
        parents += [p];
    }
    parents = parents.compress();
    if (!parents)
        return "No capable parents.";
    if (name) {
        catch any
            name = (> $code_lib.parse_name(name) <);
        with
            return (traceback()[1])[2];
    }
    
    // spawn from the first parent, add the others
    catch any {
        new = (> (parents[1]).spawn() <);
        (> new.chparents(@parents) <);
    
        // let the user know whats up
        .tell(((("Spawned new object " + (new.namef('ref))) + " from ") + (map p in (parents) to (p.namef('ref)).to_english())) + ".");
        if (new.is($located))
            (> new.move_to(this()) <);
        if (name && ((((name[1])[1])[1]) == "$")) {
            name = (> tosym(((name[1])[1]).subrange(2)) <);
            (> new.set_objname(name) <);
            return ("Object name changed to: " + new) + ".";
        } else if (name) {
            if (!(new.has_ancestor($has_name)))
                return new + " cannot be given a VR name.";
            (> new.set_name(@name[1]) <);
            for t in (name[2])
                (> new.add_name_template(t) <);
            return (((("Renamed " + new) + " to \"") + (new.name())) + "\"") + ((new.name_templates()) ? (" (" + ((new.name_templates()).to_english())) + ")" : "");
        }
    } with {
        .tell((traceback()[1])[2]);
        if (valid(new)) {
            line = new.namef('xref);
            new.destroy();
            if (valid(new))
                return ("Unable to destroy new object " + line) + ".";
            else
                return ("Sucessfully destroyed new object " + line) + ".";
        }
    }
    
    // $#Moved 16 Dec 96 19:45 from $user.spawn_cmd() by $brandon
};

protected method .ancestors_cmd() {
    arg cmdstr, cmd, args;
    var syn, obj, maxlevels, line;
    
    (> .perms(caller(), 'command) <);
    syn = cmd + " <obj> [<levels>]";
    args = args.explode();
    if (!((args.length()) in [1, 2]))
        return syn;
    obj = .match_env_nice(args[1]);
    if ((args.length()) == 2) {
        if ((args[2]) == "all")
            maxlevels = 0;
        else
            maxlevels = abs(toint(args[2])) + 1;
    } else {
        maxlevels = 3;
    }
    line = ("Ancestors of " + obj) + ":";
    if (maxlevels) {
        line += tostr(maxlevels - 1);
        line = ((line + " level") + (((maxlevels - 1) > 1) ? "s" : "s")) + ":";
    } else {
        line += "all levels:";
    }
    .tell(line);
    .tell(obj._display_ancestors("", #[], 0, maxlevels));
    .tell("---");
};

public method .undefine_setting_cmd() {
    arg cmdstr, cmd, args;
    var name, definer, syn, name, m;
    
    syn = ("Syntax: `" + cmd) + " <definer>:<setting>`";
    if (!(m = regexp(args, "^ *([^:]+):([^ $]+)")))
        return syn;
    [definer, name] = m;
    catch any
        definer = (> .match_environment(definer) <);
    with
        return (traceback()[1])[2];
    if (!name)
        return syn;
    catch any
        (> definer.undefine_setting(name) <);
    with
        return (traceback()[1])[2];
    return ((("Undefined setting " + definer) + ":") + name) + ".";
};

public method .configure_setting_cmd() {
    arg cmdstr, cmd, args;
    var def_opts, opts, o, name, config, m, definer, syn, type, def, val;
    
    syn = ("Syntax: `" + cmd) + " <definer>:<setting>[=default] [options]`";
    def_opts = [];
    for o in (["get", "set", "parse"])
        def_opts += [[o, 1], [o + "-a?rgs", 1]];
    def_opts += [["c?lear", 1], ["f?ormat", 1], ["a?ccess", 1], ["t?ype", 1]];
    [args, opts] = $parse_lib.getopt(args, def_opts);
    args = join(args, " ");
    if (!args) {
        .tell(syn);
        for o in (def_opts.slice(1))
            .tell(((("   +" + o) + "=<") + ((o.strip("?")).replace("-", " "))) + ">");
        return "Types can be any ColdC type and \"boolean\"";
    }
    if ((m = regexp(args, "^([^=]+) *= *(.*)$")))
        [args, def] = m;
    else
        def = "";
    if ((m = regexp(args, "^([^:]+) *: *([\@a-z0-9-]+)")))
        [definer, name] = m;
    else
        definer = args;
    catch any
        definer = (> .match_environment(definer) <);
    with
        return (traceback()[1])[2];
    if (!name)
        return syn;
    
    // setup some default config opts based off the desired type
    config = #[];
    if ((m = "t?ype" in (opts.slice(1)))) {
        type = (| ((opts[m])[4]).to_symbol() |);
        if ((!type) || ((!($data_lib.is_valid_type(type))) && (type != 'boolean)))
            return "Types can be any ColdC type and \"boolean\"";
        switch (type) {
            case 'boolean:
                config = #[['parse, ['is_boolean]], ['format, ['format_boolean]]];
            default:
                config = #[['parse, ['is_type, type]]];
        }
    }
    
    // now build default config--not the most efficient way--but cleaner
    config = (> ._def_setcmd_opt("get", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("get-a?rgs", 'data_list, opts, config) <);
    config = (> ._def_setcmd_opt("set", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("set-a?rgs", 'data_list, opts, config) <);
    config = (> ._def_setcmd_opt("parse", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("parse-a?rgs", 'data_list, opts, config) <);
    config = (> ._def_setcmd_opt("c?lear", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("f?ormat", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("a?ccess", 'symbol, opts, config) <);
    
    // now reconfig it
    for o in (config) {
        catch any
            (> definer.set_setting_attr(name, @o) <);
        with
            .tell((traceback()[1])[2]);
    }
    .tell(((("Reconfigured setting " + definer) + ":") + name) + " as:");
    config = (definer.defined_settings())[name];
    for o in (config) {
        val = o[2];
        o = o[1];
        .tell((("    +" + strsub(tostr(o), "_", "-")) + "=") + (val[1]));
        if (listlen(val) > 1)
            .tell((("    +" + strsub(tostr(o), "_", "-")) + "-args=") + (sublist(val, 2.0).join(",")));
    }
};

public method .define_setting_cmd() {
    arg cmdstr, cmd, args;
    var def_opts, opts, o, name, config, m, definer, syn, type, def, val;
    
    syn = ("Syntax: `" + cmd) + " <definer>:<setting>[=default] [options]`";
    def_opts = [];
    for o in (["get", "set", "parse"])
        def_opts += [[o, 1], [o + "-a?rgs", 1]];
    def_opts += [["c?lear", 1], ["f?ormat", 1], ["a?ccess", 1], ["t?ype", 1]];
    [args, opts] = $parse_lib.getopt(args, def_opts);
    args = join(args, " ");
    if (!args) {
        .tell(syn);
        for o in (def_opts.slice(1))
            .tell(((("   +" + o) + "=<") + ((o.strip("?")).replace("-", " "))) + ">");
        return "Types can be any ColdC type and \"boolean\"";
    }
    if ((m = regexp(args, "^([^=]+) *= *(.*)$")))
        [args, def] = m;
    else
        def = "";
    if ((m = regexp(args, "^([^:]+) *: *([\@a-z0-9-]+)")))
        [definer, name] = m;
    else
        return syn;
    catch any
        definer = (> .match_environment(definer) <);
    with
        return (traceback()[1])[2];
    if (!name)
        return syn;
    
    // setup some default config opts based off the desired type
    config = #[];
    if ((m = "t?ype" in (opts.slice(1)))) {
        type = (| ((opts[m])[4]).to_symbol() |);
        if ((!type) || ((!($data_lib.is_valid_type(type))) && (type != 'boolean)))
            return "Types can be any ColdC type and \"boolean\"";
        switch (type) {
            case 'boolean:
                config = #[['parse, ['is_boolean]], ['format, ['format_boolean]]];
            default:
                config = #[['parse, ['is_type, type]]];
        }
    }
    
    // now build default config--not the most efficient way--but cleaner
    config = (> ._def_setcmd_opt("get", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("get-a?rgs", 'data_list, opts, config) <);
    config = (> ._def_setcmd_opt("set", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("set-a?rgs", 'data_list, opts, config) <);
    config = (> ._def_setcmd_opt("parse", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("parse-a?rgs", 'data_list, opts, config) <);
    config = (> ._def_setcmd_opt("c?lear", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("f?ormat", 'symbol, opts, config) <);
    config = (> ._def_setcmd_opt("a?ccess", 'symbol, opts, config) <);
    
    // now add it..
    catch any
        config = (> definer.define_setting(name, config) <);
    with
        return (traceback()[1])[2];
    .tell(((("-- Defined setting " + definer) + ":") + name) + " as:");
    for o in (config) {
        val = o[2];
        o = o[1];
        .tell((("    +" + strsub(tostr(o), "_", "-")) + "=") + (val[1]));
        if (listlen(val) > 1)
            .tell((("    +" + strsub(tostr(o), "_", "-")) + "-args=") + (sublist(val, 2).join(",")));
    }
    
    // and set the default value
    catch any {
        o = definer;
        o = o.set_setting(name, o, def);
        val = o.format_setting(name, o, o.get_setting(name, o));
        return ["-- Default Setting:", (("  " + name) + " = ") + val, "--"];
    } with {
        return (traceback()[1])[2];
    }
};

private method ._def_setcmd_opt() {
    arg opt, type, opts, dict;
    var i, value, m;
    
    if (!(i = opt in (opts.slice(1))))
        return dict;
    value = (opts[i])[4];
    if (!value)
        throw(~stop, ("No value for option \"" + opt) + "\".");
    catch any {
        switch (type) {
            case 'symbol:
                value = [(> value.to_symbol() <)];
            case 'data_list:
                value = (> fromliteral(value) <);
                if (type(value) != 'list)
                    value = [value];
        }
    } with {
        rethrow(~stop);
    }
    opt = opt.strip("?");
    if ((m = match_pattern(opt, "*-args"))) {
        opt = tosym(m[1]);
        if (!dict_contains(dict, opt))
            throw(~stop, ((("Arguments defined for " + opt) + " without defining ") + opt) + " method.");
        value = [(dict[opt])[1], @value];
        return dict_add(dict, opt, value);
    } else {
        return dict_add(dict, tosym(opt), value);
    }
};

public method .parse_match_with() {
    arg value, @args;
    
    if (value in ["regexp", "pattern", "begin"])
        return tosym("match_" + (value.lowercase()));
    throw(~perm, "You can match with: regexp, pattern, begin.");
    
    // $#Copied 14 Mar 97 17:47 from $thing.check_match_with() by $user_bruce
};


new object $admin: $programmer;

var $root inited = 1;
var $root owned = [$admin];
var $root manager = $admin;
var $root quota = 75000;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'command_cache, 'variables];
var $root managed = [$admin];
var $location contents = [];
var $located location = $body_cave;
var $located obvious = 1;
var $user password = "*";
var $user connected_at = 0;
var $user last_command_at = 0;
var $user connections = [];
var $user modes = #[];
var $user formatter = $mail_list;
var $user parsers = [$command_parser];
var $user context = #[['last, $body_cave]];
var $user task_connections = #[];
var $programmer eval_prefix = #[["me", "me = this()"], ["here", "here = this().location()"]];
var $admin shutdown_started = 0;
var $command_aliases command_aliases = [];
var $mail_list letters = #[];
var $mail_list letters_index = #[];
var $mail_list senders = 1;
var $mail_list readers = [];
var $mail_list notify = [$admin];
var $mail_list last_letter = 0;
var $mail_list mail = [];
var $mail_ui subscribed = #[[$admin, [791485891, 0]]];
var $mail_ui current = #[['location, 0], ['list, $admin]];
var $described prose = [];
var $has_name name = ['prop, "Generic Admin", "Generic Admin"];
var $has_commands local = #[["@del-t?ask|@kill", [["@del-t?ask|@kill", "*", "@del-t?ask|@kill <any>", 'del_task_cmd, #[[1, ['any, []]]]]]], ["@backup", [["@backup", "", "@backup", 'backup_cmd, #[]]]], ["@shutdown", [["@shutdown", "*", "@shutdown <any>", 'shutdown_cmd, #[[1, ['any, []]]]]]], ["@mojo", [["@mojo", "*", "@mojo <any>", 'mojo_cmd, #[[1, ['any, []]]]]]], ["@adjust|@promote", [["@adjust|@promote", "* to *", "@adjust|@promote <user> to <any>", 'adjust_cmd, #[[1, ['user, []]], [3, ['any, []]]]]]], ["@new-password|@newpw?d", [["@new-password|@newpw?d", "*", "@new-password|@newpw?d <user>", 'new_password_cmd, #[[1, ['user, []]]]]]], ["@task?s", [["@task?s", "*", "@task?s <any>", 'tasks_cmd, #[[1, ['any, []]]]]]], ["@core", [["@core", "*", "@core <list object>", 'core_cmd, #[[1, ['list, ['object, []]]]]]]], ["@rehash-all", [["@rehash-all", "*", "@rehash-all <any:-p?urge>", 'rehash_all_cmd, #[[1, ['any_opt, [["p?urge"]]]]]]]], ["@reap", [["@reap", "*", "@reap <any>", 'reap_cmd, #[[1, ['any, []]]]]]]];
var $channel_ui channel_dict = #[];
var $channel_ui active_channels = #[];
var $foundation defined_msgs = #[["mojo-on", #[['branches, ["general", "actor"]]]], ["mojo-off", #[['branches, ["general", "actor"]]]], ["mojo-look", #[['branches, ["general", "actor"]]]]];
var $foundation msgs = #[["mojo-on", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, "'s eyes glow as Mojo courses through ", <$generator, ["actor.pp", [], [], 'gen_actorpp]>, " body."], #[['this, $admin]]]>], ["actor", <$ctext_frob, [["Your eyes glow as Mojo courses through your body."], #[['this, $admin]]]>]]], ["mojo-off", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, "'s eyes stop glowing as the Mojo leaves ", <$generator, ["actor.pp", [], [], 'gen_actorpp]>, " body."], #[['this, $admin]]]>], ["actor", <$ctext_frob, [["Your eyes stop glowing as the Mojo leaves your body."], #[['this, $admin]]]>]]], ["mojo-look", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, "'s eyes ", <$generator, ["mojo.what", [], [], 'gen_mojowhat]>, "glow from Mojo."], #[['this, $admin]]]>], ["actor", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, "'s eyes ", <$generator, ["mojo.what", [], [], 'gen_mojowhat]>, "glow from mojo."], #[['this, $admin]]]>]]]];
var $thing gender = $gender_neuter;
var $command_cache local_cache = #[["@del-t", ["@del-t?ask|@kill"]], ["@del-ta", ["@del-t?ask|@kill"]], ["@del-tas", ["@del-t?ask|@kill"]], ["@del-task", ["@del-t?ask|@kill"]], ["@kill", ["@del-t?ask|@kill"]], ["@backup", ["@backup"]], ["@shutdown", ["@shutdown"]], ["@mojo", ["@mojo"]], ["@adjust", ["@adjust|@promote"]], ["@promote", ["@adjust|@promote"]], ["@new-password", ["@new-password|@newpw?d"]], ["@newpw", ["@new-password|@newpw?d"]], ["@newpwd", ["@new-password|@newpw?d"]], ["@task", ["@task?s"]], ["@tasks", ["@task?s"]], ["@core", ["@core"]], ["@rehash-all", ["@rehash-all"]], ["@reap", ["@reap"]], ["@id", ["@id"]], ["@which", ["@which"]], ["@eval", ["@eval"]], ["@add-c", ["@add-c?ommand|@ac"]], ["@add-co", ["@add-c?ommand|@ac"]], ["@add-com", ["@add-c?ommand|@ac"]], ["@add-comm", ["@add-c?ommand|@ac"]], ["@add-comma", ["@add-c?ommand|@ac"]], ["@add-comman", ["@add-c?ommand|@ac"]], ["@add-command", ["@add-c?ommand|@ac"]], ["@ac", ["@add-c?ommand|@ac", "@a?ction"]], ["@del-c", ["@del-c?ommand|@dc"]], ["@del-co", ["@del-c?ommand|@dc"]], ["@del-com", ["@del-c?ommand|@dc"]], ["@del-comm", ["@del-c?ommand|@dc"]], ["@del-comma", ["@del-c?ommand|@dc"]], ["@del-comman", ["@del-c?ommand|@dc"]], ["@del-command", ["@del-c?ommand|@dc"]], ["@dc", ["@del-c?ommand|@dc"]], ["@join", ["@join"]], ["@chpar", ["@chpar?ents"]], ["@chpare", ["@chpar?ents"]], ["@chparen", ["@chpar?ents"]], ["@chparent", ["@chpar?ents"]], ["@chparents", ["@chpar?ents"]], ["@add-s", ["@add-s?hortcut|@as"]], ["@add-sh", ["@add-s?hortcut|@as"]], ["@add-sho", ["@add-s?hortcut|@as"]], ["@add-shor", ["@add-s?hortcut|@as"]], ["@add-short", ["@add-s?hortcut|@as"]], ["@add-shortc", ["@add-s?hortcut|@as"]], ["@add-shortcu", ["@add-s?hortcut|@as"]], ["@add-shortcut", ["@add-s?hortcut|@as"]], ["@as", ["@add-s?hortcut|@as"]], ["@del-m", ["@del-m?ethod|@delm?ethod|@dm"]], ["@del-me", ["@del-m?ethod|@delm?ethod|@dm"]], ["@del-met", ["@del-m?ethod|@delm?ethod|@dm"]], ["@del-meth", ["@del-m?ethod|@delm?ethod|@dm"]], ["@del-metho", ["@del-m?ethod|@delm?ethod|@dm"]], ["@del-method", ["@del-m?ethod|@delm?ethod|@dm"]], ["@delm", ["@del-m?ethod|@delm?ethod|@dm"]], ["@delme", ["@del-m?ethod|@delm?ethod|@dm"]], ["@delmet", ["@del-m?ethod|@delm?ethod|@dm"]], ["@delmeth", ["@del-m?ethod|@delm?ethod|@dm"]], ["@delmetho", ["@del-m?ethod|@delm?ethod|@dm"]], ["@delmethod", ["@del-m?ethod|@delm?ethod|@dm"]], ["@dm", ["@del-m?ethod|@delm?ethod|@dm"]], ["@rehash", ["@rehash"]], ["@trace-method", ["@trace-method|@trace"]], ["@trace", ["@trace-method|@trace"]], ["@ledit", ["@ledit"]], ["@d", ["@d?isplay"]], ["@di", ["@d?isplay"]], ["@dis", ["@d?isplay"]], ["@disp", ["@d?isplay"]], ["@displ", ["@d?isplay"]], ["@displa", ["@d?isplay"]], ["@display", ["@d?isplay"]], ["@program", ["@program"]], ["@del-v", ["@del-v?ariable|@dv"]], ["@del-va", ["@del-v?ariable|@dv"]], ["@del-var", ["@del-v?ariable|@dv"]], ["@del-vari", ["@del-v?ariable|@dv"]], ["@del-varia", ["@del-v?ariable|@dv"]], ["@del-variab", ["@del-v?ariable|@dv"]], ["@del-variabl", ["@del-v?ariable|@dv"]], ["@del-variable", ["@del-v?ariable|@dv"]], ["@dv", ["@del-v?ariable|@dv"]], ["@show", ["@show"]], ["@mv", ["@mv|@move|@cp|@copy", "@mv|@move"]], ["@move", ["@mv|@move|@cp|@copy", "@mv|@move"]], ["@cp", ["@mv|@move|@cp|@copy"]], ["@copy", ["@mv|@move|@cp|@copy"]], ["@del-s", ["@del-s?hortcut|@ds"]], ["@del-sh", ["@del-s?hortcut|@ds"]], ["@del-sho", ["@del-s?hortcut|@ds"]], ["@del-shor", ["@del-s?hortcut|@ds"]], ["@del-short", ["@del-s?hortcut|@ds"]], ["@del-shortc", ["@del-s?hortcut|@ds"]], ["@del-shortcu", ["@del-s?hortcut|@ds"]], ["@del-shortcut", ["@del-s?hortcut|@ds"]], ["@ds", ["@del-s?hortcut|@ds"]], ["@add-p", ["@add-p?arent|@ap"]], ["@add-pa", ["@add-p?arent|@ap"]], ["@add-par", ["@add-p?arent|@ap"]], ["@add-pare", ["@add-p?arent|@ap"]], ["@add-paren", ["@add-p?arent|@ap"]], ["@add-parent", ["@add-p?arent|@ap"]], ["@ap", ["@add-p?arent|@ap"]], ["@del-p", ["@del-p?arent|@dp"]], ["@del-pa", ["@del-p?arent|@dp"]], ["@del-par", ["@del-p?arent|@dp"]], ["@del-pare", ["@del-p?arent|@dp"]], ["@del-paren", ["@del-p?arent|@dp"]], ["@del-parent", ["@del-p?arent|@dp"]], ["@dp", ["@del-p?arent|@dp"]], ["@grep", ["@grep"]], ["@chmod", ["@chmod|@mmod|@omod|@chflag?s"]], ["@mmod", ["@chmod|@mmod|@omod|@chflag?s"]], ["@omod", ["@chmod|@mmod|@omod|@chflag?s"]], ["@chflag", ["@chmod|@mmod|@omod|@chflag?s"]], ["@chflags", ["@chmod|@mmod|@omod|@chflag?s"]], ["@dump", ["@dump"]], ["@list", ["@list"]], ["@add-v", ["@add-v?ariable|@av"]], ["@add-va", ["@add-v?ariable|@av"]], ["@add-var", ["@add-v?ariable|@av"]], ["@add-vari", ["@add-v?ariable|@av"]], ["@add-varia", ["@add-v?ariable|@av"]], ["@add-variab", ["@add-v?ariable|@av"]], ["@add-variabl", ["@add-v?ariable|@av"]], ["@add-variable", ["@add-v?ariable|@av"]], ["@av", ["@add-v?ariable|@av"]], ["@hl", ["@hl?ist|@help-list"]], ["@hli", ["@hl?ist|@help-list"]], ["@hlis", ["@hl?ist|@help-list"]], ["@hlist", ["@hl?ist|@help-list"]], ["@help-list", ["@hl?ist|@help-list"]], ["@hw", ["@hw?rite|@help-write"]], ["@hwr", ["@hw?rite|@help-write"]], ["@hwri", ["@hw?rite|@help-write"]], ["@hwrit", ["@hw?rite|@help-write"]], ["@hwrite", ["@hw?rite|@help-write"]], ["@help-write", ["@hw?rite|@help-write"]], ["@spawn", ["@spawn"]], ["@ancestors", ["@ancestors"]], ["@nh", ["@nh?n|@new-help|@new-help-node"]], ["@nhn", ["@nh?n|@new-help|@new-help-node"]], ["@new-help", ["@nh?n|@new-help|@new-help-node"]], ["@new-help-node", ["@nh?n|@new-help|@new-help-node"]], ["@config-set", ["@config-set?ting|@configure-set?ting"]], ["@config-sett", ["@config-set?ting|@configure-set?ting"]], ["@config-setti", ["@config-set?ting|@configure-set?ting"]], ["@config-settin", ["@config-set?ting|@configure-set?ting"]], ["@config-setting", ["@config-set?ting|@configure-set?ting"]], ["@configure-set", ["@config-set?ting|@configure-set?ting"]], ["@configure-sett", ["@config-set?ting|@configure-set?ting"]], ["@configure-setti", ["@config-set?ting|@configure-set?ting"]], ["@configure-settin", ["@config-set?ting|@configure-set?ting"]], ["@configure-setting", ["@config-set?ting|@configure-set?ting"]], ["@def-set", ["@def-set?ting|@define-set?ting"]], ["@def-sett", ["@def-set?ting|@define-set?ting"]], ["@def-setti", ["@def-set?ting|@define-set?ting"]], ["@def-settin", ["@def-set?ting|@define-set?ting"]], ["@def-setting", ["@def-set?ting|@define-set?ting"]], ["@define-set", ["@def-set?ting|@define-set?ting"]], ["@define-sett", ["@def-set?ting|@define-set?ting"]], ["@define-setti", ["@def-set?ting|@define-set?ting"]], ["@define-settin", ["@def-set?ting|@define-set?ting"]], ["@define-setting", ["@def-set?ting|@define-set?ting"]], ["@undef-set", ["@undef-set?ting|@undefine-set?ting"]], ["@undef-sett", ["@undef-set?ting|@undefine-set?ting"]], ["@undef-setti", ["@undef-set?ting|@undefine-set?ting"]], ["@undef-settin", ["@undef-set?ting|@undefine-set?ting"]], ["@undef-setting", ["@undef-set?ting|@undefine-set?ting"]], ["@undefine-set", ["@undef-set?ting|@undefine-set?ting"]], ["@undefine-sett", ["@undef-set?ting|@undefine-set?ting"]], ["@undefine-setti", ["@undef-set?ting|@undefine-set?ting"]], ["@undefine-settin", ["@undef-set?ting|@undefine-set?ting"]], ["@undefine-setting", ["@undef-set?ting|@undefine-set?ting"]], ["@descend", ["@descend?ants"]], ["@descenda", ["@descend?ants"]], ["@descendan", ["@descend?ants"]], ["@descendant", ["@descend?ants"]], ["@descendants", ["@descend?ants"]], ["@realm", ["@realm?s"]], ["@realms", ["@realm?s"]], ["@child", ["@child?ren|@kids"]], ["@childr", ["@child?ren|@kids"]], ["@childre", ["@child?ren|@kids"]], ["@children", ["@child?ren|@kids"]], ["@kids", ["@child?ren|@kids"]], ["@par", ["@par?ents"]], ["@pare", ["@par?ents"]], ["@paren", ["@par?ents"]], ["@parent", ["@par?ents"]], ["@parents", ["@par?ents"]], ["@build", ["@build"]], ["@attach", ["@attach"]], ["@destroy", ["@destroy"]], ["@dig", ["@dig"]], ["@teleport", ["@teleport|@go"]], ["@go", ["@teleport|@go"]], ["@def-msg", ["@def-msg|@def-message"]], ["@def-message", ["@def-msg|@def-message"]], ["@undef-msg", ["@undef-msg|@undef-message"]], ["@undef-message", ["@undef-msg|@undef-message"]], ["@quit", ["@quit"]], ["i", ["i?nventory"]], ["in", ["i?nventory"]], ["inv", ["i?nventory"]], ["inve", ["i?nventory"]], ["inven", ["i?nventory"]], ["invent", ["i?nventory"]], ["invento", ["i?nventory"]], ["inventor", ["i?nventory"]], ["inventory", ["i?nventory"]], ["@audit", ["@audit"]], ["@who", ["@who"]], ["@del-command-a", ["@del-command-a?lias|@dca?lias"]], ["@del-command-al", ["@del-command-a?lias|@dca?lias"]], ["@del-command-ali", ["@del-command-a?lias|@dca?lias"]], ["@del-command-alia", ["@del-command-a?lias|@dca?lias"]], ["@del-command-alias", ["@del-command-a?lias|@dca?lias"]], ["@dca", ["@del-command-a?lias|@dca?lias"]], ["@dcal", ["@del-command-a?lias|@dca?lias"]], ["@dcali", ["@del-command-a?lias|@dca?lias"]], ["@dcalia", ["@del-command-a?lias|@dca?lias"]], ["@dcalias", ["@del-command-a?lias|@dca?lias"]], ["@command-a", ["@command-a?liases|@ca?liases"]], ["@command-al", ["@command-a?liases|@ca?liases"]], ["@command-ali", ["@command-a?liases|@ca?liases"]], ["@command-alia", ["@command-a?liases|@ca?liases"]], ["@command-alias", ["@command-a?liases|@ca?liases"]], ["@command-aliase", ["@command-a?liases|@ca?liases"]], ["@command-aliases", ["@command-a?liases|@ca?liases"]], ["@ca", ["@command-a?liases|@ca?liases"]], ["@cal", ["@command-a?liases|@ca?liases"]], ["@cali", ["@command-a?liases|@ca?liases"]], ["@calia", ["@command-a?liases|@ca?liases"]], ["@calias", ["@command-a?liases|@ca?liases"]], ["@caliase", ["@command-a?liases|@ca?liases"]], ["@caliases", ["@command-a?liases|@ca?liases"]], ["@add-command-a", ["@add-command-a?lias|@aca?lias"]], ["@add-command-al", ["@add-command-a?lias|@aca?lias"]], ["@add-command-ali", ["@add-command-a?lias|@aca?lias"]], ["@add-command-alia", ["@add-command-a?lias|@aca?lias"]], ["@add-command-alias", ["@add-command-a?lias|@aca?lias"]], ["@aca", ["@add-command-a?lias|@aca?lias"]], ["@acal", ["@add-command-a?lias|@aca?lias"]], ["@acali", ["@add-command-a?lias|@aca?lias"]], ["@acalia", ["@add-command-a?lias|@aca?lias"]], ["@acalias", ["@add-command-a?lias|@aca?lias"]], ["@com", ["@com?mands"]], ["@comm", ["@com?mands"]], ["@comma", ["@com?mands"]], ["@comman", ["@com?mands"]], ["@command", ["@com?mands"]], ["@commands", ["@com?mands"]], ["@news", ["@news"]], ["@forget", ["@forget"]], ["@whereis", ["@whereis|@where-is"]], ["@where-is", ["@whereis|@where-is"]], ["@ways", ["@ways"]], ["@password", ["@password|@passwd"]], ["@passwd", ["@password|@passwd"]], ["@age", ["@age"]], ["@context", ["@context"]], ["get", ["get|take"]], ["take", ["get|take"]], ["drop", ["drop"]], ["@rename", ["@rename"]], ["@add-writer", ["@add-writer|@aw"]], ["@aw", ["@add-writer|@aw"]], ["@del-writer", ["@del-writer|@dw"]], ["@dw", ["@del-writer|@dw"]], ["@chman", ["@chman?age"]], ["@chmana", ["@chman?age"]], ["@chmanag", ["@chman?age"]], ["@chmanage", ["@chman?age"]], ["@manage", ["@manage?d"]], ["@managed", ["@manage?d"]], ["@remember", ["@remember"]], ["@remembered", ["@remembered"]], ["give", ["give|put"]], ["put", ["give|put"]], ["discard", ["discard"]], ["@writes", ["@writes"]], ["@trusted", ["@trusted?-by"]], ["@trusted-", ["@trusted?-by"]], ["@trusted-b", ["@trusted?-by"]], ["@trusted-by", ["@trusted?-by"]], ["@add-trust", ["@add-trust?ee|@at"]], ["@add-truste", ["@add-trust?ee|@at"]], ["@add-trustee", ["@add-trust?ee|@at"]], ["@at", ["@add-trust?ee|@at"]], ["@del-trust", ["@del-trust?ee|@dt"]], ["@del-truste", ["@del-trust?ee|@dt"]], ["@del-trustee", ["@del-trust?ee|@dt"]], ["@dt", ["@del-trust?ee|@dt"]], ["@monitor", ["@monitor"]], ["@ex", ["@ex?amine"]], ["@exa", ["@ex?amine"]], ["@exam", ["@ex?amine"]], ["@exami", ["@ex?amine"]], ["@examin", ["@ex?amine"]], ["@examine", ["@ex?amine"]], ["@map", ["@map"]], ["@finger", ["@finger|@ustat"]], ["@ustat", ["@finger|@ustat"]], ["@trusts", ["@trusts|@trustee?s"]], ["@trustee", ["@trusts|@trustee?s"]], ["@trustees", ["@trusts|@trustee?s"]], ["@writers", ["@writers"]], ["@manager", ["@manager"]], ["view", ["view"]], ["@desc", ["@desc?ribe|@prose"]], ["@descr", ["@desc?ribe|@prose"]], ["@descri", ["@desc?ribe|@prose"]], ["@describ", ["@desc?ribe|@prose"]], ["@describe", ["@desc?ribe|@prose"]], ["@prose", ["@desc?ribe|@prose"]], ["l", ["l?ook|exam?ine"]], ["lo", ["l?ook|exam?ine"]], ["loo", ["l?ook|exam?ine"]], ["look", ["l?ook|exam?ine"]], ["exam", ["l?ook|exam?ine"]], ["exami", ["l?ook|exam?ine"]], ["examin", ["l?ook|exam?ine"]], ["examine", ["l?ook|exam?ine"]], ["walk", ["walk|go"]], ["go", ["walk|go"]], ["@ant", ["@ant|@add-name-template"]], ["@add-name-template", ["@ant|@add-name-template"]], ["@dnt", ["@dnt|@del-name-template"]], ["@del-name-template", ["@dnt|@del-name-template"]], ["@name-template", ["@name-template?s|@template?s"]], ["@name-templates", ["@name-template?s|@template?s"]], ["@template", ["@name-template?s|@template?s"]], ["@templates", ["@name-template?s|@template?s"]], ["@register", ["@register|@register-name"]], ["@register-name", ["@register|@register-name"]], ["@unregister", ["@unregister|@unregister-name"]], ["@unregister-name", ["@unregister|@unregister-name"]], ["@registered", ["@registered"]], ["@page", ["@page"]], ["@paste", ["@paste?-to"]], ["@paste-", ["@paste?-to"]], ["@paste-t", ["@paste?-to"]], ["@paste-to", ["@paste?-to"]], ["@new", ["@new"]], ["@status", ["@status|@uptime"]], ["@uptime", ["@status|@uptime"]], ["@msg", ["@msg?s|@message?s"]], ["@msgs", ["@msg?s|@message?s"]], ["@message", ["@msg?s|@message?s"]], ["@messages", ["@msg?s|@message?s"]], ["@date", ["@date|@time"]], ["@time", ["@date|@time"]], ["@set", ["@set"]], ["wh", ["wh?isper"]], ["whi", ["wh?isper"]], ["whis", ["wh?isper"]], ["whisp", ["wh?isper"]], ["whispe", ["wh?isper"]], ["whisper", ["wh?isper"]], ["say", ["say"]], ["to", ["to"]], ["emote", ["emote"]], ["quote", ["quote"]], ["spoof", ["spoof"]], ["pose", ["pose"]], ["think", ["think"]], ["wear", ["wear"]], ["remove", ["remove|shed"]], ["shed", ["remove|shed"]], ["@a", ["@a?ction"]], ["@act", ["@a?ction"]], ["@acti", ["@a?ction"]], ["@actio", ["@a?ction"]], ["@action", ["@a?ction"]], ["@sub", ["@sub?scribed"]], ["@subs", ["@sub?scribed"]], ["@subsc", ["@sub?scribed"]], ["@subscr", ["@sub?scribed"]], ["@subscri", ["@sub?scribed"]], ["@subscrib", ["@sub?scribed"]], ["@subscribe", ["@sub?scribed"]], ["@subscribed", ["@sub?scribed"]], ["@unsub", ["@unsub?scribed"]], ["@unsubs", ["@unsub?scribed"]], ["@unsubsc", ["@unsub?scribed"]], ["@unsubscr", ["@unsub?scribed"]], ["@unsubscri", ["@unsub?scribed"]], ["@unsubscrib", ["@unsub?scribed"]], ["@unsubscribe", ["@unsub?scribed"]], ["@unsubscribed", ["@unsub?scribed"]], ["@mail-list", ["@mail-list?s"]], ["@mail-lists", ["@mail-list?s"]], ["@read", ["@read"]], ["@remove-m", ["@remove-m?ail|@rmm?ail"]], ["@remove-ma", ["@remove-m?ail|@rmm?ail"]], ["@remove-mai", ["@remove-m?ail|@rmm?ail"]], ["@remove-mail", ["@remove-m?ail|@rmm?ail"]], ["@rmm", ["@remove-m?ail|@rmm?ail"]], ["@rmma", ["@remove-m?ail|@rmm?ail"]], ["@rmmai", ["@remove-m?ail|@rmm?ail"]], ["@rmmail", ["@remove-m?ail|@rmm?ail"]], ["@nn", ["@nn|@next-new"]], ["@next-new", ["@nn|@next-new"]], ["@mail", ["@mail"]], ["@send", ["@send"]], ["@create", ["@create"]], ["help", ["help"]], ["page", ["page"]], ["who", ["who"]], ["quit", ["quit"]], ["news", ["news"]], ["@gender", ["@gender"]], ["uptime", ["uptime"]], ["@alias", ["@alias"]], ["@check", ["@check|@paranoid"]], ["@paranoid", ["@check|@paranoid"]], ["@version", ["@version"]], ["@lock", ["@lock"]], ["@unlock", ["@unlock"]], ["@help", ["@help"]], ["@mcp-upload-session", ["@mcp-upload-session"]], ["@cleanup-sessions", ["@cleanup-sessions|@c-s?essions"]], ["@c-s", ["@cleanup-sessions|@c-s?essions"]], ["@c-se", ["@cleanup-sessions|@c-s?essions"]], ["@c-ses", ["@cleanup-sessions|@c-s?essions"]], ["@c-sess", ["@cleanup-sessions|@c-s?essions"]], ["@c-sessi", ["@cleanup-sessions|@c-s?essions"]], ["@c-sessio", ["@cleanup-sessions|@c-s?essions"]], ["@c-session", ["@cleanup-sessions|@c-s?essions"]], ["@c-sessions", ["@cleanup-sessions|@c-s?essions"]], ["@edit", ["@edit"]], ["@desc-c", ["@desc-c?hannel"]], ["@desc-ch", ["@desc-c?hannel"]], ["@desc-cha", ["@desc-c?hannel"]], ["@desc-chan", ["@desc-c?hannel"]], ["@desc-chann", ["@desc-c?hannel"]], ["@desc-channe", ["@desc-c?hannel"]], ["@desc-channel", ["@desc-c?hannel"]], ["@ch", ["@ch?annels"]], ["@cha", ["@ch?annels"]], ["@chan", ["@ch?annels"]], ["@chann", ["@ch?annels"]], ["@channe", ["@ch?annels"]], ["@channel", ["@ch?annels"]], ["@channels", ["@ch?annels"]], ["@join-lock-channel", ["@join-lock-channel|@jlc"]], ["@jlc", ["@join-lock-channel|@jlc"]], ["@leave-lock-channel", ["@leave-lock-channel|@llc"]], ["@llc", ["@leave-lock-channel|@llc"]], ["@use-lock-channel", ["@use-lock-channel|@ulc"]], ["@ulc", ["@use-lock-channel|@ulc"]], ["@add-channel-manager", ["@add-channel-manager|@acm"]], ["@acm", ["@add-channel-manager|@acm"]], ["@del-channel-manager", ["@del-channel-manager|@dcm"]], ["@dcm", ["@del-channel-manager|@dcm"]], ["@add-ch", ["@add-ch?annel|@addcom"]], ["@add-cha", ["@add-ch?annel|@addcom"]], ["@add-chan", ["@add-ch?annel|@addcom"]], ["@add-chann", ["@add-ch?annel|@addcom"]], ["@add-channe", ["@add-ch?annel|@addcom"]], ["@add-channel", ["@add-ch?annel|@addcom"]], ["@addcom", ["@add-ch?annel|@addcom"]], ["@del-ch", ["@del-ch?annel|@delcom"]], ["@del-cha", ["@del-ch?annel|@delcom"]], ["@del-chan", ["@del-ch?annel|@delcom"]], ["@del-chann", ["@del-ch?annel|@delcom"]], ["@del-channe", ["@del-ch?annel|@delcom"]], ["@del-channel", ["@del-ch?annel|@delcom"]], ["@delcom", ["@del-ch?annel|@delcom"]], ["@purge-channel", ["@purge-channel"]], ["@blahblahblah", ["@blahblahblah"]]];
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 1]]]]];
var $command_cache shortcut_cache = [[";*", ['eval_cmd, ["eval", 1]]], ["--*", ['remote_cmd, ["@page ", "", " with ", 1]]], ["-* *", ['remote_cmd, ["@page ", 1, " with ", 2]]], ["|*", ['quote_cmd, ["quote ", 1]]], ["\"*", ['say_cmd, ["say ", 1]]], ["%*", ['think_cmd, ["think ", 1]]], ["!*", ['spoof_cmd, ["spoof ", 1]]], [",*,*", ['esay_cmd, ["esay ", 1, " with ", 2]]], [":*", ['emote_cmd, ["emote ", 1]]], [".*", ['pose_cmd, ["pose ", 1]]], ["''*", ['to_say_cmd, ["to ", "", " say ", 1]]], ["'* *", ['to_say_cmd, ["to ", 1, " say ", 2]]], ["?*", ['help_cmd, ["?", 1]]]];
var $root settings = #[["home", $body_cave]];

root method .init_admin() {
    $sys.new_admin();
};

protected method .del_task_cmd() {
    arg cmdstr, com, args;
    var syn, sys, task, t;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    syn = ("Syntax: `" + com) + " [*]<task>`";
    args = explode(args);
    if (!args)
        return syn;
    for t in (args) {
        if (t && ((t[1]) == "*")) {
            t = substr(t, 2);
            sys = 1;
        }
        task = toint(t);
        if (!task) {
            .tell(syn, ("Invalid task '" + t) + "'");
            continue;
        }
        if (sys) {
            $scheduler.cancel(task);
            .tell(("System task " + tostr(task)) + " canceled.");
        } else {
            catch any
                $scheduler.del_task(task);
            with
                (> .tell_error(syn, (traceback()[1])[2]) <);
            .tell(("Task " + tostr(task)) + " deleted.");
        }
    }
};

protected method .tasks_cmd() {
    arg cmdstr, cmd, args;
    var out, task, queue, time, args, fmt, tfmt, info, suspend, preempt, line, x;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    out = [];
    if (args) {
        for x in (explode(args)) {
            if ((x[1]) == "*")
                x = substr(x, 2);
            if (!(task = (| $scheduler.task_info(toint(x)) |))) {
                .tell(("Invalid task '" + x) + "'");
                continue;
            }
            out = ["Task: " + ((task[1])[1]), "", strfmt("  %8l %15L %s", "TICKS", "USER", "METHOD")];
    
            // add an option to not restrict this
            for info in (sublist(task, 3))
                out += [strfmt("  %8l %15L %s.%s()", info[7], info[4], info[1], info[8])];
        }
        return out;
    }
    queue = $scheduler.task_queue();
    if (queue) {
        tfmt = "%d %h %y %H:%M:%S";
        fmt = "%5L %20L %s";
        time = $time.format(tfmt);
        out = [strfmt(fmt, "ID", "EXEC TIME", "TASK"), strfmt(fmt, "---", "---------", "----")];
        fmt += ".%s(%s)";
        for task in (queue) {
            args = toliteral(task[8]);
            out += [strfmt(fmt, task[1], $time.format(tfmt, task[2]), task[4], task[6], substr(args, 2, strlen(args) - 2))];
        }
        if (out)
            out = ["-- Database Tasks --"] + out;
    }
    if ((queue = tasks())) {
        suspend = [];
        preempt = [];
        fmt = "%8l%8l%24L";
        for task in (queue) {
            info = $scheduler.task_info(task);
            line = strfmt(fmt, (info[1])[1], (info[3])[7], ((((info[3])[1]) + ".") + ((info[3])[8])) + "()", (info[3])[4]);
            task = ($scheduler.suspended_task(task)).join();
            if (strlen(task) > 38)
                task = substr(task, 1, 35) + "...";
            if (info[2])
                preempt += [line + task];
            else
                suspend += [line + task];
        }
        tfmt = strfmt(fmt, "TASK", "TICKS", "METHOD") + "RESUMABLE BY";
        if (preempt)
            out += ["-- Preempted Tasks --", tfmt] + preempt;
        if (suspend)
            out += ["-- Suspended Tasks --", tfmt] + suspend;
    }
    return out || "-- No suspended or preempted tasks --";
    
    // $#Edited: 21 Nov 96 20:44 $miro
};

protected method .backup_cmd() {
    arg cmdstr, com;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    .tell("Starting backup.");
    $sys.do_backup(this());
    .tell("Done.");
};

protected method .shutdown_cmd() {
    arg cmdstr, com, @args;
    var time, opt, why, answer, ans;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    args = $parse_lib.getopt(args.join(), [["t?ime", 1]]);
    opt = "t?ime" in ((args[2]).slice(1));
    if (opt && ((((args[2])[opt])[4]).is_numeric()))
        time = toint(((args[2])[opt])[4]);
    else
        time = 5;
    if (!(why = (args[1]).join()))
        why = "Administrator's whim.";
    .tell(((("Shutdown " + ($motd.server_name())) + " in ") + tostr(time)) + " minutes");
    .tell("Reason for shutdown: " + why);
    ans = .prompt("Is this correct? [yes]: ");
    if (!ans)
        ans = "yes";
    if (!(ans in ["yes", "y"])) {
        .tell("I didn't think so, aborting shutdown...");
        return;
    }
    .tell("Ok!");
    $sys.do_shutdown(time, why);
};

protected method .adjust_cmd() {
    arg cmdstr, cmd, who, prep, str;
    var i, what, p, pwd, o, email, valid;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    valid = #[["user", $user], ["builder", $builder], ["programmer", $programmer], ["admin", $admin]];
    what = (str.explode()).last();
    if (!(valid.contains(what)))
        return ("Promote to: " + ((valid.keys()).to_english())) + ".";
    
    // mail them the password--do this first incase we fail here
    if ($guest in (who.parents())) {
        who.set_setting("title", $user, "");
        pwd = $code_lib.random_password();
        who.set_password(pwd);
        email = who.user_info("email");
        if (!email)
            return (who.namef('ref)) + " does not have an email address!";
        catch any {
            $smtp.sendmail(email, ("[" + ($motd.server_name())) + "] password change.", ((("The password for the user " + (who.name())) + " on ") + ($motd.server_name())) + " has been set as:", "", "    " + pwd, "", "This is an automatic message sent to the supplied address.  If this message is in error simply discard it.", "", "If no connections are made to this user within a week it will be purged.");
        } with {
            .tell_traceback(traceback());
            return "** Unable to send mail message, no changes made **";
        }
    }
    
    // selectively cleanup their 'new' parents list, retain special parents
    p = who.parents();
    for o in ([$guest] + (valid.values()))
        p = setremove(p, o);
    
    // add the parent we care about to the front, call chparents()
    // we are admins, we can handle tracebacks if they occur.
    (> who.chparents(valid[what], @p) <);
    
    // update caches.
    for o in (parents())
        o.cache_init();
    who.rehash_caches();
    
    // let'em know what we did
    what = what.add_indefinite();
    who.tell((((.name()) + " has made you ") + what) + ".");
    
    // if we changed their password, let them know that too
    if (pwd) {
        who.tell(("** Your password has been emailed to " + email) + " **");
        who.tell("** You can change it with the command: `@password` **");
    }
    (.location()).announce(((("*poof* " + (who.name())) + " is now ") + what) + ".", who, this());
    return ((("Ok, " + (who.name())) + " is now ") + what) + ".";
};

protected method .grep_cmd() {
    arg @args;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo('benice) <);
    return (> pass(@args) <);
};

protected method .mojo() {
    arg @args;
    var name;
    
    if (args)
        name = "Your ";
    else
        name = (.name()) + "'s ";
    if (this() in ($sys.system()))
        return name + "eyes glow from Mojo.";
    else
        return name + "eyes do not glow from Mojo.";
};

protected method .mojo_cmd() {
    arg cmdstr, cmd, str;
    var syn, line, vars;
    
    (> .perms(caller(), $user, $admin) <);
    syn = cmd + " on|off";
    if ((!str) || (!(str in ["on", "up", "off", "down"])))
        return .mojo(1);
    
    // this is horribly non-configurable--we need a standard set of subs.
    vars = #[["$actor", this()], ["actor", .name()], ["actor.pp", (.gender()).pronoun('pp)]];
    switch (str) {
        case "on", "up":
            $sys.add_to_system(this());
            (.location()).announce(.eval_message("mojo-on", $admin, vars));
        case "off", "down":
            $sys.del_from_system(this());
            (.location()).announce(.eval_message("mojo-off", $admin, vars));
    }
};

public method .description() {
    arg flags;
    var vars, m;
    
    vars = #[["$actor", this()], ["actor", .name()], ["mojo.what", ""]];
    if (!(this() in ($sys.system())))
        vars = vars.add("mojo.what", "do not ");
    m = .eval_message("mojo-look", $admin, vars);
    return (> pass(flags) <) + [m];
};

public method .logout() {
    arg @args;
    
    (| $sys.del_from_system(this()) |);
    return (> pass(@args) <);
};

protected method .check_mojo() {
    arg @benice;
    var answer, wording;
    
    if (benice)
        wording = " may require ";
    else
        wording = " requires ";
    if (!(this() in ($sys.system()))) {
        answer = .prompt(("This command" + wording) + "Mojo, turn it on? [yes] ");
        if (answer in ["no", "n"]) {
            .tell("Ok, aborting.");
            if (benice)
                return;
            throw(~stop, "");
        }
        .mojo_cmd("", "", "on");
    }
};

protected method .rehash_all_cmd() {
    arg cmdstr, cmd, args;
    var purge, c, p, o, d, objs, initted, user_interfaces, other;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    purge = (o = "p?urge" in ((args[2]).slice(1))) && (((args[2])[o])[3]);
    if (purge) {
        .tell("Building descendants list..");
        pause();
        pause();
        user_interfaces = $user_interfaces.descendants();
        other = (((($command_cache.children()).setremove($user_interfaces)).mmap('descendants)).flatten()).compress();
        pause();
        pause();
    
        // go atomic, we do not want confused users trying to run commands that
        // do not exist...
        $sys.atomic(1);
        for o in (other + user_interfaces) {
            if (o.is_command_cache())
                .tell("Purging " + (o.namef('ref)));
            (| o.purge_caches() |);
            refresh();
        }
    
        // get back 'other' caches--nobody said this was going to be fast.
        for o in (other) {
            o.rehash_caches();
            refresh();
        }
    }
    
    // user caches
    initted = #[];
    for o in ((| $user_db.connected() |) || [this()]) {
        for p in ((| o.parents() |) || []) {
            if (!(initted.contains(p))) {
                .tell("Initializing " + (p.namef('ref)));
                catch any {
                    (> p.rehash_caches() <);
                } with {
                    .tell(("--- traceback from " + p) + ".cache_init():");
                    .tell_traceback(traceback());
                    .tell("---");
                }
                initted = initted.add(p, 1);
            }
        }
        refresh();
    }
    
    // ok, good...
    $sys.atomic(0);
    return "Done...";
};

protected method .finger_cmd() {
    arg cmdstr, cmd, who;
    var out, tmp;
    
    out = (> pass(cmdstr, cmd, who) <);
    if (!($sys.is_system(this())))
        return out;
    if (who.connected()) {
        out += ["  Connections:"];
        for tmp in (who.connections())
            out += [(((("    " + tmp) + ": [") + ($time.format("%v/%T", tmp.active_since()))) + "] ") + (tmp.address())];
    }
    tmp = who.quota_byte_usage();
    return (out += ["  Quota:", "    Total:     " + ((who.quota()).to_english()), "    Used:      " + (tmp.to_english()), "    Remaining: " + (((who.quota()) - tmp).to_english())]);
};

protected method .new_password_cmd(): nooverride {
    arg cmdstr, cmd, user;
    var new, email;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    email = user.user_info("email");
    if (!email)
        return (user.namef('ref)) + " does not have an email address!";
    new = $code_lib.random_password();
    catch any {
        $smtp.sendmail(email, ("[" + ($motd.server_name())) + "] password change.", ((("The password for the user " + (user.name())) + " on ") + ($motd.server_name())) + " has been changed to:", "", "    " + new, "", "This is an automatic message sent to the supplied address.  If this message is in error simply discard it.");
    } with {
        .tell_traceback(traceback());
        return "** Unable to send mail message, password not changed **";
    }
    user.set_password(new);
    user.tell([((("Your password has been reset by " + (.name())) + ".  The new password has been emailed to ") + email) + "."]);
    .tell((("You reset " + (user.name())) + "'s password to: ") + new);
};

protected method .core_cmd() {
    arg cmdstr, cmd, objs;
    var o, obj;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    for obj in (objs) {
        obj.add_flag('core);
        obj.change_manager(obj);
        for o in (obj.writers('literal))
            obj.del_writer(o);
        refresh();
        .tell(("Made " + (obj.namef('core))) + " a core object.");
    }
};

protected method .reap_users_cmd() {
    arg cmdstr, cmd, args;
    var u, thresh, t, reap, m, last, tl, v;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    
    // figure threshold
    if (args) {
        catch any
            thresh = $time.from_english(args);
        with
            return "You must specify the time.";
    } else {
        thresh = (86400 * 30) * 3;
    }
    t = time();
    reap = [];
    .tell([("--- Reap Possibilities starting " + ($time.to_english(thresh))) + " ago", strfmt("%28L %4l %4l %12l %l", "User", "MNGD", "WRTS", "Last On", "Age"), strfmt("%28L %4l %4l %12l %l", "----", "----", "----", "-------", "---")]);
    for u in ($user.descendants()) {
        if ((u.connected()) || ((u.has_flag('core)) || (u.is($admin))))
            continue;
        tl = (last = abs(u.connected_at()));
        if ((tl + thresh) > t)
            continue;
        m = "";
        tl = t - tl;
        if (tl / 31449600) {
            v = tl / 31449600;
            m = (v + " year") + ((v > 1) ? "s" : "");
            tl = tl % 31449600;
        }
        if (tl / 2592000) {
            v = tl / 2592000;
            m += (((m ? " " : "") + v) + " month") + ((v > 1) ? "s" : "");
            tl = tl % 2592000;
        }
        if (tl / 604800) {
            v = tl / 604800;
            m += (((m ? " " : "") + v) + " week") + ((v > 1) ? "s" : "");
        }
        if (!m)
            m = "newborn";
        reap += [[last, strfmt("%28L %4l %4l %12l %l", u.namef('xref), listlen(u.managed()), listlen(u.writes()), $time.format("%v", last), m)]];
    }
    .tell(((reap.sort()).slice(2)).reverse());
    return "---";
    
    // $#Edited: 19 Nov 96 17:32 $miro
};

public method .uninit_admin() {
    $sys.old_admin();
};

protected method .reap_cmd() {
    arg cmdstr, cmd, args;
    var opts, thresh, i;
    
    (> .perms(caller(), 'command) <);
    (> .check_mojo() <);
    [args, opts] = $parse_lib.getopt(args, [["t?ime", 1], ["m?ail", 0]]);
    args = args.join();
    if ((i = "t?ime" in (opts.slice(1)))) {
        catch any
            thresh = $time.from_english((opts[i])[4]);
        with
            return (traceback()[1])[2];
    }
    if ("m?ail" in (opts.slice(1)))
        return .reap_mail(args, thresh || (86400 * 7));
    if (args)
        return (> .reap_user(args) <);
    else
        return (> .reap_list(thresh || ((86400 * 30) * 3)) <);
};

private method .reap_list() {
    arg thresh;
    var t, reap, u, tl, m, v, last;
    
    t = time();
    reap = [];
    .tell([("--- Reap Possibilities (Not connected for " + ($time.to_english(thresh))) + ")", strfmt("%28L %4l %4l %12l %l", "User", "MNGD", "WRTS", "Last On", "Age"), strfmt("%28L %4l %4l %12l %l", "----", "----", "----", "-------", "---")]);
    for u in ($user.descendants()) {
        if ((u.connected()) || ((u.has_flag('core)) || (u.is($admin))))
            continue;
        tl = (last = abs(u.connected_at()));
        if ((tl + thresh) > t)
            continue;
        m = "";
        tl = t - tl;
        if (tl / 31449600) {
            v = tl / 31449600;
            m = (v + " year") + ((v > 1) ? "s" : "");
            tl = tl % 31449600;
        }
        if (tl / 2592000) {
            v = tl / 2592000;
            m += (((m ? " " : "") + v) + " month") + ((v > 1) ? "s" : "");
            tl = tl % 2592000;
        }
        if (tl / 604800) {
            v = tl / 604800;
            m += (((m ? " " : "") + v) + " week") + ((v > 1) ? "s" : "");
        }
        if (!m)
            m = "newborn";
        reap += [[last, strfmt("%28L %4l %4l %12l %l", u.namef('xref), listlen(u.managed()), listlen(u.writes()), $time.format("%v", last), m)]];
    }
    .tell(((reap.sort()).slice(2)).reverse());
    return "---";
};

private method .reap_user() {
    arg str;
    var user, ans, managed, obj, reapq, nuke, name, keep;
    
    user = (| $user_db.search(str) |);
    if (!user) {
        catch any
            user = $object_lib.to_dbref(str);
        with
            return ("Unable to find user " + str) + ".";
    }
    if (!(> $parse_lib.ask(("Reap " + (user.namef('ref))) + "? [no] ") <))
        return "Aborting reap.";
    managed = setremove(user.managed(), user);
    nuke = (keep = []);
    reapq = ["", ("Reap this object managed by " + (user.namef('ref))) + "? [yes] "];
    for obj in (managed) {
        .tell("");
        .tell($object_lib.format_object(obj, 0));
        if ((> $parse_lib.ask(reapq, "(yes|y)", "yes") <))
            nuke = setadd(nuke, obj);
        else
            keep = setadd(keep, obj);
    }
    if (nuke) {
        .tell(["WRT TST Object", "--- --- ------"]);
        for obj in (nuke)
            .tell(strfmt("%3r %3r %s", listlen(obj.writers('literal)), listlen(obj.trusted('literal)), obj.namef('ref)));
        .tell("");
        if ((> $parse_lib.ask("Destroy these objects? [yes] ", "(yes|y)", "yes") <)) {
            for obj in (nuke) {
                name = obj.namef('ref);
                catch any {
                    obj.destroy();
                } with {
                    .tell("--- While Destroying " + name);
                    .tell_traceback(traceback());
                }
            }
        }
    }
    for obj in (keep)
        .tell((("Changed Manager for " + (obj.namef('ref))) + " to ") + ($reaper.namef('ref)));
    if (!(> $parse_lib.ask(("Destroy " + (user.namef('ref))) + "? ") <))
        return "Not destroying " + (user.namef('ref));
    name = user.namef('ref);
    catch any {
        user.destroy();
    } with {
        .tell("--- While Destroying " + name);
        .tell_traceback(traceback());
    }
    return ("Done reaping " + name) + ".";
};

private method .reap_mail() {
    arg str, interval;
    var email, msg, subj, ps, po, user;
    
    user = (| $user_db.search(str) |);
    if (!user) {
        catch any
            user = $object_lib.to_dbref(str);
        with
            return ("Unable to find user " + str) + ".";
    }
    email = user.user_info("email");
    ps = (user.gender()).pronoun('ps);
    po = (user.gender()).pronoun('po);
    subj = ("[" + ($motd.server_name())) + "] IMMINENT USER REAPING";
    msg = (((((((((("Your user account " + (user.namef('ref))) + " on ") + ($motd.server_name())) + " is slated for reaping, possibly due to inactivity.  If you do not connect within ") + ($time.to_english(interval))) + " ") + ps) + " and all objects managed by ") + po) + " will be destroyed.  This is an automatic message sent to the supplied email address.  If this message is in error simply discard it.").wrap_lines(75);
    .tell("---");
    .tell("To: " + email);
    .tell("Subject: " + subj);
    .tell("");
    .tell(msg);
    .tell("---");
    if (!(> $parse_lib.ask("Send this email message? [yes] ", "(yes|y)", "yes") <))
        return "Message not sent.";
    catch any {
        $smtp.sendmail(email, subj, @msg);
    } with {
        .tell_traceback(traceback());
        return "** Unable to send message";
    }
    return "Message sent.";
};


new object $on_location: $located_location;

var $root manager = $on_location;
var $root created_on = 809991549;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "note", "note"];
var $described prose = [];
var $location contents = [];
var $located location = $nowhere;
var $located obvious = 1;
var $root managed = [$on_location];
var $root owned = [$on_location];
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 1]]]]];
var $command_cache shortcut_cache = [];
var $thing gender = $gender_neuter;

public method .description() {
    arg flags;
    var line;
    
    line = ((("You see " + ((.contents()).map_to_english('namef))) + " on ") + (.name())) + ".";
    return (> pass(flags) <) + [line];
};


new object $in_location: $located_location;

var $root manager = $in_location;
var $root created_on = 809991552;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "note", "note"];
var $described prose = [];
var $location contents = [];
var $located location = $nowhere;
var $located obvious = 1;
var $root managed = [$in_location];
var $root owned = [$in_location];
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 1]]]]];
var $command_cache shortcut_cache = [];
var $thing gender = $gender_neuter;

public method .description() {
    arg flags;
    var line;
    
    line = ((("You see " + ((.contents()).map_to_english('namef))) + " in ") + (.name())) + ".";
    return (> pass(flags) <) + [line];
};


new object $lost_and_found: $in_location;

var $root manager = $lost_and_found;
var $root created_on = 806811775;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $command_cache shortcut_cache = [];
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 19]]]], ["@reactions", [["@reactions"], #[[$robot, 2]]]], ["erase", [["erase"], #[[$note, 2]]]], ["read", [["read|nread"], #[[$note, 2]]]], ["nread", [["read|nread"], #[[$note, 2]]]], ["write", [["write"], #[[$note, 2]]]], ["copy", [["copy"], #[[$note, 2]]]]];
var $has_name name = ['prop, "Lost and Found box", "Lost and Found box"];
var $described prose = [];
var $location contents = [$robot, $located, $nothing, $wearable_frob, $map_of_taobh_thiar];
var $located location = $void;
var $located obvious = 1;
var $thing lock = <$object_lock_frob, [$void]>;
var $root managed = [$lost_and_found];
var $root owned = [$lost_and_found];
var $thing gender = $gender_neuter;
var $root settings = #[["home", $lost_and_found]];


new object $trash: $located_location;

var $root manager = $trash;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 830126811;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['uniq, "System Trash Can", "the System Trash Can"];
var $described prose = <$ctext_frob, [["When you discard something, it goes here if you do not manage it."], #[]]>;
var $location contents = [];
var $located location = $void;
var $located obvious = 1;
var $root inited = 1;
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 1]]]]];
var $trash items = #[];
var $root managed = [$trash];
var $root owned = [$trash];
var $command_cache shortcut_cache = [];
var $thing gender = $gender_neuter;

public method .did_leave() {
    arg place;
    
    (> pass(place) <);
    (| (items = items.del(sender())) |);
};

public method .did_arrive() {
    arg place;
    var msg;
    
    (> pass(place) <);
    (| (items = items.add(sender(), time())) |);
};

public method .del_sender_from_contents() {
    pass();
    items = dict_del(items, sender());
    
    // $#Edited: 22 Mar 97 12:03 $brandon
};


new object $realm_settings: $foundation;

var $root manager = $realm_settings;
var $root child_index = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854028767;
var $root inited = 1;
var $root defined_settings = #[["map-position", #[['get, ['get_realm_setting]], ['parse, ['parse_map_position]], ['format, ['format_map_position]]]], ["propagate", #[['get, ['get_realm_setting]], ['parse, ['is_boolean]], ['format, ['format_boolean]]]]];
var $root settings = #[["propagate", 0], ["map-position", [0, 0, "99", #504]]];
var $root managed = [$realm_settings];

public method .get_realm_setting() {
    arg name, definer, @args;
    var v, t;
    
    t = this();
    if (.has_ancestor($place)) {
        if ((.local_settings_dict(definer)).contains(name))
            return .get_local_setting(name, definer);
        t = .realm();
    }
    return t.get_setting(name, definer, @args);
};

public method .will_propagate() {
    return .get_setting("propagate", definer());
};

public method .parse_map_position() {
    arg value;
    
    if (type(value) == 'list)
        value = value.join();
    value = (| (value.match_pattern("window *,* tag * on *")).mmap('trim) |);
    if (!value)
        throw(~parse, "Syntax: window <x>,<y> tag <tag> on <mapobject>");
    return (> [toint(value[1]), toint(value[2]), value[3], $object_lib.to_dbref(value[4])] <);
};

public method .format_map_position() {
    arg value;
    
    return "window %l, %l tag %l on %l".format(@value);
};


new object $place: $location, $realm_settings;

var $root child_index = 434;
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $described prose = [];
var $has_name name = ['uniq, "place", "the place"];
var $place realm = $realm_of_creation;
var $place exits = [];
var $place darkness = 0;
var $location contents = [];
var $place entrances = 0;
var $command_cache shortcut_cache = [];
var $root manager = $place;
var $has_commands local = #[];
var $root owned = [$place];
var $foundation defined_msgs = #[["housekeeper", #[['branches, ["general"]]]], ["connect", #[['branches, ["general"]]]], ["disconnect", #[['branches, ["general"]]]]];
var $foundation msgs = #[["housekeeper", #[["general", <$ctext_frob, [["Dust bunnies rise from under the furniture to envelope ", <$generator, ["actor", [], [], 'gen_actor]>, "'s comatose form, leaving behind a small pile of musty lint."], #[['this, $place]]]>]]], ["connect", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " wakes up."], #[['this, $place]]]>]]], ["disconnect", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " falls asleep."], #[['this, $place]]]>]]]];
var $root defined_settings = #[["public-home", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["realm", #[['get, ['realm]], ['set, ['set_setting_realm]], ['parse, ['parse_realm_setting]], ['clear, ['clear_realm_setting]]]], ["darkness", #[['get, ['darkness]], ['set, ['set_darkness]], ['parse, ['is_type, 'integer]]]]];
var $root settings = #[["public-home", 0], ["map-position", [0, 0, "99", #504]]];
var $root managed = [$place];

root method .init_place() {
    exits = (entrances = []);
    .set_realm($realm_of_creation);
};

root method .uninit_place() {
    var x;
    
    for x in (exits + entrances)
        (| x.place_destroyed(this()) |);
    (| realm.place_destroyed(this()) |);
    (| $place_db.place_destroyed(this()) |);
};

public method .environment() {
    return pass() + exits;
};

public method .description() {
    arg f;
    var e;
    
    e = .visible_exits();
    return ((> pass(f) <) + (.format_contents(f))) + (.format_exits(e, f));
};

public method .exits() {
    if (!(caller() in [$command_parser, $user]))
        (> .perms(sender()) <);
    return exits;
};

public method .did_connect() {
    (> .perms(caller(), $user) <);
    if ((.visibility()) >= 0)
        .announce(.eval_message("connect", $place, #[["$actor", sender()], ["actor", sender().name()], ["$here", this()], ["here", .name()]]), sender());
};

public method .did_disconnect() {
    (> .perms(caller(), $user) <);
    if ((.visibility()) >= 0)
        .announce(.eval_message("disconnect", $place, #[["$actor", sender()], ["actor", sender().name()], ["$here", this()], ["here", .name()]]), sender());
};

public method .realm() {
    arg @args;
    
    return realm;
};

public method .did_housekeep() {
    arg who;
    var m, v;
    
    (> .perms(sender(), $housekeeper) <);
    .announce(.eval_message("housekeeper", $place, #[["$actor", who], ["actor", who.name()], ["$here", this()], ["here", .name()]]));
};

public method .set_name() {
    arg new_name, @args;
    var old_name;
    
    old_name = .name();
    (> pass(new_name, @args) <);
    (| $place_db.room_changed_name(old_name) |);
};

public method .set_realm() {
    arg value;
    
    (caller() == $realm) || ((sender() == this()) || (> .perms(sender()) <));
    realm = value.new();
    
    // $#Edited: 15 Feb 97 19:53 $miro
};

public method .format_exits() {
    arg exits, flags;
    var output, e, exits, line, actor, how;
    
    actor = flags['actor];
    how = (flags['actor]).get_setting("exit-style", $user);
    switch (how) {
        case 'none:
            return [];
        case 'brief:
            if (!exits)
                return [];
            return ["Exits: " + ((exits.mmap('name)).to_english("none"))];
        case 'templates:
            output = [];
            for e in (exits) {
                if (e.name_templates())
                    output += [(((e.name()) + " (") + ((e.name_templates()).to_english())) + ")"];
                else
                    output += [e.name()];
            }
            return output ? ["Exits: " + (output.to_english())] : [];
        case 'long:
            output = [];
            for e in (exits)
                output += [(("  " + (e.name())) + " to ") + ((e.dest()).name())];
            return output ? ["Exits: "] + (output.lcolumnize(actor.linelen())) : [];
        case 'verbose:
            output = [];
            for e in (exits) {
                if (e.name_templates())
                    line = (((e.name()) + " (") + ((e.name_templates()).to_english("no templates"))) + ")";
                else
                    line = e.name();
                output += [(("  " + line) + " to ") + ((e.dest()).name())];
            }
            return output ? ["Exits: ", @output.lcolumnize(actor.linelen())] : [];
    }
    return [];
};

public method .format_contents() {
    arg flags;
    var users, br, exclude, actor, objects, output, obj, line;
    
    // called by .description
    users = [];
    objects = [];
    actor = flags['actor];
    exclude = (| flags['exclude] |) || [];
    for obj in (.contents()) {
        if ((!(obj in exclude)) && ((obj != actor) && (| obj.is_obvious_to(actor) |))) {
            if (obj.has_ancestor($body))
                users += [obj.namef('nactivity)];
            else
                objects += [obj.name()];
        }
    }
    output = [];
    br = (<$format, ["br", [], [], 'do_br]>);
    if (users) {
        line = ($list.to_english(users)) + " ";
        line = (line + (((users.length()) > 1) ? "are" : "is")) + " here.";
    
        //output += [br, line];
        output += [line];
    }
    if (objects) {
        line = "You see ";
        line = (line + ($list.to_english(objects))) + " here.";
    
        //output += [br, line];
        output += [line];
    }
    return output;
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .visible_exits() {
    var obv, exit;
    
    obv = [];
    for exit in (exits) {
        if ((exit.visibility()) >= (.visibility()))
            obv += [exit];
    }
    return obv;
};

public method .realm_name() {
    arg @ctype;
    
    [(ctype ?= "text/plain")] = ctype;
    switch (ctype) {
        case "text/html":
            return (((.hname()) + " (") + ((| realm.realm_name() |) || "<unknown>")) + ")";
        default:
            return (((.name()) + " (") + ((| realm.realm_name() |) || "<unknown>")) + ")";
    }
    
    // $#Edited: 20 Dec 96 06:44 $miro
};

public method .will_attach() {
    arg type, @by_whom;
    
    [(by_whom ?= sender())] = by_whom;
    if ((!(| .trusts(by_whom) |)) && (!(.get_setting("public-home", $place))))
        throw(~perm, "Place is not publicly extendable.");
};

public method .visible_exits_formatted() {
    arg actor, how;
    var output, ex, exits, line;
    
    exits = .visible_exits();
    switch (how) {
        case 'none:
            return [];
        case 'brief:
            if (!exits)
                return [];
            return ["Exits: " + ($list.to_english($list.mmap(exits, 'name), "none"))];
        case 'average:
            output = [];
            for ex in (exits) {
                line = (ex.name()) + " (";
                line += $list.to_english(ex.name_templates(), "no, templates");
                output += [line];
            }
            return output ? ["Exits: " + ($list.to_english(output))] : [];
        case 'long:
            output = [];
            for ex in (exits)
                output += [((("  " + (ex.name())) + " (to ") + ((ex.dest()).name())) + ")"];
            return output ? ["Exits: ", @$list.lcolumnize(output, actor.linelen())] : [];
        case 'verbose:
            output = [];
            for ex in (exits) {
                line = ex.prose();
                if (!line)
                    line = [ex.name()];
                output += [line[1]];
            }
            return output ? [output.join()] : [];
    }
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .place_destroyed() {
    arg place;
    var e;
    
    (> .perms(caller(), $place, $realm) <);
    for e in (exits) {
        if ((e.dest()) == sender())
            e.destination_destroyed();
    }
};

public method .set_objname(): nooverride {
    arg new_objname;
    
    if ((caller() != $place) && (!(sender() in ($sys.system()))))
        throw(~perm, "Place objname can only be changed by $place.");
    (> pass(new_objname) <);
};

public method .attach_exit() {
    arg type, exit;
    
    if (!(caller().is($exit)))
        throw(~perm, "Caller is not an exit.");
    if (type == 'source) {
        .add_object_to_remote_cache(exit);
        (| (.realm()).add_exit_to(exit.dest()) |);
        exits = setadd(exits, exit);
    } else {
        entrances = setadd(entrances, exit.source());
    }
    
    // $#Edited: 19 Feb 97 02:23 $miro
};

public method .rehash_caches() {
    var exit;
    
    (> pass() <);
    for exit in (exits)
        (> .add_object_to_remote_cache(exit) <);
};

public method .darkness() {
    arg @args;
    
    return darkness;
};

public method .set_setting_realm() {
    arg name, definer, value, @args;
    
    (> .perms(sender()) <);
    .set_realm(value);
};

public method .prose() {
    arg @no_default;
    var ret;
    
    ret = pass(@no_default);
    if (type(ret) == 'frob)
        (| (ret = ret.set_vars((.realm()).ctext_variables())) |);
    return ret;
    
    // $#Edited: 19 Feb 97 02:23 $miro
};

public method .detach_exit() {
    arg type, exit;
    
    if (!(caller().is($exit)))
        throw(~perm, "Caller is not an exit.");
    if (type == 'source) {
        .del_object_from_remote_cache(exit);
        exits = setremove(exits, exit);
    } else {
        entrances = setremove(entrances, exit.source());
    }
};

public method .entrances() {
    (| .perms(caller(), definer(), $command_parser) |) || (> .perms(sender()) <);
    return entrances;
};

root method .core_place(): nooverride {
    .set_realm($realm_of_creation);
};

public method .update_exit_frob() {
    arg this, what, new, @remove;
    
    (> .perms(caller(), $exit_frob) <);
    exits = setremove(exits, (<sender(), this>));
    if (remove)
        this = this.del(what);
    else
        this = this.add(what, new);
    exits = setadd(exits, (<sender(), this>));
    return (<sender(), this>);
};

public method .is_connected_to() {
    arg dest;
    var i;
    
    (> .perms(caller(), $realm) <);
    for i in (exits) {
        if ((| dest == (i.dest()) |))
            return 1;
    }
    return 0;
    
    // $#Edited: 15 Feb 97 19:46 $miro
};

public method .parse_realm_setting() {
    arg value, @args;
    var realm;
    
    realm = $place_lib.match_realm(value);
    if (!realm)
        throw(~invrealm, ("Unable to find the realm " + value) + ".");
    else if (!(realm.is($realm)))
        throw(~invrealm, (realm.namef('ref)) + " is not a realm.");
    return realm;
};

public method .clear_realm_setting() {
    arg name;
    
    (> .perms(sender()) <);
    realm = $realm_of_creation;
};


new object $nowhere: $place;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $location contents = [$on_location, $in_location];
var $described prose = [];
var $has_name name = ['prop, "Nowhere", "Nowhere"];
var $place exits = [];
var $place realm = $realm_of_creation;
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 4]]]]];
var $root manager = $nowhere;
var $root managed = [$nowhere];
var $root owned = [$nowhere];
var $place entrances = [];
var $event_handler hooks = #[['movement, []], ['user_connect, []]];
var $event_handler hooked = #[];
var $root child_index = 7;
var $command_cache shortcut_cache = [];
var $root settings = #[["propagate", 1], ["public-home", 0]];

public method .description() {
    arg flags;
    
    return [];
    
    // $#Edited: 27 Nov 96 14:25 $brandon
};

public method .announce() {
    arg @args;
    
    // $#Edited: 27 Nov 96 14:37 $brandon
};


new object $body_cave: $place;

var $root manager = $body_cave;
var $root created_on = 808865147;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $command_cache shortcut_cache = [];
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 16]]]]];
var $has_name name = ['uniq, "Body Cave", "the Body Cave"];
var $described prose = [];
var $location contents = [$reaper, $builder, $guest, $no_one, $programmer, $admin, $player, $storyteller];
var $place exits = [];
var $place realm = $realm_of_creation;
var $physical visibility = -100;
var $root managed = [$body_cave];
var $root owned = [$body_cave];
var $place entrances = [];
var $root settings = #[["public-home", 1], ["propagate", 1]];

public method .announce() {
    arg @who_cares;
    
    // $#Edited: 18 Aug 96 22:06 $jenner
};


new object $void: $place;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $location contents = [$thing, $lost_and_found, $thing_frob, $trash, $located_location, $body, $user, $reaper_log, $log, $http_log, $note, $slate, $login_log, $generic_map, $exit_frob];
var $described prose = ["A place existing for the soul purpose of doing so, when it wishes be."];
var $has_name name = ['uniq, "Void", "the Void"];
var $place exits = [];
var $place realm = $realm_of_creation;
var $command_cache shortcut_cache = [];
var $command_cache remote_cache = #[["@boot", [["@boot"], #[[$thing, 30]]]], ["read", [["read", "read|nread"], #[[$log, 8], [$note, 12]]]], ["erase", [["erase"], #[[$note, 12]]]], ["nread", [["read|nread"], #[[$note, 12]]]], ["write", [["write"], #[[$note, 12]]]], ["copy", [["copy"], #[[$note, 12]]]], ["@lock", [["@lock"], #[[$exit, 2]]]], ["@unlock", [["@unlock"], #[[$exit, 2]]]], ["open", [["open"], #[[$exit, 2]]]], ["close", [["close"], #[[$exit, 2]]]]];
var $root manager = $void;
var $root managed = [$void];
var $root owned = [$void];
var $place entrances = [];
var $root settings = #[["propagate", 1]];


new object $the_pit: $place;

var $root inited = 1;
var $root manager = $the_pit;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $location contents = [];
var $described prose = <$ctext_frob, [["A cozy atmosphere pervades this room, a small hideaway where people can come to relax and socialize. The cement walls are covered with various scribbles burn marks, and stains of unrecognizable origin."], #[]]>;
var $has_name name = ['prop, "The Pit", "The Pit"];
var $place exits = [];
var $place realm = $realm_of_creation;
var $root managed = [$the_pit];
var $root owned = [$the_pit];
var $place entrances = [];
var $event_handler hooks = #[['movement, [#131, #502, #9]], ['user_connect, [#131, #502]]];
var $event_handler hooked = #[[#9, ['movement]]];
var $root settings = #[["public-home", 0], ["map-position", [0, 0, "00", $map_of_taobh_thiar]], ["propagate", 1]];
var $has_commands local = #[];
var $command_cache shortcut_cache = [];

root method .core_the_pit() {
    .set_prose("A cozy atmosphere pervades this room, a small hideaway where people can come to relax and socialize. The cement walls are covered with various scribbles burn marks, and stains of unrecognizable origin.");
};


new object $frob: $core;

var $root child_index = 11;
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root manager = $frob;
var $root managed = [$frob];
var $root owned = [$frob];

public method .unparse() {
    arg rep;
    
    return ((("<" + this()) + ", ") + rep) + ">";
    
    // $#Edited: 13 Jun 96 01:14 $levi
};

public method .new() {
    return (<this(), #[]>);
};

public method .to_frob() {
    arg value;
    
    // this differs from .new in it's application
    return (<this(), value>);
};

frob method .value(): nooverride {
    arg value;
    
    return value;
};

frob method .has_ancestor() {
    arg this, ancestor;
    
    return (> pass(ancestor) <);
};

frob method .is() {
    arg this, ancestor;
    
    return (> pass(ancestor) <);
};

public method .new_with() {
    arg value;
    
    return (<this(), value>);
};

frob method .destroy() {
    arg this;
    
    throw(~perm, "You cannot destroy a frob, try 'discard'");
    
    // $#Edited: 29 Nov 96 12:44 $brandon
};


new object $network: $core;

var $root child_index = 4;
var $root manager = $network;
var $root created_on = 809051864;
var $root inited = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root managed = [$network];
var $root owned = [$network];

public method ._ip(): native;

bind_native .ip() ._ip();

public method .ip() {
    arg @args;
    
    return (> ._ip(@args) <);
};

public method ._hostname(): native;

bind_native .hostname() ._hostname();

public method .hostname() {
    arg @args;
    
    return (> ._hostname(@args) <);
};


new object $connection_interface: $network, $command_cache, $frob;

var $root child_index = 5;
var $root manager = $connection_interface;
var $root created_on = 809051864;
var $root inited = 1;
var $root quota_exempt = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $connection_interface connection = 0;
var $root managed = [$connection_interface];
var $root owned = [$connection_interface];

public method .parse_line() {
    arg this, line;
    var cmd, c, match, parsed, i, m, a, u;
    
    catch any {
        while (line && ((line[1]) == " "))
            line = line.subrange(2);
        if (!line) {
            return .null_cmd(this, line);
        } else {
            cmd = line.explode();
            cmd = [line, cmd[1], ((cmd.subrange(2)).join()) || ""];
            c = (| .match_in_local_cache(@cmd) |);
            if (c && ((c[1]) == 'local)) {
                // screw duplicates, take the first match
                match = (c[2])[1];
                m = match[2];
                i = match[5];
                parsed = i.keys();
                for a in [1 .. m.length()] {
                    if (a in parsed)
                        m = m.replace(a + 2, (> $command_lib.convert_arg((i[a])[1], m[a + 2], $no_one, ((i[a])[2]) ? ((i[a])[2])[1] : $no_one, $no_one) <));
                }
                return (> .(match[4])(this, @m) <);
            }
            return (> .invalid_cmd(this, line) <);
        }
    } with {
        if (((traceback()[1])[3]) != 'no_traceback) {
            (this['connection]).write($parse_lib.traceback(traceback()));
            return 'disconnect;
        }
    }
    
    // $#Edited: 18 Jul 96 14:56 $levi
};

public method .connection_going_away() {
    arg @args;
    
    (> .close() <);
};

public method .linelen() {
    arg @args;
    
    return 79;
};

public method .send() {
    arg @args;
    
    return (> .write(@args) <);
};

public method .write() {
    arg this, what;
    
    return (> (this['connection]).write(what) <);
};

public method .null_cmd() {
    arg @args;
    
    return 'disconnect;
};

public method .invalid_cmd() {
    arg @args;
    
    return 'disconnect;
};

public method .connection() {
    return connection;
};

public method .tell() {
    arg @args;
    
    (> .write(@args) <);
};

public method .new() {
    arg c;
    var i;
    
    (> .perms(caller(), $connection) <);
    i = .spawn();
    i.set_connection(c);
    return i;
};

public method .new_connection() {
    arg this, host, port;
    
};

public method .set_connection() {
    arg c;
    
    (> .perms(caller(), definer()) <);
    connection = c;
};

public method .daemon_shutdown() {
    var i;
    
    (> .perms(caller(), $connection) <);
    for i in (.children())
        (> i.close() <);
};

public method .close() {
    (> .perms(sender()) <);
    (> $sys.destroy_sender() <);
};

public method .connection_starting() {
    arg addr, port;
    
    // $#Edited: 03 Dec 96 01:05 $brad
};


new object $http_interface: $connection_interface;

var $root child_index = 12830;
var $root manager = $http_interface;
var $root owned = [$http_interface];
var $root created_on = 809075102;
var $root inited = 1;
var $root quota_exempt = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root managed = [$http_interface];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $http_interface keep_alive = 0;
var $http_interface cache = [];
var $http_interface method = "GET";
var $http_interface http = "HTTP/0.9";
var $http_interface status = 405;
var $http_interface URI = "/";
var $http_interface bytes = 205;
var $http_interface ctype = 0;
var $http_interface cached = 0;
var $http_interface full = 0;
var $http_interface header = 0;
var $http_interface info = 0;
var $command_cache shortcut_cache = [];

root method .init_http_interface() {
    .reset_variables();
    
    // $#Edited: 30 Oct 96 12:56 $brandon
};

protected method .close_interface() {
    arg @args;
    var c;
    
    if ((!args) && keep_alive) {
        .reset_variables();
        return;
    }
    (.connection()).close();
};

protected method .send_header() {
    arg @lines;
    
    if (!full)
        return;
    (.connection()).write(([((http + " ") + status) + " ", "Server: ColdWeb/2.0 (Virtual Environment)", "Connection: " + (keep_alive ? "Keep-Alive" : "close"), "Content-type: " + ctype, "Content-length: " + bytes] + lines) + [""]);
};

protected method .respond() {
    arg body;
    var host;
    
    if (type(body) != 'buffer)
        body = strings_to_buf(body);
    bytes = buflen(body);
    .send_header();
    (.connection()).write(body);
    host = (.connection()).address();
    .close_interface();
    .log_request(host);
};

protected method .respond_with_file() {
    arg fstat;
    var host;
    
    bytes = fstat[2];
    .send_header();
    (.connection()).cwritef("html" + URI);
    host = (.connection()).address();
    .close_interface();
    .log_request(host);
};

protected method .find_filename() {
    var file, actual, stat, ifiles, i;
    
    stat = (| $file.fstat("html" + URI) |);
    if (!stat) {
        ifiles = ["home.html", "index.html", "welcome.html"];
        file = URI;
        actual = URI;
        if ((file[strlen(file)]) != "/")
            file += "/";
        while ((!stat) && ifiles) {
            URI = file + (ifiles[1]);
            stat = (| $file.fstat("html" + URI) |);
            ifiles = ifiles.delete(1);
        }
        if (!stat) {
            URI = actual;
            status = 404;
            .respond($http.response(status, ("Unable to find URL " + toliteral(URI)) + "."));
            return 0;
        }
    }
    if ((i = URI.rindex("."))) {
        switch (URI.subrange(i + 1)) {
            case "txt":
                ctype = "text/plain";
            case "gif":
                ctype = "image/gif";
        }
    }
    return stat;
};

protected method .http_method_POST() {
    var len, body, part;
    
    len = (| header["Content-Length"] |);
    if ((len == ~keynf) || (!len))
        (> .respond($sys.response((status = 400), "No Content-Length.")) <);
    body = (.connection()).handle_POST_input(toint(len[1]));
    
    // handle this differently in normal situations
    for part in (body)
        info = info.add('args, (info['args]).union(part.explode_http_encoding()));
    .http_method_GET();
    
    // $#Edited: 30 Oct 96 12:56 $brandon
};

public method .connection_going_away() {
    arg @args;
    
    (> .close() <);
};

public method .parse_line() {
    arg line;
    var match;
    
    if (!method) {
        if (!line)
            return;
        line = explode(line);
        if (listlen(line) != 3) {
            (.connection()).write($http.response(400, "HTTP/0.9 not supported."));
            .close();
            return;
        }
        if ((match = regexp(line[1], "^(GET|POST|HEAD)$")))
            method = match[1];
        else
            return .die(405, ("Method: \"" + (line[1])) + "\".");
        URI = line[2];
        http = line[3];
    } else if (line) {
        if ((match = regexp(line, "^([^:]+): *(.+)$"))) {
            if (((match[1]) == "Connection") && ((match[2]) == "Keep-Alive"))
                keep_alive = 1;
            else
                header = header.add_elem(@match);
        }
    } else {
        // parse the URI
        info = URI.explode_url();
        URI = "/" + ((info['path]).join("/"));
        catch any {
            (> .(tosym("http_method_" + method))() <);
        } with {
            if (error() != ~stop)
                .respond($parse_lib.html_traceback(traceback(), (status = 500)));
        }
    }
};

protected method .log_request() {
    arg host;
    var line;
    
    line = (((((((((((host + " - - [") + ($time.format("%d %h %y %H:%M"))) + "] \"") + method) + " ") + URI) + " ") + http) + "\" ") + tostr(status)) + " ") + tostr(bytes);
    if ((| header["User-Agent"] |))
        line = (line + ";; ") + ((header["User-Agent"]).join());
    $sys.log(line);
    
    // $#Edited: 30 Oct 96 12:56 $brandon
};

protected method .http_method_GET() {
    var target, gate;
    
    if (URI == "/") {
        .respond($motd.build_html());
    } else if (match_begin(URI, "/~")) {
        target = (| $user_db.search(substr((info['path])[1], 2)) |);
        info = (| target.user_info("home-page") |);
        if (info) {
            status = 302;
            .redirect(info);
        } else {
            status = 404;
            .respond($http.response(404, "Unable to find user " + substr((info['path])[1], 2)));
        }
    } else if (match_begin(URI, "/bin")) {
        target = sublist(info['path], 2);
        if (!target) {
            status = 300;
            return .respond($http.response(300, ["Multiple Choices: "] + ($http.list_gateways())));
        }
        gate = target[1];
        target = sublist(target, 2);
        if (!(($http.gateways()).contains(gate))) {
            status = 502;
            .respond($http.response(502, ("Bad gateway: \"" + gate) + "\""));
        } else if (!gate) {
            status = 300;
            return .respond($http.response(300, ["Multiple Choices: "] + ($http.list_gateways())));
        } else {
            catch any {
                info = (> $http.(tosym("bin_" + gate))(target, info, header) <);
                status = info[1];
                if ((type(info[2]) == 'buffer) || (status != 200))
                    return .respond(info[2]);
                return .respond((info[2]) + ($http.page_tail()));
            } with {
                status = 500;
                return .respond($parse_lib.html_traceback(traceback(), 500));
            }
        }
    } else if ((info = .find_filename())) {
        .respond_with_file(info);
    }
};

protected method .http_method_HEAD() {
    var info, target, gate, head, host;
    
    head = [];
    status = 200;
    if (URI == "/") {
        bytes = buflen(strings_to_buf($motd.build_html()));
    } else if (match_begin(URI, "/~")) {
        target = (| $user_db.search(substr((info['path])[1], 2)) |);
        info = (| target.user_info("home-page") |);
        if (info) {
            status = 302;
            bytes = buflen(strings_to_buf($http.response(302, "Relocated at: " + location)));
            head += ["Location: " + info];
        } else {
            status = 404;
            bytes = buflen(strings_to_buf($http.response(404, "Unable to find user " + substr((info['path])[1], 2))));
        }
    } else if (match_begin(URI, "/bin")) {
        target = sublist(info['path], 2);
        if (!target) {
            status = 300;
            bytes = buflen(strings_to_buf($http.response(300, ["Multiple Choices: "] + ($http_lib.list_gateways()))));
        } else {
            gate = target[1];
            target = sublist(target, 2);
            if (!(($http.gateways()).contains(gate))) {
                status = 502;
                bytes = buflen(strings_to_buf($http.response(502, ("Bad gateway: \"" + gate) + "\"")));
            } else if (!gate) {
                status = 300;
                bytes = buflen(strings_to_buf($http.response(300, ["Multiple Choices: "] + ($http_lib.list_gateways()))));
            } else {
                catch any {
                    info = (> $http.(tosym("bin_" + gate))(@target) <);
                    status = info[1];
                    if ((type(info[2]) == 'buffer) || (status != 200))
                        bytes = buflen(strings_to_buf(info[2]));
                    else
                        bytes = buflen(strings_to_buf((info[2]) + ($http.page_tail())));
                } with {
                    status = 500;
                    bytes = buflen(strings_to_buf($parse_lib.html_traceback(traceback(), 500)));
                }
            }
        }
    } else if ((info = .find_filename())) {
        bytes = fstat[2];
    }
    .send_header(@head);
    host = (.connection()).address();
    .close_interface();
    .log_request(host);
};

protected method .reset_variables() {
    method = "";
    http = "HTTP/1.0";
    status = 200;
    URI = "";
    bytes = 0;
    ctype = $http.html_version();
    full = 1;
    header = #[];
    
    // $#Edited: 30 Oct 96 12:41 $brandon
    // $#Edited: 30 Oct 96 12:56 $brandon
};

public method .set_status() {
    arg s;
    
    (> .perms(caller(), $http_connection) <);
    status = s;
    
    // $#Edited: 30 Oct 96 12:56 $brandon
};

protected method .redirect() {
    arg location;
    var body, host, l;
    
    host = (.connection()).address();
    body = strings_to_buf($http.response(303, "Relocated at: " + location));
    bytes = buflen(body);
    .send_header("Location: " + location);
    (.connection()).write(body);
    .close_interface();
    .log_request(host);
};


new object $smtp_interface: $connection_interface, $has_name;

var $root manager = $smtp_interface;
var $root quota_exempt = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 849172060;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $root inited = 1;
var $root child_index = 129;
var $root managed = [$smtp_interface];
var $smtp_interface mail_from = 0;
var $smtp_interface cmds = #[["HELP", 'help_cmd], ["QUIT", 'quit_cmd], ["VRFY", 'verify_cmd], ["EXPN", 'verify_cmd], ["HELO", 'hello_cmd], ["MAIL", 'mail_from_cmd], ["NOOP", 'noop_cmd], ["RCPT", 'recipient_cmd], ["DATA", 'data_cmd]];
var $smtp_interface cmd_help = #[["HELP", ["HELP [<topic>]", "    For more help on any command type 'help <cmd>'"]], ["QUIT", ["QUIT", "    Ends your mail session"]], ["EXPN", ["EXPN <recipient>", "   Expand an address."]], ["VRFY", ["VRFY <recipient>", "   Verify an address."]], ["HELO", ["HELO <hostname>", "   Introduce yourself."]], ["MAIL", ["MAIL FROM: <sender>", "   Specify sender/return path."]], ["NOOP", ["NOOP", "   Do nothing"]], ["RCPT", ["RCPT TO:<recipient>", "   Specifies the recipient.  Can be used any number of times."]], ["DATA", ["DATA", "   Following data is collected as the message", "   End with a single dot"]]];
var $smtp_interface given_hostname = "";
var $smtp_interface mail_to = 0;
var $smtp_interface mail_body = 0;
var $smtp_interface mail_status = 0;
var $has_name name = ['prop, "smtp_interface", "smtp_interface"];
var $command_cache shortcut_cache = [];

public method .parse_line() {
    arg line;
    var method, cmd, args;
    
    $brad.debug(line);
    if (mail_status == 'read_body) {
        if (line == ".") {
            return .send_mail();
        } else {
            mail_body += [line];
            return;
        }
    }
    cmd = line.word(1);
    if ((line.length()) >= ((cmd.length()) + 2))
        args = line.subrange((cmd.length()) + 2);
    else
        args = "";
    catch ~keynf {
        method = definer().get_cmd(cmd);
    } with {
        (.connection()).write("500 unrecognized command");
        return 'disconenct;
    }
    return .(method)(args);
    
    // $#Edited: 30 Nov 96 03:53 $brad
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .connection_starting() {
    arg addr, port;
    
    $brad.debug("New SMTP connection");
    (.connection()).write((("220 " + ($sys.server_info('server_hostname))) + " SMTP ColdMail 0.01/0.01; ") + ($time.format("%a, %e %b %Y %T %Z")));
    
    // $#Edited: 29 Nov 96 13:34 $brad
};

public method .help_cmd() {
    arg rest;
    var i, conn;
    
    conn = .connection();
    if ((rest.length()) == 0) {
        conn.write(["214-This is ColdMail 0.01.", "214-Valid Commands:"]);
        for i in (definer().get_cmds())
            conn.write("214-  " + i);
        conn.write("214 End of Help");
    } else {
        catch ~keynf {
            rest = definer().get_cmd_help(rest);
            for i in (rest)
                conn.write("214-" + i);
            conn.write("214 End of Help");
        } with {
            conn.write(("504 HELP topic '" + rest) + "' not found.");
        }
    }
    
    // $#Edited: 29 Nov 96 15:48 $brad
};

public method .quit_cmd() {
    arg rest;
    
    (.connection()).write(("221 " + ($sys.server_info('server_hostname))) + " closing connection");
    return 'disconnect;
    
    // $#Edited: 29 Nov 96 15:44 $brad
};

public method .get_cmd() {
    arg cmd;
    
    return (> cmds[cmd] <);
    
    // $#Edited: 28 Nov 96 14:29 $brad
};

public method .get_cmd_help() {
    arg help;
    
    return (> cmd_help[help] <);
    
    // $#Edited: 28 Nov 96 14:32 $brad
};

public method .get_cmds() {
    return cmds.keys();
    
    // $#Edited: 28 Nov 96 14:37 $brad
};

public method .verify_cmd() {
    arg rest;
    var conn, user, i, out;
    
    conn = .connection();
    if ((rest.length()) == 0) {
        conn.write("501 Argument required");
    } else {
        out = [];
        for i in (rest.explode()) {
            catch ~ambig, ~listnf {
                user = .parse_user(i);
                out += [user.name()];
            } with {
                switch (error()) {
                    case ~ambig:
                        conn.write(("553 " + i) + "... user ambiguous");
                    default:
                        conn.write(("550 " + i) + "... user unknown");
                        return;
                }
            }
        }
        for i in [1 .. out.length()]
            conn.write((((((((i == (out.length())) ? "250 " : "250-") + (out[i])) + " <") + (out[i])) + "%cold@") + ($sys.server_info('server_hostname))) + ">");
    }
    
    // $#Edited: 30 Nov 96 02:59 $brad
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .hello_cmd() {
    arg rest;
    var conn;
    
    conn = .connection();
    if ((rest.length()) == 0) {
        conn.write("501 HELO requires domain address");
    } else if (given_hostname == 0) {
        conn.write(((("250 " + ($sys.server_info('server_hostname))) + " Hello ") + (conn.address())) + ", pleased to meet you");
        given_hostname = rest;
    } else {
        conn.write("503 portland.puremagic.com Duplicate HELO");
    }
    
    // $#Edited: 29 Nov 96 15:54 $brad
};

public method .mail_from_cmd() {
    arg rest;
    var conn, i;
    
    conn = .connection();
    if (((rest.length()) <= 5) || (((i = ":" in rest) != 5) || ((| rest.subrange(1, 5) |) != "from:"))) {
        conn.write(("501 Syntax error in \"" + (rest.subrange(1, (i == 0) ? rest.length() : (i - 1)))) + "\"");
    } else if (mail_from != "") {
        conn.write("503 Sender already specified");
    } else {
        mail_from = (rest.subrange(6)).trim();
        mail_to = [];
        mail_body = [];
        conn.write(("250 " + mail_from) + "... sender ok");
    }
    
    // $#Edited: 30 Nov 96 03:01 $brad
};

public method .init_smtp_interface() {
    mail_from = "";
    mail_to = [];
    mail_body = [];
    mail_status = 'idle;
    
    // $#Edited: 30 Nov 96 03:35 $brad
};

public method .uninit_smtp_interface() {
    mail_from = 0;
    mail_to = 0;
    mail_body = 0;
    mail_status = 0;
    
    // $#Edited: 30 Nov 96 03:35 $brad
};

public method .noop_cmd() {
    arg rest;
    
    (.connection()).write("250 Ok");
    
    // $#Edited: 30 Nov 96 00:00 $brad
};

public method .recipient_cmd() {
    arg rest;
    var conn, i, user;
    
    conn = .connection();
    if (mail_from == "") {
        conn.write("503 Need MAIL before RCPT");
    } else if (((rest.length()) <= 3) || (((i = ":" in rest) != 3) || ((| rest.subrange(1, 3) |) != "to:"))) {
        conn.write(("501 Syntax error in \"" + (rest.subrange(1, (i == 0) ? rest.length() : (i - 1)))) + "\"");
    } else {
        catch ~ambig, ~listnf {
            user = .parse_user(rest.subrange(4));
            mail_to += [user];
            conn.write(("250 " + user) + "... recipient ok");
        } with {
            if (error() == ~listnf)
                conn.write("550 User unknown");
            else
                conn.write("553 User ambiguous");
        }
    }
    
    // $#Edited: 30 Nov 96 03:14 $brad
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .parse_user() {
    arg user;
    
    if (((user[1]) == "<") && ((user[user.length()]) == ">"))
        user = user.subrange(2, (user.length()) - 2);
    return (> $mail_lib.match_mail_recipient(user.trim()) <);
    
    // $#Edited: 30 Nov 96 03:14 $brad
};

public method .data_cmd() {
    arg rest;
    var conn;
    
    conn = .connection();
    if (mail_from == "") {
        conn.write("503 Need MAIL command");
    } else if (mail_to == []) {
        conn.write("503 Need RCPT command");
    } else {
        conn.write("354 Enter mail, end with \".\" on a line by itself");
        mail_status = 'read_body;
    }
    
    // $#Edited: 30 Nov 96 03:54 $brad
};

public method .send_mail() {
    var mail;
    
    .set_name(mail_from, 'prop);
    mail = $mail_message.new_mail();
    mail.set_subject("internet mail");
    mail.set_text(mail_body);
    catch any {
        mail.send(@mail_to);
        mail.set_from(mail_from);
        (.connection()).write(("250 " + ($smtp_daemon.get_msg_id())) + " Message accepted for delivery");
    } with {
        (.connection()).write("550 Requested action not taken: Error delivering mail");
        $brad.debug(traceback());
    }
    mail_status = 'idle;
    mail_from = "";
    mail_to = [];
    mail_body = [];
    
    // $#Edited: 30 Nov 96 04:46 $brad
};


new object $finger_interface: $connection_interface;

var $root manager = $finger_interface;
var $root quota_exempt = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 849598071;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $root inited = 1;
var $root child_index = 40;
var $root managed = [$finger_interface];
var $command_cache shortcut_cache = [];

public method .parse_line() {
    arg line;
    var who, out, time, gender;
    
    if ((line.length()) > 0) {
        catch any {
            who = $user_db.exact_match(line);
            out = ["Information on " + (who.name())];
            out = [@out, @(who.display_info('no_blanks)).prefix("  ")];
            time = who.created_on();
            if (who.is($thing))
                gender = (who.gender()).pronoun('psc);
            else
                gender = "It";
            out = [@out, (("  " + (who.name())) + " was created on ") + ($time.format("%A %B %e %Y", time)), ((("  " + gender) + " is ") + ($time.elapsed(time() - time, 'long))) + " old."];
            if (who.is($user))
                out = [@out, ((("  " + gender) + " has logged ") + ($time.elapsed(who.connected_seconds(), 'long))) + " online."];
            if (who.connected())
                out = [@out, ("  " + (who.name())) + " is currently connected."];
            else
                out = [@out, (((("  " + (who.name())) + " was last connected at ") + ($time.format("%r", abs(who.connected_at())))) + " ") + ($time.format("%A %B %e %Y", abs(who.connected_at())))];
            (.connection()).write(out);
        } with {
            (.connection()).write("Unable to locate user: " + line);
        }
    } else {
        catch any
            (.connection()).write($code_lib.generate_listing($user_db.connected()));
        with
            (.connection()).write("Error");
    }
    return 'disconnect;
    
    // $#Edited: 03 Dec 96 01:32 $brad
};

public method .connection_starting() {
    arg addr, port;
    
    $brad.debug("Finger connection inbound");
    
    // $#Edited: 03 Dec 96 01:05 $brad
};


new object $login_interface: $connection_interface;

var $root child_index = 15712;
var $root manager = $login_interface;
var $root created_on = 809051864;
var $root inited = 1;
var $root quota_exempt = 1;
var $root flags = ['methods, 'code, 'core, 'variables, 'command_cache];
var $has_commands local = #[["@who", [["@who", "", "@who", 'who_cmd, #[]]]], ["m?otd", [["m?otd", "", "m?otd", 'motd_cmd, #[]]]], ["h?elp", [["h?elp", "", "h?elp", 'help_cmd, #[]]]], ["guest|connect-guest", [["guest|connect-guest", "*", "guest|connect-guest <any>", 'connect_guest_cmd, #[[1, ['any, []]]]]]], ["c?onnect", [["c?onnect", "*", "c?onnect <any>", 'connect_cmd, #[[1, ['any, []]]]]]], ["@quit|QUIT", [["@quit|QUIT", "", "@quit|QUIT", 'quit_cmd, #[]]]], ["cr?eate", [["cr?eate", "*", "cr?eate <any>", 'create_cmd, #[[1, ['any, []]]]]]]];
var $command_cache shortcut_cache = [];
var $command_cache local_cache = #[["@who", ["@who"]], ["m", ["m?otd"]], ["mo", ["m?otd"]], ["mot", ["m?otd"]], ["motd", ["m?otd"]], ["h", ["h?elp"]], ["he", ["h?elp"]], ["hel", ["h?elp"]], ["help", ["h?elp"]], ["guest", ["guest|connect-guest"]], ["connect-guest", ["guest|connect-guest"]], ["c", ["c?onnect"]], ["co", ["c?onnect"]], ["con", ["c?onnect"]], ["conn", ["c?onnect"]], ["conne", ["c?onnect"]], ["connec", ["c?onnect"]], ["connect", ["c?onnect"]], ["@quit", ["@quit|QUIT"]], ["QUIT", ["@quit|QUIT"]], ["cr", ["cr?eate"]], ["cre", ["cr?eate"]], ["crea", ["cr?eate"]], ["creat", ["cr?eate"]], ["create", ["cr?eate"]]];
var $root managed = [$login_interface];
var $root owned = [$login_interface];

protected method .connect_cmd() {
    arg cmdstr, cmd, args;
    var syn, stderr, passwd, name, user;
    
    syn = cmd + " <name> <password>";
    stderr = "Either that user does not exist or has a different password.";
    args = args.explode();
    if ((args.length()) < 2)
        (> .tell_error("Last word is taken as the password.", syn) <);
    passwd = args[args.length()];
    name = (args.subrange(1, (args.length()) - 1)).join();
    user = (| $user_db.search(name) |) || (> .tell_error(syn, stderr) <);
    catch any {
        if (!(user.check_password(passwd, (.connection()).address())))
            (> .tell_error(syn, stderr) <);
    } with {
        (> .tell_error(syn, stderr) <);
    }
    (.connection()).change_interface(user);
};

protected method .create_cmd() {
    arg cmdstr, cmd, args;
    var syn, msg, user, semail;
    
    if (!($login_daemon.get_setting("creation-allowed", $login_daemon)))
        return (> .tell_error("", $login_daemon.get_setting("creation-disabled-msg", $login_daemon)) <);
    syn = cmd + " <name> <password> <email@host>";
    semail = $sys.get_system_email('login);
    args = args.explode_quoted();
    ((args.length()) == 3) || (> .tell_error(syn) <);
    if ((| $user_db.search(args[1]) |))
        return .tell(("The name '" + (args[1])) + "' is already taken.");
    catch any {
        user = $sys.create_user(@args);
    } with {
        if (user)
            (| user.destroy() |);
        msg = ["There was a problem creating you:"];
        msg += $parse_lib.traceback(traceback());
        msg += ["If there is a problem contact: " + semail];
        (| $login_log.log(traceback()) |);
        (> .tell_error(syn, msg) <);
        return;
    }
    (.connection()).change_interface(user);
};

protected method .quit_cmd() {
    arg cmdstr, cmd;
    
    .print("Goodbye.");
    return 'disconnect;
};

protected method .connect_guest_cmd() {
    arg cmdstr, cmd, args;
    var syn, msg, c, email, name, result, semail, user;
    
    syn = cmd + " <your name> <your email>";
    semail = $sys.get_system_email('login);
    args = args.explode();
    c = .connection();
    if ((args.length()) < 2)
        (> .tell_error(syn) <);
    name = (args.subrange(1, (args.length()) - 1)).join();
    email = args[args.length()];
    if ($sys.validate_email_addresses())
        result = $code_lib.valid_email(email);
    if ((result[1]) != 'valid) {
        switch (result[1]) {
            case 'invalid:
                c.write(["", ("=> Syntax: `" + syn) + "`"]);
                c.write("The given email address is not a legitimate address.");
                c.write("Specify both username and hostname.");
                return;
            case 'invip, 'invhostname:
                c.write("** Your hostname seems to be invalid.");
                c.write("** You should set a valid email address.");
        }
    }
    catch any {
        user = (> $sys.create_user(name, 0, email, 'anonymous_user_class) <);
    } with {
        c.write(["", ("=> Syntax: `" + syn) + "`"]);
        c.write((traceback()[1])[2]);
        c.write("If there is a problem contact: " + semail);
        return;
    }
    c.change_interface(user);
};

protected method .who_cmd() {
    arg cmdstr, cmd;
    
    .print($code_lib.generate_listing($user_db.connected()));
};

protected method .help_cmd() {
    arg cmdstr, cmd;
    
    .print($motd.connect_help());
};

protected method .null_cmd() {
    arg @args;
    
    return (> .invalid_cmd(@args) <);
};

protected method .invalid_cmd() {
    arg @args;
    var line;
    
    line = (((($login_interface.local_cache()).to_list()).slice(2)).slice(1)).compress();
    if (!($login_daemon.get_setting("creation-allowed", $login_daemon)))
        line = line.del("cr?eate");
    .print("Try: " + (line.to_english("", " or ")));
    
    // $#Edited: 15 Feb 97 17:12 $brad
    // $#Edited: 20 Feb 97 16:51 $brad
};

protected method .print() {
    arg what;
    
    (.connection()).write(what);
};

protected method .motd() {
    var out;
    
    out = ($motd.build('default)) + ["", " ** Use 'H?elp' for a list of commands **".center(79), ""];
    return out;
};

protected method .motd_cmd() {
    arg cmdstr, cmd;
    
    .print(.motd());
};

protected method .tell_error() {
    arg syntax, @problem;
    var problem, line, sprefix, prefix, length;
    
    length = 79;
    if (syntax)
        .print(("=> Syntax: `" + syntax) + "`");
    if (problem) {
        for line in (problem) {
            if (type(line) == 'string)
                line = line.wrap_lines(length, "!  ", 1);
            .print(line);
        }
    }
    throw(~stop, "!  ** use h?elp for a list of commands and their usages **");
};

public method .connection_starting() {
    arg host, port;
    
    (> .perms(caller(), $connection) <);
    .print(.motd());
};

public method .parse_line() {
    arg line;
    var cmd, c, match, parsed, i, m, a, u;
    
    catch any {
        while (line && ((line[1]) == " "))
            line = line.subrange(2);
        if (!line) {
            return .null_cmd(line);
        } else {
            cmd = line.explode();
            cmd = [line, cmd[1], ((cmd.subrange(2)).join()) || ""];
            c = (| $login_interface.match_in_local_cache(@cmd) |);
            if (c && ((c[1]) == 'local)) {
                // screw duplicates, take the first match
                match = (c[2])[1];
                m = match[2];
                i = match[5];
                parsed = i.keys();
                for a in [1 .. m.length()] {
                    if (a in parsed)
                        m = m.replace(a + 2, (> $command_parser.convert_arg(cmd[2], (i[a])[1], m[a + 2], $no_one, ((i[a])[2]) ? ((i[a])[2])[1] : $no_one, $no_one) <));
                }
                return (> .(match[4])(@m) <);
            }
            return (> .invalid_cmd(line) <);
        }
    } with {
        if (error() == ~stop) {
            if ((traceback()[1])[2])
                .print((traceback()[1])[2]);
        } else {
            .print($parse_lib.traceback(traceback()));
            return 'disconnect;
        }
    }
    
    // $#Edited: 14 Feb 97 18:35 $brad
};


new object $connection: $network;

var $root child_index = 11;
var $root manager = $connection;
var $root created_on = 809051864;
var $root inited = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $connection buffer = `[];
var $connection host = "";
var $connection daemon = 0;
var $connection active = 0;
var $connection line_buffer = 0;
var $connection interface = 0;
var $connection timeout = 0;
var $connection read_block = [];
var $connection started_at = 0;
var $connection port = 0;
var $connection foreign_addr = 0;
var $connection local_port = 0;
var $connection local_addr = 0;
var $connection remote_port = 0;
var $connection remote_addr = 0;
var $connection remote_name = 0;
var $root managed = [$connection];
var $root owned = [$connection];
var $connection tid = 0;

public method .daemon_shutdown() {
    var c;
    
    // called by $daemon.stop_listening()
    (> .perms(caller(), $daemon) <);
    for c in (.children())
        (> c.close() <);
    (> interface.daemon_shutdown() <);
};

root method .init_connection() {
    buffer = `[];
    local_addr = (remote_addr = "");
    line_buffer = [];
    timeout = 300;
    tid = -1;
    
    // remove all flags
    .set_flags([]);
    
    // $#Edited: 03 Dec 96 02:01 $brad
};

root method .uninit_connection() {
    (| close_connection() |);
    active = 0;
    if (interface)
        (| interface.connection_going_away(.address(), remote_port) |);
    interface = 0;
    if (read_block)
        read_block = read_block.add('lines, 'disconnected);
    .finish_reading_block();
    if (tid != (-1))
        $scheduler.del_task(tid);
    tid = 0;
    
    // $#Edited: 03 Dec 96 02:14 $brad
};

public method .timeout() {
    return timeout;
};

public method .address() {
    (> .perms(sender()) <);
    return remote_addr;
    
    // if you want, remove the above return and you will exec the following
    // note: this currently blocks everything while doing name lookups
    if (!remote_name)
        remote_name = .hostname(remote_addr);
    return remote_name;
};

public method .set_timeout() {
    arg seconds;
    
    (> .perms(sender(), interface, this()) <);
    timeout = seconds;
    if (!timeout)
        (| clear_var('timeout) |);
};

public method .change_interface() {
    arg new;
    var old;
    
    (> .perms(sender()) <);
    if (interface) {
        old = interface;
        old.connection_going_away(.address(), remote_port);
    }
    interface = new;
    (.manager()).change_connection_interface(old, new);
    interface.connection_starting(.address(), remote_port);
};

public method .new_interface() {
    arg obj;
    
    (> .perms(sender()) <);
    interface = obj;
};

public method .set_daemon() {
    arg obj;
    
    (> .perms(sender()) <);
    daemon = obj;
};

public method .write() {
    arg what, @how;
    var elem, sep;
    
    sep = ('non_terminated in how) ? `[] : `[13, 10];
    switch (type(what)) {
        case 'string:
            what = $buffer.from_strings([what], sep);
        case 'list:
            what = $buffer.from_strings(what, sep);
        case 'buffer:
        default:
            throw(~type, "Write: strings, list of strings and buffers.");
    }
    cwrite(what);
};

driver method .parse() {
    arg incoming;
    var lines, line, index;
    
    lines = buf_to_strings(buffer + incoming);
    index = listlen(lines);
    buffer = lines[index];
    lines = delete(lines, index);
    line_buffer += lines;
    while (line_buffer) {
        line = line_buffer[1];
        line_buffer = delete(line_buffer, 1);
        (| .parse_line(line) |);
    }
};

protected method .parse_line() {
    arg line;
    
    if (read_block) {
        read_block = read_block.parse(line);
        line = .rehash_read_status();
        if ((!line) && (line != ""))
            return;
    }
    if ((interface.parse_line(line)) == 'disconnect)
        (> .close() <);
};

public method .cwritef() {
    arg fname;
    
    (> .perms(sender()) <);
    (> cwritef(fname) <);
};

public method .is_reading_block() {
    return read_block ? 1 : 0;
};

public method .finish_reading_block() {
    var task_id, lines;
    
    (> .perms(sender()) <);
    task_id = read_block.task_id();
    lines = read_block.lines();
    read_block = 0;
    $scheduler.resume(task_id, lines);
};

public method .abort_reading_block() {
    (> .perms(sender()) <);
    read_block = read_block.add('lines, 'aborted);
    .finish_reading_block();
};

public method .start_reading_block() {
    arg count;
    
    (> .perms(sender()) <);
    read_block = $read_parser.new_with(task_id(), count);
    (| .push_buffered() |);
    return (> $scheduler.suspend(this()) <);
};

protected method .rehash_read_status() {
    switch (read_block.status()) {
        case 'abort:
            .abort_reading_block();
        case 'not_done:
            // do nothing
        case 'done:
            .finish_reading_block();
        case 'pass_command:
            return read_block.command();
    }
    return 0;
};

protected method .do_timeout() {
    $brad.debug("do_timeout");
    if (!timeout)
        return;
    .write(("Timeout (" + tostr(timeout)) + ")");
    .close();
    
    // $#Edited: 03 Dec 96 02:02 $brad
    // $#Edited: 03 Dec 96 02:10 $brad
    // $#Edited: 03 Dec 96 02:16 $brad
};

public method .close() {
    (> .perms(sender()) <);
    (> $sys.destroy_sender() <);
};

driver method .disconnect() {
    .close();
};

public method .set_remote_port() {
    arg port;
    
    (> .perms(sender()) <);
    remote_port = port;
};

public method .new_connection() {
    var new, i;
    
    (> .perms(caller(), $daemon) <);
    new = .spawn();
    i = interface.new(new);
    new.add_writer(sender());
    new.add_writer(interface);
    new.add_writer((| class(i) |) || i);
    new.add_writer(this());
    new.new_interface(i);
    return new;
};

public method .active() {
    return active;
};

public method .write_string() {
    arg string;
    
    if ((sender() != interface) && (sender() != (| class(interface) |)))
        throw(~perm, sender() + " cannot write this connection.");
    if (type(string) != 'string)
        throw(~type, "Argument must be a string.");
    cwrite($buffer.from_string(string));
};

public method .write_strings() {
    arg strings;
    
    if ((sender() != interface) && (sender() != (| class(interface) |)))
        throw(~perm, sender() + " cannot write this connection.");
    if (type(strings) != 'list)
        throw(~type, "Argument must be a list of strings.");
    cwrite($buffer.from_strings(string));
};

public method .write_buffer() {
    arg buffer;
    
    if ((sender() != interface) && (sender() != (| class(interface) |)))
        throw(~perm, sender() + " cannot write this connection.");
    if (type(buffer) != 'buffer)
        throw(~type, "Argument must be a buffer.");
    cwrite(buffer);
};

public method .active_since() {
    return active;
};

public method .start() {
    arg remote, local, rport, lport;
    
    // Make this method 'fork' from the regular thread stack
    (> .perms(caller(), $daemon) <);
    active = time();
    remote_addr = remote;
    remote_port = rport;
    local_addr = local;
    local_port = lport;
    
    //    $brad.debug("timeout", timeout);
    //    if (timeout)
    //        $scheduler.add_task(timeout, 'do_timeout);
    interface.connection_starting(.address(), remote_port);
    
    // $#Edited: 03 Dec 96 02:11 $brad
    // $#Edited: 03 Dec 96 02:15 $brad
    // $#Edited: 03 Dec 96 11:33 $brad
};

public method .interface() {
    (caller() == $daemon) || (> .perms(sender()) <);
    return interface;
};

public method .interface_going_away() {
    if ((sender() != interface) && (sender() != (| class(interface) |)))
        throw(~perm, sender() + " is not the interface.");
    interface = 0;
    (> $sys.destroy_sender() <);
};

protected method .open_connection() {
    arg host, port;
    
    (> open_connection(host, port) <);
};

protected method .set_active() {
    arg value;
    
    active = value;
};

public method .change_connection_interface() {
    arg old, new;
    var i;
    
    (> .perms(caller(), $connection) <);
    if (old)
        sender().del_writer((| class(old) |) || old);
    sender().add_writer((| class(new) |) || new);
};

private method .push_buffered(): forked {
    var line;
    
    // called when a read() suspends the connection--to finish unbuffering i/o
    while (line_buffer) {
        line = line_buffer[1];
        line_buffer = delete(line_buffer, 1);
        (| .parse_line(line) |);
    }
};


new object $login_connection: $connection;

var $root child_index = 16821;
var $root manager = $login_connection;
var $root created_on = 809051865;
var $root inited = 1;
var $root quota_exempt = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $connection interface = $login_interface;
var $connection active = 0;
var $connection buffer = `[];
var $connection host = "";
var $connection daemon = 0;
var $connection line_buffer = [];
var $connection timeout = 0;
var $connection read_block = 0;
var $connection started_at = 0;
var $root managed = [$login_connection];
var $root owned = [$login_connection];

public method .local_echo_off() {
    (sender() == (.interface())) || (> .perms(sender()) <);
    cwrite(`[255, 251, 1, 0, 13]);
};

public method .local_echo_on() {
    (sender() == (.interface())) || (> .perms(sender()) <);
    cwrite(`[255, 252, 1, 0, 13]);
};


new object $http_connection: $connection;

var $root child_index = 12843;
var $root manager = $http_connection;
var $root created_on = 809075134;
var $root inited = 1;
var $root quota_exempt = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $connection buffer = `[27];
var $connection host = "";
var $connection daemon = 0;
var $connection active = 0;
var $connection line_buffer = [];
var $connection interface = $http_interface;
var $connection timeout = 0;
var $connection read_block = 0;
var $connection started_at = 0;
var $root managed = [$http_connection];
var $root owned = [$http_connection];
var $http_connection buffer = 0;
var $http_connection line_buffer = 0;
var $http_connection reading = 0;

root method .init_http_connection() {
    buffer = `[];
    line_buffer = [];
};

public method .start() {
    arg @args;
    
    .set_timeout(0);
    return (> pass(@args) <);
};

public method .handle_POST_input() {
    arg len;
    var body;
    
    if (buflen(buffer) < len) {
        reading = 300;
        while ((buflen(buffer) < len) && --reading) {
            $scheduler.sleep(1);
            refresh();
        }
        if (buflen(buffer) < len) {
            buffer = `[];
            status = 400;
            throw(~timeout, "Timeout on receiving POST request");
        }
    }
    body = buf_to_strings(subbuf(buffer, 1, len));
    buffer = subbuf(buffer, len + 1);
    if ((`[13, 10] in buffer) == 1)
        buffer = subbuf(buffer, 3);
    if ((body[listlen(body)]) == `[])
        body = delete(body, listlen(body));
    else
        body = replace(body, listlen(body), buf_to_str(body[listlen(body)]));
    return body;
};

driver method .parse() {
    arg incoming;
    var l, line, i, t, int, sub;
    
    catch any {
        buffer += incoming;
        int = .interface();
        while (!reading) {
            if (!(i = `[13, 10] in buffer))
                break;
            sub = subbuf(buffer, 1, i - 1);
            line = buf_to_str(sub);
            buffer = subbuf(buffer, i + 2);
            (> int.parse_line(line) <);
        }
    } with {
        int.set_status(500);
        int.respond($parse_lib.html_traceback(traceback(), 500));
    }
};


new object $outbound_connection: $connection;

var $root manager = $outbound_connection;
var $root quota = 100000;
var $root inited = 1;
var $root created_on = 844616370;
var $root quota_exempt = -1;
var $connection buffer = `[];
var $connection remote_addr = "";
var $connection local_addr = "";
var $connection line_buffer = [];
var $connection timeout = 0;
var $root child_index = 89;
var $connection host = "";
var $connection daemon = 0;
var $connection active = 0;
var $connection interface = 0;
var $connection read_block = 0;
var $connection started_at = 0;
var $root trusted = [$smtp];
var $root flags = ['core, 'methods, 'code, 'variables];
var $root managed = [$outbound_connection];

driver method .connect() {
    arg task_id;
    
    $scheduler.resume(task_id, 'success);
    
    // $#Edited: 25 Oct 96 22:45 $brian
};

driver method .failed() {
    arg task_id, reason;
    
    $scheduler.resume(task_id, reason);
    
    // $#Edited: 25 Oct 96 22:45 $brian
};

public method .open_connection() {
    arg host, port;
    
    (> .perms(sender()) <);
    (> pass(host, port) <);
    return $scheduler.suspend(this());
    
    // $#Edited: 25 Oct 96 22:45 $brian
};

public method .new() {
    var child, daemon, port, i;
    
    (| .perms(sender(), 'trusts) |) || (> .perms(caller(), 'trusts) <);
    child = .spawn();
    
    // do perms stuff
    child.add_writer(sender());
    child.add_writer(this());
    child.new_interface(sender());
    return child;
    
    // $#Edited: 25 Oct 96 22:45 $brian
};


new object $smtp_connection: $connection;

var $root manager = $smtp_connection;
var $connection interface = $smtp_interface;
var $root inited = 1;
var $root created_on = 849170589;
var $connection buffer = `[];
var $connection remote_addr = "";
var $connection local_addr = "";
var $connection line_buffer = [];
var $connection timeout = 300;
var $root quota_exempt = 1;
var $root child_index = 132;
var $root managed = [$smtp_connection];
var $root flags = ['core];


new object $finger_connection: $connection;

var $root manager = $finger_connection;
var $connection interface = $finger_interface;
var $root inited = 1;
var $root created_on = 849598061;
var $connection buffer = `[];
var $connection remote_addr = "";
var $connection local_addr = "";
var $connection line_buffer = [];
var $connection timeout = 10;
var $root quota_exempt = 1;
var $root child_index = 49;
var $root managed = [$finger_connection];
var $connection tid = 0;
var $root flags = ['core];


new object $veil_connection: $network;

var $root manager = $veil_connection;
var $root inited = 1;
var $root created_on = 814651762;
var $root child_index = 2;
var $veil_connection last_id = 0;
var $veil_connection ch_types = 0;
var $veil_connection channels = 0;
var $veil_connection incomplete = 0;
var $veil_connection host = 0;
var $veil_connection packets = 0;
var $veil_connection ch_info = 0;
var $veil_connection daemon = 0;
var $veil_connection active = 0;
var $veil_connection timeout = 0;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root managed = [$veil_connection];
var $root owned = [$veil_connection];

driver method .parse() {
    arg incoming;
    var p, message, i;
    
    // p = buf_to_veil_packets(incomplete, incoming);
    incomplete = p.last();
    i = 1;
    message = `[];
    while (packets) {
        p = packets[i];
        message += p[4];
        if (p[1]) {
            packets = packets.subrange(i + 1);
            (| .message(p[1], p[2], message) |);
            message = `[];
            i = 1;
        }
        ++i;
    }
    
    // using subscripting keeps us from copying the list of packets every
    // iteration of the while loop.  We want to do it in the above way,
    // as then the packet list and current message is stored on the object,
    // which saves us if the current task suspends.
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

public method .write() {
    arg buf, id, info, push;
    
    // cwrite(buf_from_veil_packets([[push, info, ch, buf]]));
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

public method .next_id() {
    last_id += 2;
    return last_id;
    
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

protected method .packet() {
    arg packet;
    var control;
    
    control = (| channels[packet[3]] |);
    if (!control) {
        control = .new_channel(@packet.subrange(1, 3));
    
        // just ignore the packet
        if (!control)
            return;
    }
    control.incoming(packet);
    
    // $# Edited 25 Oct 1995 17:51 Lynx ($lynx)
};

protected method .new_channel() {
    arg id, buf;
    var lines, reg, par;
    
    // parse the buffer to figure out what type of channel it is.
    // for now everything is 'shell;
    par = ((buf[1]) * 256) + (buf[2]);
    lines = subbuf(buf, 3).to_strings();
    channels = channels.add(id, $user_rascal);
    ch_info = ch_info.add(id, [par, lines]);
    
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

protected method .message() {
    arg status, id, buf;
    var control;
    
    control = (| channels[id] |);
    switch (status) {
        case 'abort:
            .close_channel(id);
            return;
        case 'close:
            .close_channel(id);
        case 'open:
            if (control)
                return;
            control = .new_channel(id, buf);
            return;
    }
    if (!control)
        return;
    
    // fork this
    control.inbound(buf);
    
    // $# Edited 25 Oct 1995 18:45 Lynx ($lynx)
};

protected method .close_channel() {
    arg id;
    
    channels = (| channels.del(id) |);
    ch_info = (| ch_info.del(id) |);
    
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

public method .outbound() {
    arg what, type, @nopush;
    var id, a;
    
    id = (| ch_types[type] |);
    if (id == ~keynf)
        throw(~invch, strfmt("Invalid channel type: %d.", type));
    if (!id) {
        id = .new_id();
        ch_types = ch_types.add(type, id);
        a = 'open;
    }
    switch (type(what)) {
        case 'string:
            what = $buffer.from_strings([what], `[10]);
        case 'list:
            what = $buffer.from_strings(what, `[10]);
        case 'buffer:
        default:
            throw(~type, "Write: strings, list of strings and buffers.");
    }
    
    // cwrite(buf_from_veil_packets([[nopush ? 0 | 1, a, id, buf]]));
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

public method .init_veil_connection() {
    incomplete = `[];
    packets = [];
    channels = #[];
    ch_types = #[];
    ch_info = #[];
    last_id = 1;
    host = "";
    daemon = 0;
    active = 0;
    timeout = 0;
    .set_flags([]);
    
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

public method .close() {
    arg @msg;
    var c;
    
    (caller() == definer()) || (> .perms(sender()) <);
    msg = $buffer.from_strings([@msg, ["Goodbye"]][1]);
    active = 0;
    for c in (channels.keys())
        .write(msg, ch, 'close, 1);
    (| close_connection() |);
    for c in (channels)
        (| (c[2]).connection_going_away() |);
    channels = #[];
    
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
    // $#Edited: 30 Nov 96 21:22 $miro
};

root method .uninit_connection() {
    if (active)
        .close(["** Connection aborted due to object destruction **"]);
    
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

public method .daemon_shutdown() {
    var c;
    
    (> .perms(caller(), $daemon) <);
    for c in (.children())
        (> .close(["** Connection aborted due to daemon shutdown **"]) <);
    
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

public method .timeout() {
    return timeout;
    
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

public method .address() {
    (> .perms(sender()) <);
    return host;
    
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

public method .set_host() {
    arg host;
    
    (> .perms(sender()) <);
    set_var('host, host);
    
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

public method .set_daemon() {
    arg daemon;
    
    (> .perms(sender()) <);
    set_var('daemon, daemon);
    
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

protected method .do_timeout() {
    arg seconds;
    
    .close([("VEIL: ** Timeout " + tostr(seconds)) + " seconds **"]);
    
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

driver method .disconnect() {
    arg @args;
    var c;
    
    // this is called by the driver, after the connection is dead, so
    // we have no connection already.
    active = 0;
    for c in (channels)
        (| (c[2]).connection_going_away() |);
    channels = #[];
    
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

public method .set_port() {
    arg port;
    
    (> .perms(sender()) <);
    set_var('port, port);
    
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

public method .active() {
    return active;
    
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

driver method .connect() {
    arg client, server, socket;
    
    host = client;
    daemon.new_connection();
};

public method .active_since() {
    return active;
    
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};

public method .start() {
    // Make this method 'fork' from the regular thread stack
    (> .perms(caller(), $daemon) <);
    active = time();
    
    // do something
    // $# Edited 25 Oct 1995 18:41 Lynx ($lynx)
};


new object $smtp: $network;

var $root manager = $smtp;
var $smtp maildrop = "127.0.0.1";
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 845213524;
var $root managed = [$smtp];
var $smtp debugging = [];
var $root inited = 1;
var $smtp postmaster = 0;
var $smtp valid_host_regexp = "^([-a-z0-9]+\.)+(gov|edu|com|org|int|mil|net|nato|arpa|[a-z][a-z])$";
var $smtp valid_email_regexp = "^[-a-z0-9_!.%+$'=]+[^.]$";
var $root trusted_by = [$outbound_connection];

public method .parse_address() {
    arg addr;
    
    return [(| addr.subrange(1, (addr.rindex("@")) - 1) |) || addr, (| addr.subrange((addr.rindex("@")) + 1) |) || ""];
    
    // $#Edited: 25 Oct 96 22:39 $brian
};

public method .sendmail() {
    arg recip, subj, @lines;
    var mailagent, reason;
    
    (> .perms(sender(), 'trusts) <);
    mailagent = ((((($motd.server_name()) + " (") + ($sys.server_info('server_hostname))) + ":") + ($login_daemon.current_port())) + ")";
    if ((reason = .invalid_email_address(recip)))
        throw(~invemail, reason);
    return .raw_sendmail(recip, "Date: " + ($time.format("%a, %e %b %Y %T %Z")), "From: " + (.return_address()), "To: " + recip, "Subject: " + subj, "Errors-to: " + (.errors_to_address()), "X-Mail-Agent: " + mailagent, @lines);
    
    // $#Edited: 25 Oct 96 22:39 $brian
};

public method .invalid_email_address() {
    arg address;
    var at, name, host;
    
    if (!address)
        return "no email address supplied";
    if (!(at = address.rindex("@")))
        return "not a valid email address";
    name = address.subrange(1, at - 1);
    host = address.subrange(at + 1);
    if ((name.match_regexp("^in%")) || (name.match_regexp("^smtp%")))
        return ("'" + name) + "' doesn't look like a valid username (try removing the 'in%' or 'smtp%')";
    if (!(host.match_regexp(valid_host_regexp)))
        return ("'" + host) + "' doesn't look like a valid Internet host";
    if (!(name.match_regexp(valid_email_regexp)))
        return ("'" + name) + "' doesn't look like a valid username for Internet mail";
    return "";
    
    // $#Edited: 25 Oct 96 22:39 $brian
};

public method .invalid_hostname() {
    arg hostname;
    
    return (hostname.match_regexp(valid_host_regexp)) ? "" : (("'" + hostname) + "' is not a valid internet host name");
};

public method .raw_sendmail() {
    arg recip, @body;
    var x, blank, data, debugto, target, line, state, timeout;
    
    (sender() == this()) || (> .perms(sender(), 'system) <);
    if (type(debugging) == 'list)
        debugto = debugging;
    else
        debugto = debugging && [.manager()];
    data = [];
    for x in (body) {
        refresh();
        if (!(blank || (x.match_regexp("[a-z0-9-]*: ")))) {
            if (x)
                data += [""];
            blank++;
        }
        data += [(x == ".") ? "." + x : x];
    }
    pause();
    target = $outbound_connection.new();
    catch any {
        target.open_connection(.maildrop(), 25);
    } with {
        line = "Cannot open connection to maildrop: " + ((traceback()[1])[2]);
        (| target.close() |);
        throw(~mailerr, line);
    }
    timeout = $scheduler.add_task(120, 'timeout, target);
    state = 'connect;
    catch any {
        while (type((| (x = target.start_reading_block('one)) |)) == 'list) {
            x = x[1];
            if (debugto)
                debugto.mmap('tell, "GET: " + x);
            if (x && (!((x[1]) in "23"))) {
                target.close();
                (| $scheduler.del_task(timeout) |);
                return x;
            } else if (x && ((x[4]) == "-")) {
                continue;
            }
            switch (state) {
                case 'connect:
                    ._send(target, "HELO " + ($sys.server_info('server_hostname)), debugto);
                    state = 'from;
                case 'from:
                    ._send(target, ("MAIL FROM: <" + (.postmaster())) + ">", debugto);
                    state = 'rcpt;
                case 'rcpt:
                    ._send(target, ("RCPT TO:<" + recip) + ">", debugto);
                    state = 'data;
                case 'data:
                    ._send(target, "DATA", debugto);
                    state = 'send_data;
                case 'send_data:
                    for line in (data)
                        ._send(target, line, debugto);
                    ._send(target, ".", debugto);
                    state = 'quit;
                case 'quit:
                    ._send(target, "QUIT", debugto);
                    break;
            }
        }
        (| target.close() |);
        return 0;
    } with {
        (| target.close() |);
        (| $scheduler.del_task(timeout) |);
        rethrow(error());
    }
    (| $scheduler.del_task(timeout) |);
    
    // $#Edited: 25 Oct 96 22:39 $brian
};

public method .postmaster() {
    return postmaster || ($sys.get_system_email('default));
    
    // $#Edited: 25 Oct 96 22:39 $brian
};

public method .maildrop() {
    return maildrop || "localhost";
    
    // $#Edited: 25 Oct 96 22:39 $brian
};

public method .return_address() {
    return .postmaster();
    
    // $#Edited: 25 Oct 96 22:39 $brian
};

public method .errors_to_address() {
    return .postmaster();
    
    // $#Edited: 25 Oct 96 22:39 $brian
};

public method .connection_starting() {
    arg addr, port;
    
    return;
    
    // $#Edited: 25 Oct 96 23:08 $brian
};

public method .connection_going_away() {
    arg addr, port;
    
    return;
    
    // $#Edited: 25 Oct 96 23:08 $brian
};

private method ._send() {
    arg conn, line, debugto;
    
    if (debugto)
        debugto.mmap('tell, "SEND: " + line);
    conn.write_string(line + "\n");
    
    // $#Edited: 27 Oct 96 10:12 $brian
};

protected method .timeout() {
    arg conn;
    
    (| conn.close() |);
    
    // $#Edited: 27 Oct 96 11:02 $brian
};

root method .core_smtp(): nooverride {
    postmaster = 0;
    debugging = [];
    maildrop = "127.0.0.1";
    
    // $#Edited: 21 Dec 96 23:55 $brian
};


new object $daemon: $network;

var $root child_index = 6;
var $root manager = $daemon;
var $root created_on = 809051864;
var $root inited = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $daemon default_port = 0;
var $daemon connection = 0;
var $daemon next_connection = 0;
var $daemon current_port = 0;
var $root managed = [$daemon];
var $root owned = [$daemon];
var $root defined_settings = #[["default-port", #[['get, ['get_default_port]], ['set, ['set_default_port]], ['parse, ['is_type, 'integer]]]], ["connection", #[['get, ['get_connection]], ['set, ['set_connection]], ['parse, ['parse_connection_setting]]]]];

public method .get_default_port() {
    arg @args;
    
    return default_port;
};

protected method .set_connection() {
    arg name, definer, value, @args;
    
    connection = value;
};

public method .stop_listening() {
    arg @port;
    
    (> .perms(sender()) <);
    (> connection.daemon_shutdown() <);
    (| clear_var('next_connection) |);
};

public method .start_listening() {
    arg @port;
    
    (> .perms(sender()) <);
    (| .stop_listening() |);
    current_port = port ? port[1] : default_port;
    next_connection = connection.new_connection();
    bind_port(current_port);
    
    // $#Edited: 22 Nov 96 17:54 $miro
};

public method .startup() {
    arg @args;
    var name, opt, port;
    
    (> .perms(caller(), 'system) <);
    catch any {
        name = tostr(.objname());
        name = "-p" + (name.subrange(1, ("_" in name) - 1));
        opt = name in args;
    }
    port = (| toint(args[opt + 1]) |) || default_port;
    catch any {
        (| .stop_listening() |);
        (> .start_listening(port) <);
        $sys.log(((("** Starting " + this()) + " on port ") + tostr(port)) + " **");
    } with {
        switch (error()) {
            case ~bind:
                $sys.log(("** Unable to bind to port " + tostr(port)) + "! **");
            default:
                $sys.log($parse_lib.traceback(traceback()));
        }
    }
};

public method .current_port() {
    return current_port;
};

public method .shutdown() {
    arg @args;
    
    (> .perms(caller(), $sys) <);
    (> .stop_listening() <);
};

driver method .connect() {
    arg remote, local, socket;
    var conn;
    
    if ($sys.blacklisted(remote)) {
        close_connection();
        return;
    }
    if (!valid(next_connection))
        next_connection = connection.new_connection();
    conn = next_connection;
    reassign_connection(conn);
    next_connection = connection.new_connection();
    conn.start(remote, local, socket, current_port);
};

protected method .set_default_port() {
    arg name, definer, value, @args;
    
    // MOST systems don't allow this without root access--if you can do
    // it go ahead and remove this code, in general its not safe.
    if (value < 1024)
        throw(~perm, "Set a port greater than 1024");
    default_port = value;
};

protected method .get_connection() {
    arg @args;
    
    return connection;
};

public method .parse_connection_setting() {
    arg value, @args;
    var obj;
    
    obj = (> $object_lib.to_dbref(value) <);
    if (!(obj.is($connection)))
        throw(~perm, "Connection object must be descended from $connection.");
    return obj;
};

root method .core_daemon() {
    .stop_listening();
};


new object $http_daemon: $daemon;

var $root manager = $http_daemon;
var $root created_on = 809075222;
var $root inited = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $daemon default_port = 1180;
var $daemon connection = $http_connection;
var $daemon current_port = 1180;
var $root managed = [$http_daemon];
var $root owned = [$http_daemon];


new object $login_daemon: $daemon;

var $root manager = $login_daemon;
var $root created_on = 809051992;
var $root inited = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $daemon connection = $login_connection;
var $daemon default_port = 1138;
var $daemon current_port = 1138;
var $root managed = [$login_daemon];
var $root owned = [$login_daemon];
var $root defined_settings = #[["creation-disabled-msg", #[]], ["creation-allowed", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]]];
var $root settings = #[["creation-disabled-msg", "Sorry, character creation is disabled."], ["creation-allowed", 1]];

root method .core_login_daemon() {
    .set_setting("creation-allowed", $login_daemon, "yes");
};


new object $veil_daemon: $daemon;

var $root manager = $veil_daemon;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root created_on = 814668214;
var $root inited = 1;
var $daemon default_port = 1100;
var $daemon connection = $veil_connection;
var $root managed = [$veil_daemon];
var $root owned = [$veil_daemon];


new object $smtp_daemon: $daemon;

var $root manager = $smtp_daemon;
var $daemon default_port = 1125;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 849170427;
var $root inited = 1;
var $daemon connection = $smtp_connection;
var $daemon current_port = 1125;
var $root managed = [$smtp_daemon];
var $smtp_daemon msg_id = 19;

public method .get_msg_id() {
    msg_id++;
    return msg_id;
    
    // $#Edited: 30 Nov 96 03:43 $brad
};


new object $finger_daemon: $daemon;

var $root manager = $finger_daemon;
var $daemon default_port = 1179;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 849597984;
var $root inited = 1;
var $daemon connection = $finger_connection;
var $daemon current_port = 1179;
var $root managed = [$finger_daemon];


new object $logic_frob: $frob;

var $root child_index = 6;
var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $logic_frob;
var $root managed = [$logic_frob];
var $root owned = [$logic_frob];
var $logic_frob token = 0;

public method .try() {
    arg @args;
    
    return 0;
};

public method .token() {
    return token;
    
    // $#Edited: 11 Dec 96 09:58 $brandon
};

public method .set_token() {
    arg new;
    
    (> .perms(sender(), 'manager) <);
    token = new;
    
    // $#Edited: 11 Dec 96 09:59 $brandon
};


new object $xor: $logic_frob;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $xor;
var $root managed = [$xor];
var $root owned = [$xor];
var $logic_frob token = "^";

public method .test() {
    arg xorlist, @args;
    var val, x;
    
    val = 0;
    for x in (xorlist) {
        catch ~type, ~methodnf
            val = val ? !(x.test(@args)) : (x.test(@args));
        with
            val = val ? !x : x;
    }
    return val;
};

frob method .unparse() {
    arg xorlist;
    var str, x;
    
    str = "";
    for x in (xorlist) {
        catch any
            str = (str + (x.unparse())) + " ^^ ";
        with
            str = (str + tostr(x)) + " ^^ ";
    }
    return ("(" + (str && (str.subrange(1, (str.length()) - 4)))) + ")";
    
    // $#Edited: 11 Dec 96 09:48 $brandon
};


new object $and: $logic_frob;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $and;
var $root managed = [$and];
var $root owned = [$and];
var $logic_frob token = "&&";

public method .test() {
    arg andlist, @args;
    var val, x;
    
    val = 0;
    for x in (andlist) {
        catch ~type, ~methodnf
            val = x.test(@args);
        with
            val = x;
        if (!val)
            break;
    }
    return val;
};

frob method .unparse() {
    arg andlist;
    var str, x;
    
    str = "";
    for x in (andlist) {
        catch any
            str = (str + (x.unparse())) + " && ";
        with
            str = (str + tostr(x)) + " && ";
    }
    return ("(" + (str && (str.subrange(1, (str.length()) - 4)))) + ")";
    
    // $#Edited: 11 Dec 96 09:48 $brandon
};


new object $and_lock_frob: $and;

var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $and_lock_frob;
var $root managed = [$and_lock_frob];
var $root owned = [$and_lock_frob];

public method .new_lock() {
    arg lhs, rhs;
    
    if ((type(lhs) != 'frob) || (type(rhs) != 'frob))
        throw(~perm, "Arguments are not both frobs.");
    return (<this(), [lhs, rhs]>);
};

public method .try() {
    arg lock, obj;
    
    return ((lock[1]).try(obj)) && ((lock[2]).try(obj));
};

public method .lock_name() {
    arg lock, @type;
    
    [(type ?= 'literal)] = type;
    switch (type) {
        case 'literal:
            return ((("(" + ((lock[1]).lock_name(type))) + " && ") + ((lock[2]).lock_name(type))) + ")";
        default:
            return (((lock[1]).lock_name(type)) + " and ") + ((lock[2]).lock_name(type));
    }
    
    // $#Edited: 30 Nov 96 21:22 $miro
};


new object $lock_frob: $logic_frob;

var $root child_index = 7;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $lock_frob names = 0;
var $root manager = $lock_frob;
var $root managed = [$lock_frob];
var $root owned = [$lock_frob];
var $lock_frob lock_types = [["inside", $inside_lock_frob], ["indirect", $indirect_lock_frob], ["owner", $owner_lock_frob]];

public method .lock_name() {
    arg value, @type;
    
    [(type ?= 'default)] = type;
    if (type == 'literal)
        type = 'default;
    return (| names[type] |) || (names['default]);
    
    // $#Edited: 30 Nov 96 20:00 $miro
};

public method .set_lock_name() {
    arg name;
    
    (> .perms(sender(), 'manager) <);
    lock_name = name;
};

public method .add_name() {
    arg type, name;
    
    (> .perms(sender(), 'manager) <);
    if (!names)
        names = #[];
    names = names.add(type, name);
};

public method .new_with() {
    arg str;
    
    return (> .parse(str, sender()) <);
    
    // $#Edited: 11 Dec 96 09:48 $brandon
};

public method .parse() {
    arg s, who;
    var stack, lock, n, m, obj, type, i;
    
    stack = [];
    s = " " + s;
    s = strsed(s, "&([^&])", "&&%1", "g");
    s = strsed(s, "\|([^\|])", "||%1", "g");
    s = strsub(s, " or ", " || ");
    s = strsub(s, " and ", " && ");
    s = strsub(s, " not ", " !");
    while (1) {
        // Look for valid prefixes.
        while (1) {
            (s = s.trim()) || throw(~parse, "String ends unexpectedly.");
            if ((s[1]) == "(") {
                stack = ['open, @stack];
                s = s.subrange(2);
            } else if ((s[1]) == "!") {
                if (stack && ((stack[1]) == 'not))
                    stack = stack.subrange(2);
                else
                    stack = ['not, @stack];
                s = s.subrange(2);
            } else {
                break;
            }
        }
    
        // Look for an object name or tag
        m = regexp(s, "^([^)&|]+)(.*)");
        if (!m)
            throw(~parse, "Null object obj_name.");
        s = m[2];
        lock = (m[1]).trim();
        if (!lock)
            throw(~parse, "Null object obj_name.");
    
        // try and match it
        type = $object_lock_frob;
        for i in (lock_types) {
            if (lock.match_begin((i[1]) + ":")) {
                type = i[2];
                lock = lock.subrange(((i[1]).length()) + 2);
                break;
            }
        }
        if ((obj = (| who.match_environment(lock) |))) {
            lock = type.new_lock(obj);
        } else {
            switch (lock) {
                case "any", "true", "anybody":
                    lock = $true_lock_frob.new();
                case "none", "false", "nobody":
                    lock = $false_lock_frob.new();
                default:
                    throw(~parse, ("Invalid lock tag \"" + lock) + "\"");
            }
        }
        stack = [lock, @stack];
    
        // Loop until no more reduction to be done.
        while (1) {
            // Process negations, ands, ors.
            while (1) {
                if ((stack.length()) < 2)
                    break;
                if ((stack[2]) == 'not)
                    stack = [$not_lock_frob.new_lock(stack[1]), @stack.subrange(3)];
                else if ((stack[2]) == 'and)
                    stack = [$and_lock_frob.new_lock(stack[1], stack[3]), @stack.subrange(4)];
                else if ((stack[2]) == 'or)
                    stack = [$or_lock_frob.new_lock(stack[1], stack[3]), @stack.subrange(4)];
                else
                    break;
            }
    
            // Close parens, if necessary; otherwise stop.
            if ((!s) || ((s[1]) != ")"))
                break;
            while (s && ((s[1]) == ")")) {
                if (((stack.length()) < 2) || ((stack[2]) != 'open))
                    throw(~parse, "Misplaced right parenthesis.");
                stack = [stack[1], @stack.subrange(3)];
                s = (s.subrange(2)).trim();
            }
        }
    
        // Are we done?
        if (!s) {
            if ((stack.length()) > 1)
                throw(~parse, "Unmatched left parentheses.");
            return stack[1];
        }
    
        // No, we're at a conjunction.
        if ((s[1]) == "&") {
            stack = ['and, @stack];
            s = s.subrange(3);
        } else if ((s[1]) == "|") {
            stack = ['or, @stack];
            s = s.subrange(3);
        } else {
            throw(~parse, "Illegal character following right parenthesis.");
        }
    }
};


new object $object_lock_frob: $lock_frob;

var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $object_lock_frob;
var $root owned = [$object_lock_frob];
var $root managed = [$object_lock_frob];

public method .new_lock() {
    arg obj;
    
    if (type(obj) != 'objnum)
        throw(~perm, "Argument is not a dbref.");
    return (<this(), [obj]>);
};

public method .try() {
    arg lock, obj;
    
    return ((lock[1]) == obj) || ((obj == sender()) || ($sys.is_system(obj)));
    
    // $#Edited: 13 Feb 97 12:23 $miro
};

public method .lock_name() {
    arg value, @type;
    
    return (value[1]).name();
};

frob method .unparse() {
    arg obj;
    
    return toliteral(obj[1]);
    
    // $#Edited: 11 Dec 96 09:46 $brandon
};


new object $inside_lock_frob: $lock_frob;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $inside_lock_frob;
var $root managed = [$inside_lock_frob];
var $root owned = [$inside_lock_frob];

public method .try() {
    arg lock, obj;
    
    return ((lock[1]).contains(obj)) || ($sys.is_system(obj));
    
    // $#Edited: 03 Nov 96 17:48 $miro
};

public method .new_lock() {
    arg obj;
    
    if (type(obj) != 'objnum)
        throw(~perm, "Argument is not a dbref.");
    return (<this(), [obj]>);
    
    // $#Edited: 03 Nov 96 17:47 $miro
};

public method .lock_name() {
    arg value, @type;
    
    return "inside:" + ((value[1]).name());
    
    // $#Edited: 03 Nov 96 17:48 $miro
};


new object $indirect_lock_frob: $lock_frob;

var $root manager = $indirect_lock_frob;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847067040;
var $root inited = 1;
var $root managed = [$indirect_lock_frob];

public method .new_lock() {
    arg obj;
    
    if (type(obj) != 'objnum)
        throw(~perm, "Argument is not a dbref.");
    return (<this(), [obj]>);
    
    // $#Edited: 03 Nov 96 17:50 $miro
};

public method .try() {
    arg lock, obj;
    
    return ((lock[1]).try_indirect_lock(obj)) || ($sys.is_system(obj));
    
    // $#Edited: 03 Nov 96 17:50 $miro
};

public method .lock_name() {
    arg value, @type;
    
    return "indirect:" + ((value[1]).name());
    
    // $#Edited: 03 Nov 96 17:50 $miro
};


new object $owner_lock_frob: $lock_frob;

var $root manager = $owner_lock_frob;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847067045;
var $root inited = 1;
var $root managed = [$owner_lock_frob];

public method .new_lock() {
    arg obj;
    
    if (type(obj) != 'objnum)
        throw(~perm, "Argument is not a dbref.");
    return (<this(), [obj]>);
    
    // $#Edited: 03 Nov 96 17:53 $miro
};

public method .try() {
    arg lock, obj;
    
    return ((lock[1]) in (obj.owners())) || ($sys.is_system(obj));
    
    // $#Edited: 03 Nov 96 17:53 $miro
};

public method .lock_name() {
    arg value, @type;
    
    return "owner:" + ((value[1]).name());
};


new object $carry_lock_frob: $lock_frob;

var $root manager = $carry_lock_frob;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855862163;
var $root inited = 1;
var $root managed = [$carry_lock_frob];

public method .try() {
    arg lock, obj;
    
    lock = lock[1];
    return (lock == obj) || ((lock in (obj.contents())) || ((obj == sender()) || ($sys.is_system(obj))));
    
    // $#Edited: 13 Feb 97 13:06 $miro
};

public method .lock_name() {
    arg value, @type;
    
    return "owner:" + ((value[1]).name());
    
    // $#Edited: 13 Feb 97 12:31 $miro
};

public method .new() {
    return (<this(), #[]>);
    
    // $#Edited: 13 Feb 97 12:31 $miro
};


new object $parent_lock_frob: $lock_frob;

var $root manager = $parent_lock_frob;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856053423;
var $root inited = 1;
var $root managed = [$parent_lock_frob];

public method .try() {
    arg lock, obj;
    
    return ((lock[1]).has_ancestor(obj)) || ($sys.is_system(obj));
    
    // $#Edited: 15 Feb 97 17:39 $brad
    // $#Edited: 15 Feb 97 17:53 $brad
};

public method .new_lock() {
    arg obj;
    
    if (type(obj) != 'objnum)
        throw(~perm, "Argument is not a dbref.");
    return (<this(), [obj]>);
    
    // $#Edited: 03 Nov 96 17:53 $miro
    // $#Copied 15 Feb 97 17:40 from $owner_lock_frob.new_lock() by $brad
};

public method .lock_name() {
    arg value, @type;
    
    return "parent:" + ((value[1]).name());
    
    // $#Edited: 15 Feb 97 17:41 $brad
};


new object $not: $logic_frob;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $not;
var $root managed = [$not];
var $root owned = [$not];

public method .test() {
    arg notlist, @args;
    var val;
    
    catch ~range {
        catch ~type, ~methodnf
            return !((notlist[1]).test(@args));
        with
            return !(notlist[1]);
    } with {
        return 1;
    }
};

frob method .unparse() {
    arg notlist;
    
    catch any {
        catch ~type, ~methodnf
            return "!" + ((notlist[1]).unparse());
        with
            return "!" + tostr(notlist[1]);
    } with {
        return "!()";
    }
    
    // $#Edited: 11 Dec 96 09:48 $brandon
};


new object $not_lock_frob: $not;

var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $not_lock_frob;
var $root managed = [$not_lock_frob];
var $root owned = [$not_lock_frob];

public method .new_lock() {
    arg lock;
    
    if (type(lock) != 'frob)
        throw(~perm, "Argument is not a lock.");
    return (<this(), [lock]>);
};

public method .try() {
    arg lock, obj;
    
    return !((lock[1]).try(obj));
};

public method .lock_name() {
    arg lock, @type;
    
    [(type ?= 'literal)] = type;
    switch (type) {
        case 'literal:
            return ("(!" + ((lock[1]).lock_name(type))) + ")";
        default:
            return "not " + ((lock[1]).lock_name(type));
    }
    
    // $#Edited: 30 Nov 96 21:22 $miro
};


new object $or: $logic_frob;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $or;
var $root managed = [$or];
var $root owned = [$or];

public method .test() {
    arg orlist, @args;
    var val, x;
    
    val = 0;
    for x in (orlist) {
        catch ~type, ~methodnf
            val = x.test(@args);
        with
            val = x;
        if (val)
            break;
    }
    return val;
};

frob method .unparse() {
    arg orlist;
    var str, x;
    
    str = "";
    for x in (orlist) {
        catch any
            str = (str + (x.unparse())) + " || ";
        with
            str = (str + tostr(x)) + " || ";
    }
    return ("(" + (str && (str.subrange(1, (str.length()) - 4)))) + ")";
    
    // $#Edited: 11 Dec 96 09:48 $brandon
};


new object $or_lock_frob: $or;

var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $or_lock_frob;
var $root managed = [$or_lock_frob];
var $root owned = [$or_lock_frob];

public method .new_lock() {
    arg lhs, rhs;
    
    if ((type(lhs) != 'frob) || (type(rhs) != 'frob))
        throw(~perm, "Arguments are not both frobs.");
    return (<this(), [lhs, rhs]>);
};

public method .try() {
    arg lock, obj;
    
    return ((lock[1]).try(obj)) || ((lock[2]).try(obj));
};

public method .lock_name() {
    arg lock, @type;
    
    [(type ?= 'literal)] = type;
    switch (type) {
        case 'literal:
            return ((("(" + ((lock[1]).lock_name(type))) + " || ") + ((lock[2]).lock_name(type))) + ")";
        default:
            return (((lock[1]).lock_name(type)) + " or ") + ((lock[2]).lock_name(type));
    }
    
    // $#Edited: 30 Nov 96 21:22 $miro
};


new object $true: $logic_frob;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $true;
var $root managed = [$true];
var $root owned = [$true];

frob method .unparse() {
    arg dummy;
    
    return "yes";
};

public method .test() {
    arg @args;
    
    return 1;
};


new object $true_lock_frob: $true;

var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $true_lock_frob;
var $root managed = [$true_lock_frob];
var $root owned = [$true_lock_frob];

public method .new_lock() {
    return (<this(), []>);
};

public method .try() {
    arg lock, obj;
    
    return 1;
};


new object $false: $logic_frob;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $false;
var $root managed = [$false];
var $root owned = [$false];

frob method .unparse() {
    arg dummy;
    
    return "no";
};

public method .test() {
    arg @args;
    
    return 0;
};


new object $false_lock_frob: $false;

var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $false_lock_frob;
var $root managed = [$false_lock_frob];
var $root owned = [$false_lock_frob];

public method .new_lock() {
    return (<this(), []>);
};

public method .try() {
    arg lock, obj;
    
    return 0;
};


new object $realm: $frob, $has_name, $realm_settings, $event_handler;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['uniq, "Realm", "the Realm"];
var $realm local = #[['weather, "nice"], ['weather_text, <$ctext_frob, [[], #[]]>], ['map_position, [0, 0, "00"]], ['map_object, $generic_map], ['climate, $climate], ['location, 'interior], ['season, "summer"], [$place, 'interior], ['timeobject, $world_time], ['timezone, 0]];
var $root manager = $realm;
var $root managed = [$realm];
var $root owned = [$realm];
var $realm links = 0;
var $root trusted_by = [$world];
var $root defined_settings = #[["weather-time", #[['get, ['get_realm_setting]], ['parse, ['parse_weather_time]], ['format, ['format_weather_time]]]]];
var $root settings = #[["weather-time", [$weather_1, "spring", $climate_taobh_thiar, 0, $world_time, 0]], ["propagate", 1]];

public method .new() {
    var i;
    
    (sender().is($place)) || throw(~place, sender() + " is not a place.");
    local = local.setadd(sender());
    .cleanup_local();
    return this();
    
    // $#Edited: 15 Feb 97 20:04 $miro
};

public method .init_realms_frob() {
    local = #[];
    
    // $#Edited: 12 Aug 96 17:54 $jenner
};

root method .uninit_realms_frob() {
    var x;
    
    for x in (local)
        (| (x[1]).set_realm($realm_of_creation) |);
};

public method .place_destroyed() {
    arg @args;
    
    (sender() == (.manager())) || (> .perms(caller(), $place) <);
    (| (local = local.setremove(sender())) |);
};

public method .local() {
    return local;
    
    // $#Edited: 12 Aug 96 17:54 $jenner
};

frob method .name() {
    arg @args;
    
    return (> pass(@args) <);
    
    // $#Edited: 15 Feb 97 19:46 $miro
};

public method .realm_name() {
    var realms;
    
    realms = .realms();
    if ((realms.length()) > 2)
        realms = [realms[1], realms.last()];
    return realms.join(", ");
    
    // $#Edited: 15 Feb 97 19:46 $miro
};

public method .realms() {
    var r;
    
    if (definer() == this())
        return [];
    return [.name()] + (((.parents())[1]).realms());
    
    // $#Edited: 15 Feb 97 19:46 $miro
};

public method .cleanup_local() {
    var i, t;
    
    t = this();
    local = filter i in (local) where ((| (i.realm()) == t |));
    
    // $#Edited: 19 Feb 97 02:23 $miro
};

root method .uninit_realm() {
    var x;
    
    for x in (local)
        (| x.set_realm($realm_of_creation) |);
    
    // $#Edited: 15 Feb 97 20:04 $miro
};

public method .init_realm() {
    local = [];
    links = #[];
    
    // $#Edited: 15 Feb 97 20:04 $miro
};

public method .ctext_variables() {
    var climate, weather, season, depend, timeobj, timezone, ret;
    
    [weather, season, climate, depend, timeobj, timezone] = .get_setting("weather-time", $realm);
    ret = (| climate.ctext_variables(weather, season) |) || #[];
    ret = ret.add('daytime, timeobj.daytime(timezone, (| climate.daylength(season) |) || 0));
    ret = ret.add('evaluator, $realm_base_eval);
    return ret;
};

public method .add_exit_to() {
    arg dest;
    
    (> .perms(caller(), $place) <);
    if ((dest.realm()) != this()) {
        links = links || #[];
    
        // Do a quick sanity check before adding a new cross-realm exit
        ._check_links();
    
        // The format is: links, source, destination, path source->dest
        links = links.add_elem(dest.realm(), [this(), sender(), dest, []]);
    }
    
    // $#Edited: 19 Feb 97 02:23 $miro
};

public method ._check_links() {
    arg @propagate_check;
    var i, j, k, d;
    
    (caller() == $realm_admin_ui) || (> .perms(caller(), $realm) <);
    d = #[];
    for i in (links || #[]) {
        for j in (i[2]) {
            // Run at low priority...
            refresh();
            if (!(j[4])) {
                if ((j[2]).is_connected_to(j[3]))
                    d = d.add_elem(i[1], j);
            } else if (((j[2]).is_connected_to((j[4])[1])) && ((!find k in [1 .. ((j[4]).length()) - 1] where (refresh() && (!(((j[4])[k]).is_connected_to((j[4])[k + 1]))))) && (((j[4]).last()).is_connected_to(j[3])))) {
                d = d.add_elem(i[1], j);
            }
        }
    }
    links = d;
    if (propagate_check)
        (| ((.parents())[1])._check_links(@propagate_check) |);
    
    // $#Edited: 15 Feb 97 19:46 $miro
};

public method .advance_weather() {
    var d, new;
    
    (caller() == $world) || (> .perms(sender()) <);
    d = .get_setting("weather-time", $realm);
    new = (d[3]).advance(d[1], d[2], (d[4]) || []);
    if (new != (d[1])) {
        d = d.replace(1, new);
        .set_setting("weather-time", $realm, d);
        .realm_announce(new.eval_message("invoke", $weather, .ctext_variables()));
    }
};

public method .realm_announce() {
    arg message;
    
    (caller() == this()) || (> .perms(sender()) <);
    $world.send_event('realm_announce, message);
    
    // $#Edited: 07 Mar 97 16:32 $miro
};

public method .parse_weather_time() {
    arg value;
    var m, climate, depend, i, obj, tmp, str;
    
    if (type(value) == 'list)
        value = (value.join()).trim();
    value = (| (value.regexp("^(.+) (.+) in (.+),([^+-]+)([+-] *[0-9]+)?$")).mmap('trim) |);
    if (!value)
        throw(~type, "Value is not parsable as weather/time data.");
    if ((value.length()) < 5)
        value += ["0"];
    if ((m = (value[3]).match_pattern("* influenced by *"))) {
        value = value.replace(3, (m[1]).trim());
        depend = [];
        for i in ((((m[2]).trim()).split(";")).mmap('trim)) {
            refresh();
            [tmp, (str ?= "=50%")] = (i.regexp("([^=]+)(= *[0-9]+%)?")).mmap('trim);
            str = toint(((str.match_pattern("=*%"))[1]).trim());
            if (!(obj = $place_lib.match_realm(tmp)))
                throw(~match, ("Can't find realm " + tmp) + ".");
            depend += [[obj, str]];
        }
        depend ?= 0;
    } else {
        depend = 0;
    }
    if ((m = (value[3]).match_pattern("*($*)")))
        value = value.replace(3, "$" + (m[2]));
    if ((m = (value[4]).match_pattern("*($*)")))
        value = value.replace(4, "$" + (m[2]));
    climate = (> $object_lib.to_dbref(value[3]) <);
    return (> [climate.match_weather(value[1]), value[2], climate, depend, $object_lib.to_dbref(value[4]), toint((value[5]).replace(" ", ""))] <);
};

public method .format_weather_time() {
    arg value;
    var out, i;
    
    out = "%l %l in %l%l, %l".format((value[1]).name(), value[2], (value[3]).namef('ref), (value[4]) ? " influenced by " + (map i in (value[4]) to (((i[1]).name()) + (((i[2]) == 50) ? "" : ((" = " + (i[2])) + "%"))).join("; ")) : "", (value[5]).namef('ref));
    if ((value[6]) > 0)
        out += "+";
    if ((value[6]) != 0)
        out += value[6];
    return out;
};


new object $realm_of_creation: $realm;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "<Creation>", "<Creation>"];
var $realm local = [$nowhere, $body_cave, $void, $place, $the_pit];
var $root manager = $realm_of_creation;
var $root managed = [$realm_of_creation];
var $root owned = [$realm_of_creation];
var $realm links = #[];
var $root settings = #[["propagate", 1]];

public method .core_realm_of_creation() {
    local = [$the_pit];
    links = #[];
    
    // $#Edited: 15 Feb 97 19:46 $miro
};


new object $thing_frob: $frob, $thing;

var $root child_index = 7;
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core, 'frob];
var $located location = $void;
var $located obvious = 1;
var $described prose = [];
var $has_name name = ['uniq, "Thing Frob", "the Thing Frob"];
var $root manager = $thing_frob;
var $root managed = [$thing_frob];
var $root owned = [$thing_frob];
var $thing gender = $gender_neuter;

frob method .match_name() {
    arg this, str;
    var t, m;
    
    if ((m = match_begin((this['name])[2], str)))
        return 1;
    if (this.contains('name_templates)) {
        for t in (this['name_templates]) {
            if ((m = match_template(str, t)))
                return 1;
        }
    }
    return 0;
};

frob method .location() {
    arg this;
    
    return (| this['location] |) || $nowhere;
};

frob method .did_move() {
    arg this;
    
    return (<this(), this>);
};

frob method .is_obvious_to() {
    arg this, whom;
    
    return 1;
};

frob method .will_move() {
    arg this, mover, place;
    
    if (!(> .try_lock(this, mover) <))
        throw(~locked, ((((.name()).capitalize()) + " is locked to ") + ((this['lock]).lock_name('thing))) + ".");
    return 1;
};

frob method .prose() {
    arg this, @no_default;
    
    return (| this['prose] |) || (no_default ? 0 : "You see nothing special");
};

frob method .namef() {
    arg dict, @args;
    
    return .name(dict);
};

private method .change_data() {
    arg this, what, new, @remove;
    
    if (valid(this['location]))
        (this['location]).del_frob_from_contents((<this(), this>));
    if (remove)
        this = this.del(what);
    else
        this = this.add(what, new);
    if (valid(this['location]))
        (this['location]).add_frob_to_contents((<this(), this>));
    return (<this(), this>);
};

frob method .manager() {
    arg this;
    
    return this['manager];
};

frob method .description() {
    arg this, flags;
    var out;
    
    out = (<$ctext_frob, [[(<$format, ["subj", [], [.name(this)], 'do_subj]>)], #[]]>);
    if ((| flags['prose] |))
        return [out, .prose(this)];
    return [out];
};

frob method .name_templates() {
    arg this;
    
    return (| this['name_templates] |) || [];
};

frob method .get_description(): nooverride {
    arg this, @dflags;
    var flags, f;
    
    flags = #[['prose, 1], ['actor, sender()]];
    if (dflags && (type(dflags[1]) == 'dictionary)) {
        dflags = dflags[1];
        for f in (dflags.keys())
            flags = dict_add(flags, f, dflags[f]);
    }
    return .description(this, flags);
};

frob method .all_remote_commands() {
    arg this;
    
    return pass();
};

frob method .remote_commands() {
    arg this;
    
    return pass();
};

frob method .set_prose() {
    arg this, new;
    
    return .change_data(this, 'prose, new);
};

frob method .set_name() {
    arg this, new, @args;
    var type;
    
    if (!new)
        return;
    if (new && ((new[1]) in ["$", "#"]))
        throw(~invname, "Names cannot begin with \"$\" or \"#\".");
    if (match_regexp(new, "^(a|an|the) +"))
        throw(~bad_name, "Do not include articles in name, use +u +n or +p instead.");
    [(type ?= 'normal)] = args;
    switch (type) {
        case 'prop:
            new = [type, new, new];
        case 'uniq:
            new = [type, new, "the " + new];
        case 'normal:
            new = [type, new, ((new.a_or_an()) + " ") + new];
        default:
            throw(~invarg, "Type must be one of: 'prop, 'normal or 'uniq.");
    }
    return .change_data(this, 'name, new);
    
    // $#Edited: 30 Nov 96 20:00 $miro
};

public method .new() {
    var name, prose, data, n;
    
    return (<this(), #[['prose, []], ['location, sender()], ['manager, sender()], ['name, .name('literal)]]>);
};

frob method .del_name_template() {
    arg this, template;
    var new;
    
    new = setremove(.name_templates(this), template);
    return .change_data(this, 'name_templates, new);
};

frob method .name() {
    arg dict, @args;
    var name;
    
    name = dict['name];
    if (!name)
        return tostr(this());
    if (!args)
        return name[3];
    switch (args[1]) {
        case 'type:
            return name[1];
        case 'noarticle:
            return name[2];
        default:
            return name;
    }
};

frob method .add_name_template() {
    arg this, template;
    var new;
    
    new = setadd(.name_templates(this), template);
    return .change_data(this, 'name_templates, new);
};

frob method .get_command_info() {
    arg this, @args;
    
    return pass(@args);
};

frob method .discard() {
    arg data;
    
    //// just allow anybody to discard for now..
    //  if (data['manager] != sender())
    //      throw(~perm, "You are not the manager of " + .name(data));
    (data['location]).del_frob_from_contents((<this(), data>));
};

frob method .move_to() {
    arg data, place;
    var location;
    
    if (!(place.has_ancestor($location)))
        throw(~type, "Argument is not a location.");
    location = data['location];
    if (!valid(location))
        location = $nowhere;
    (> .will_move(data, sender(), place) <);
    return .change_data(data, 'location, place);
};

frob method .perms() {
    arg this, what, @args;
    
    return (what == (this['manager])) || (> (this['location]).perms(what, @args) <);
};

frob method .visibility() {
    arg this, @args;
    
    return (| this['visibility] |) || 0;
};

public method .new_with() {
    arg @args;
    var name, prose, data, n;
    
    name = (listlen(args) > 0) && (args[1]);
    prose = (listlen(args) > 1) && (args[2]);
    new = .new();
    if (prose)
        new = new.set_prose(prose);
    if (name)
        new = new.set_name(name);
    return new;
};

frob method .configure() {
    arg this, set;
    var p, end, ctext, s, still, type;
    
    (> .perms(this, sender()) <);
    s = sender();
    still = ("Do you still want to describe " + (.name(this))) + "? [no] ";
    if (!(set.contains('described_prose))) {
        while (!end) {
            if (.is(this, $exit))
                type = "exit ";
            else
                type = "";
            p = s.read((("Describe " + type) + (.name(this))) + ", Enter \".\" to finish or \"@abort\" to abort description.");
            if (p == 'aborted) {
                end = !(s.prompt_yesno(still, 0));
            } else {
                catch any {
                    ctext = (> $compiler.compile_cml(p) <);
                    s.tell(["You submitted the following description:", ""]);
                    s.tell(ctext);
                    s.tell("");
                    if (!(end = s.prompt_yesno("Keep this description? [yes] ")))
                        ctext = 0;
                } with {
                    s.tell(["The following CML compiler error occurred:", "  ", (traceback()[1])[2]]);
                    end = !(s.prompt_yesno(still, 0));
                }
            }
        }
        if (ctext)
            this = (.set_prose(this, ctext)).value();
        set = set.add('described_prose, 1);
    }
    return [this, set];
};

frob method .set_visibility() {
    arg this, value;
    
    return .change_data(this, 'visibility, value);
};

frob method .get_msg(): nooverride {
    arg this, name, definer;
    
    return dict_union(definer.get_default_msg(name), (| (this['msgs])[name] |) || #[]);
};

frob method .eval_message() {
    arg this, name, definer, vars;
    var eval, msg;
    
    eval = (| definer.get_msg_attr(name, 'evaluator) |) || $bs_eval;
    msg = $message_frob.new_with(.get_msg(this, name, definer));
    vars = dict_add(vars, 'evaluator, eval);
    msg = msg.set_vars(vars);
    vars = dict_add(vars, 'time, 'pre);
    return msg.eval_ctext(vars);
};

frob method .set_msg(): nooverride {
    arg this, name, branch, definer, value;
    var compiler, branches, msg, definer, msgs;
    
    (> .perms(this, sender()) <);
    compiler = (| definer.get_msg_attr(name, 'compiler) |) || $compiler;
    value = (> compiler.compile_cml(value) <);
    branch ?= "general";
    if (!(branch in (definer.get_msg_attr(name, 'branches))))
        throw(~badbranch, ((("Message branch \"" + name) + ".") + branch) + "\" is not defined.");
    if (dict_contains(this, 'msgs))
        msgs = this['msgs];
    else
        msgs = #[];
    msg = dict_add((| msgs[name] |) || #[], branch, value);
    msgs = dict_add(msgs, name, msg);
    return .change_data(this, 'msgs, msgs);
};

frob method .clear_msg(): nooverride {
    arg this, name, @branches;
    var messages, branch, msg;
    
    (caller() != definer()) && (> .perms(this, sender()) <);
    if (dict_contains(this, 'msgs))
        messages = this['msgs];
    else
        messages = #[];
    if (!dict_contains(messages, name))
        return;
    if (!branches) {
        messages = dict_del(messages, name);
    } else {
        msg = messages[name];
        for branch in (branches) {
            if (dict_contains(msg, branch))
                msg = dict_del(msg, branch);
        }
        if (!msg)
            messages = dict_del(messages, name);
    }
    if (!messages)
        return .change_data(this, 'msgs, 0, 'remove);
    else
        return .change_data(this, 'msgs, messages);
};

frob method .all_msgs(): nooverride {
    arg this;
    
    if (dict_contains(this, 'msgs))
        return pass(this['msgs]);
    return pass();
};

frob method .msg_definer(): nooverride {
    arg this, name;
    
    return pass(name);
};

frob method .get_setting(): nooverride {
    arg this, name, definer;
    var i, settings;
    
    i = definer.setting_info(name);
    if (dict_contains(i, 'access))
        (> .((i['access])[1])(this, name, sender(), caller(), @sublist(i['access], 2.0)) <);
    if (dict_contains(i, 'get))
        return (> .((i['get])[1])(this, name, definer, @sublist(i['get], 2)) <);
    if ((!dict_contains(this, 'settings)) || (!dict_contains(this['settings], name)))
        return (> pass(name, definer) <);
    return (this['settings])[name];
};

frob method .set_setting(): nooverride {
    arg this, name, definer, value;
    var i, args, settings;
    
    (> .perms(this, sender()) <);
    i = (> definer.setting_info(name) <);
    if (dict_contains(i, 'parse)) {
        args = sublist(i['parse], 2);
        catch ~methodnf
            value = (> .((i['parse])[1])(value, @args) <);
        with
            value = (> $settings.((i['parse])[1])(value, @args) <);
    }
    if (dict_contains(i, 'set)) {
        return (> .((i['set])[1])(this, name, definer, value, @sublist(i['set], 2)) <);
    } else {
        settings = dict_add((| this['settings] |) || #[], name, value);
        return .change_data(this, 'settings, settings);
    }
};

frob method .clear_setting(): nooverride {
    arg this, name, definer;
    var info, args, settings;
    
    (caller() == definer()) || (> .perms(this, sender()) <);
    info = (> definer.setting_info(name) <);
    if (dict_contains(info, 'clear)) {
        args = sublist(info['clear], 2);
        return (> .((info['clear])[1])(this, name) <);
    } else if (dict_contains(this, 'settings) && dict_contains(this['settings], name)) {
        settings = dict_del(settings, name);
        if (!settings)
            return .change_data(this, 'settings, 0, 'remove);
        else
            return .change_data(this, 'settings, settings);
    }
};

frob method .all_defined_settings() {
    arg this;
    
    return pass();
};

frob method .setting_definer(): nooverride {
    arg this, name;
    
    return pass(name);
};

frob method .format_setting(): nooverride {
    arg this, name, definer, value;
    var i, args;
    
    return pass(name, definer, value);
};

frob method .set_gender(): nooverride {
    arg name, definer, value;
    
    throw(~perm, "You cannot set the gender on frobs, sorry.");
};

public method .try_lock() {
    arg this, @args;
    
    return (| this['lock] |) ? (this['lock]).try(@args) : 1;
    
    // $#Edited: 17 Mar 97 02:55 $miro
};

frob method .local_commands() {
    arg this;
    
    return pass();
};

frob method .shortcuts() {
    arg this;
    
    return pass();
};

frob method .all_local_commands() {
    arg this;
    
    return pass();
    
    // $#Edited: 17 Mar 97 21:50 $brandon
};

frob method .all_shortcuts() {
    arg this;
    
    return pass();
};


new object $wearable_frob: $thing_frob;

var $root child_index = 9;
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $described prose = [];
var $has_name name = ['normal, "Generic Wearable Frob", "a Generic Wearable Frob"];
var $has_commands remote = #[];
var $root manager = $wearable_frob;
var $located location = $lost_and_found;
var $root managed = [$wearable_frob];
var $root owned = [$wearable_frob];
var $thing gender = 0;

frob method .wear() {
    arg this;
    
    if ((this['location]) != sender())
        throw(~perm, ("You are not holding " + (.name(this))) + ".");
    return .change_data(this, 'worn, sender());
    
    // $#Edited: 13 Dec 96 19:58 $user_vang
    // $#Edited: 16 Dec 96 20:11 $user_vang
};

public method .new() {
    return .to_frob((pass().value()).add('worn, 0));
    
    // $#Edited: 13 Dec 96 16:36 $brandon
    // $#Edited: 13 Dec 96 19:58 $user_vang
    // $#Edited: 16 Dec 96 20:11 $user_vang
};

protected method .change_data() {
    arg this, what, new;
    
    // hairy
    if (!(this['worn])) {
        if (what != 'worn)
            return pass(this, what, new);
        else
            (this['location]).del_frob_from_contents((<this(), this>));
    } else if (valid(this['worn])) {
        (this['worn]).shed((<this(), this>));
    }
    this = dict_add(this, what, new);
    if (valid(this['worn]))
        (this['worn]).wear((<this(), this>));
    else if (valid(this['location]))
        (this['location]).add_frob_to_contents((<this(), this>));
    return (<this(), this>);
    
    // $#Edited: 13 Dec 96 19:58 $user_vang
    // $#Edited: 16 Dec 96 20:11 $user_vang
};

frob method .shed() {
    arg this;
    
    if (!(this['worn]))
        throw(~perm, ("You are not wearing " + (.name(this))) + ".");
    if ((this['worn]) != sender())
        throw(~perm, ((("Remove " + (.name(this))) + " from ") + sender()) + "!?");
    return .change_data(this, 'worn, 0);
    
    // $#Edited: 13 Dec 96 19:58 $user_vang
    // $#Edited: 16 Dec 96 20:11 $user_vang
};


new object $exit: $physical;

var $exit source = $void;
var $exit dest = $void;
var $exit lock = <$true_lock_frob, []>;
var $root child_index = 386;
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $described prose = [];
var $has_name name = ['uniq, "Generic Exit", "the Generic Exit"];
var $has_commands remote = #[["@lock", [["@lock", "*", "@lock <this>", 'lock_cmd, #[[1, ['this, []]]]], ["@lock", "* with|to *", "@lock <this> with|to <any>", 'lock_with_cmd, #[[1, ['this, []]], [3, ['any, []]]]]]], ["@unlock", [["@unlock", "*", "@unlock <this>", 'unlock_cmd, #[[1, ['this, []]]]]]], ["open", [["open", "*", "open <this>", 'open_cmd, #[[1, ['this, []]]]]]], ["close", [["close", "*", "close <this>", 'close_cmd, #[[1, ['this, []]]]]]]];
var $exit closed = 0;
var $exit closable = 0;
var $root manager = $exit;
var $root owned = [$exit];
var $foundation defined_msgs = #[["invoke", #[['branches, ["actor", "source", "dest"]]]], ["exit-open", #[['branches, ["actor", "general"]]]], ["exit-close", #[['branches, ["actor", "general"]]]], ["lock-fail", #[['branches, ["general", "actor"]]]], ["lock-try", #[['branches, ["general", "actor"]]]], ["lock-unlock", #[['branches, ["general", "actor"]]]], ["lock-lock", #[['branches, ["general", "actor"]]]], ["exit-closed", #[['branches, ["actor", "general"]]]]];
var $foundation msgs = #[["invoke", #[["actor", <$ctext_frob, [["You take ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $exit]]]>], ["source", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " goes through ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $exit]]]>], ["dest", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " arrives."], #[['this, $exit]]]>]]], ["exit-close", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " closes ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $exit]]]>], ["actor", <$ctext_frob, [["You close ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $exit]]]>]]], ["exit-open", #[["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " opens ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $exit]]]>], ["actor", <$ctext_frob, [["You open ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $exit]]]>]]], ["lock-fail", #[["actor", <$ctext_frob, [[<$generator, ["this", [], [], 'gen_this]>, " is locked."], #[['this, $exit]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " tries to take ", <$generator, ["this", [], [], 'gen_this]>, " but its locked!"], #[['this, $exit]]]>]]], ["lock-try", #[["actor", <$ctext_frob, [["You use ", <$generator, ["lock", [], [], 'gen_lock]>, " on ", <$generator, ["this", [], [], 'gen_this]>, "."], #[['this, $exit]]]>], ["general", <$ctext_frob, [[], #[['this, $exit]]]>]]], ["lock-unlock", #[["actor", <$ctext_frob, [["You unlock ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $exit]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " unlocks ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $exit]]]>]]], ["lock-lock", #[["actor", <$ctext_frob, [["You lock ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $exit]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " locks ", <$generator, ["this", [], [], 'gen_this]>, <$generator, ["withlock", [], [], 'gen_withlock]>, "."], #[['this, $exit]]]>]]], ["exit-closed", #[["actor", <$ctext_frob, [["You try to go through ", <$generator, ["this", [], [], 'gen_this]>, " but it is closed!"], #[['this, $exit]]]>], ["general", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " tries to take ", <$generator, ["this", [], [], 'gen_this]>, " but it is closed!"], #[['this, $exit]]]>]]]];
var $root settings = #[["closable", "no"]];
var $root defined_settings = #[["closable", #[['get, ['get_closable]], ['set, ['set_closable]], ['clear, ['clear_closable]], ['parse, ['is_boolean]], ['format, ['format_boolean]]]]];
var $root managed = [$exit];

root method .uninit_exit() {
    (| .detach() |);
    (| clear_var('source) |);
    (| clear_var('dest) |);
    (| clear_var('lock) |);
};

public method .invoke() {
    arg @flags;
    var s, here, vars, m, actor, ln, v;
    
    s = (actor = sender());
    if (closed) {
        m = .eval_message("exit-closed", $exit, .exit_msg_vars(s));
        return source.announce(m);
    }
    if (flags)
        flags = flags[1];
    else
        flags = #[];
    flags = flags.add('actor, s);
    flags = flags.add_elem('exclude, s);
    if (!valid(.dest()))
        return s.tell((.name()) + " has an invalid destination!");
    if (lock && (!(lock.try(s)))) {
        v = #[["lock", lock.lock_name()]];
        m = .eval_message("lock-fail", $exit, .exit_msg_vars(s, v));
        return source.announce(m);
    }
    s.move_to(dest);
    m = .eval_message("invoke", $exit, .exit_msg_vars(s));
    dest.announce(m);
    source.announce(m);
};

public method .lock() {
    return lock || ($true_lock_frob.new());
};

public method .attach() {
    arg src, dst, @ignore;
    
    (> .perms(sender()) <);
    (src.is($place)) || throw(~place, (source.namef('ref)) + " is not a place.");
    (dst.is($place)) || throw(~place, (dest.namef('ref)) + " is not a place.");
    (| .detach() |);
    (> src.will_attach('source, sender()) <);
    (> dst.will_attach('dest, sender()) <);
    source = src;
    dest = dst;
    (> source.attach_exit('source, this()) <);
    (> dest.attach_exit('dest, this()) <);
};

public method .dest() {
    return dest;
};

public method .source() {
    return source;
};

public method .place_destroyed() {
    arg place;
    
    (> .perms(caller(), $place) <);
    .detach();
    if (sender() in [dest, source])
        $sys.destroy_sender();
};

public method .destination_destroyed() {
    var msg, line, name;
    
    (> .perms(caller(), $place) <);
    $sys.destroy_sender();
};

private method .detach(): nooverride {
    source && (source.detach_exit('source, this()));
    dest && (dest.detach_exit('dest, this()));
};

public method .lock_cmd() {
    arg cmdstr, cmd, this;
    
    if (!(| .perms(sender()) |))
        return ((("Only " + ((.manager()).name())) + " can lock ") + (.name())) + "!";
    lock = $false_lock_frob.new();
    return "You lock " + (.name());
};

public method .lock_with_cmd() {
    arg cmdstr, cmd, this, prep, str;
    
    if (!(| .perms(sender()) |))
        return ((("Only " + ((.manager()).name())) + " can lock ") + (.name())) + "!";
    catch ~objnf, ~parse {
        lock = $lock_parser.parse(str, sender());
        return ((("You lock " + (.name())) + " to allow ") + (lock.lock_name('exit))) + ".";
    } with {
        switch (error()) {
            case ~objnf:
                return "Object not found in lock string.";
            case ~parse:
                return "Invalid lock string.";
        }
    }
};

public method .unlock_cmd() {
    arg cmdstr, cmd, this;
    
    if (!(| .perms(sender()) |))
        return ((("Only " + ((.manager()).name())) + " can lock ") + (.name())) + "!";
    lock = $true_lock_frob.new();
    sender().tell("You unlock " + (.name()));
};

public method .is_visible_to() {
    arg whom;
    
    return (.visibility()) >= ((whom.location()).darkness());
};

protected method .description() {
    arg flags;
    var desc;
    
    if (closed)
        return (> pass(flags) <) + [(.name()) + " is closed."];
    if ((!(| flags['prose] |)) || (!valid(.dest())))
        return (> pass(flags) <);
    return [(<$ctext_frob, [[(<$format, ["subj", [], [("Through " + (.name())) + " you see.."], 'do_subj]>)], #[]]>), (.dest()).get_description(flags)];
};

private method .invoke_notify() {
    arg actor, flags;
    var vars, m;
    
    if (flags.contains('simple)) {
        actor.tell("You take " + (.name()));
        (.dest()).announce((actor.name()) + " arrives.");
        (.source()).announce((((actor.name()) + " goes through ") + (.name())) + ".");
    } else {
        vars = #[["$actor", actor], ["actor", actor.name()], ["$source", .source()], ["source", (.source()).name()], ["$dest", .dest()], ["dest", (.dest()).name()], ["$exit", this()], ["exit", .name()]];
        m = .eval_message("invoke", $exit, vars);
        (.dest()).announce(m);
        (.source()).announce(m);
    }
};

public method .exit_msg_vars() {
    arg actor, @more;
    var vars;
    
    vars = #[["$actor", actor], ["actor", actor.name()], ["$source", source], ["source", source.name()], ["$dest", dest], ["dest", dest.name()], ["$this", this()], ["this", .name()], ["$lock", lock]];
    if (more)
        vars = dict_union(vars, more[1]);
    return vars;
};

public method .try_lock() {
    arg @args;
    
    lock.try(@args);
    
    // $#Edited: 17 Mar 97 02:48 $miro
};

public method .close_cmd() {
    arg cmdstr, cmd, this;
    var vars, m;
    
    catch ~locked
        .try_lock(sender());
    with
        return (traceback()[1])[2];
    if (closable) {
        if (closed) {
            return ((.name()).capitalize()) + " is already closed.";
        } else {
            closed = 1;
            vars = #[["$actor", sender()], ["actor", sender().name()], ["$this", this()], ["this", .name()]];
            m = .eval_message("exit-close", $exit, vars);
            source.announce(m);
            dest.announce(m);
        }
    } else {
        return ((.name()).capitalize()) + " cannot be closed.";
    }
};

public method .open_cmd() {
    arg cmdstr, cmd, this;
    var vars, m;
    
    catch ~locked
        .try_lock(sender());
    with
        return (traceback()[1])[2];
    if (closable) {
        if (closed) {
            clear_var('closed);
            vars = #[["$actor", sender()], ["actor", sender().name()], ["$this", this()], ["this", .name()]];
            m = .eval_message("exit-open", $exit, vars);
            source.announce(m);
            dest.announce(m);
        } else {
            return ((.name()).capitalize()) + " is already open.";
        }
    } else {
        return ((.name()).capitalize()) + " cannot be opened.";
    }
};

public method .get_closable() {
    arg name, definer;
    
    $brandon.tell("exit");
    return closable;
};

protected method .clear_closable() {
    arg name;
    
    (| clear_var('closable) |);
};


new object $coord_exit: $exit;

var $root manager = $coord_exit;
var $coord_exit coordinates = 0;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848977724;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $described prose = [];
var $exit source = $nowhere;
var $exit dest = $nowhere;
var $exit lock = <$true_lock_frob, []>;
var $root inited = 1;
var $root managed = [$coord_exit];

public method .coordinates() {
    return coordinates || [0, 0, 0];
};

public method .configure() {
    arg set;
    var s, radial, azimuth, distance, ans, c, dist, m;
    
    set = (> pass(set) <);
    if (set.contains('exit_coordinates))
        return set;
    s = sender();
    if (!(| s.get_setting("experienced", $user) |))
        s.tell($place_lib.build_hint(5));
    while (1) {
        ans = s.prompt(((("Exit coordinates for " + (.name())) + " (to ") + ((.dest()).name())) + ") ");
        if (ans == "@abort")
            throw(~abort, "Abort");
        if (ans == "@skip")
            return set;
        if (ans == "@shortcuts") {
            s.tell(["-- Coordinate Shortcuts:", map c in ($place_lib.coordinate_shortcuts()) to (strfmt(" %20l %7l %s", c[1], @c[2]))]);
            continue;
        }
        if (!ans) {
            s.tell("Invalid Coordinates.");
            continue;
        }
        catch ~coordnf, ~invcoord {
            if (ans.is_numeric()) {
                ans = ans.explode_english_list();
                if ((ans.length()) != 2) {
                    s.tell("Seperate coordinates with a comma.");
                    continue;
                }
                if ((!((ans[1]).is_numeric())) || (!((ans[2]).is_numeric()))) {
                    s.tell("Invalid coordinates.");
                    continue;
                }
                if ((!((ans[1]).is_numeric())) || (!((ans[2]).is_numeric()))) {
                    s.tell("Invalid coordinates.");
                    continue;
                }
                radial = toint(ans[1]);
                azimuth = toint(ans[2]);
            } else {
                ans = $place_lib.coordinates(ans);
                radial = ans[1];
                azimuth = ans[2];
            }
            (> $place_lib.valid_coordinates(radial, azimuth) <);
        } with {
            s.tell((traceback()[1])[2]);
            continue;
        }
    }
    while (!dist) {
        ans = s.prompt(("Distance from center of room (metric) [" + ($place_lib.get_default('distance))) + "] ");
        if (!ans)
            dist = $place_lib.get_default('distance);
        else if (ans == "@skip")
            return set;
        else if ((m = match_regexp(ans, "^ *([0-9]+) *M *$")))
            dist = toint(m[1]) * 100;
        else if ((m = match_regexp(ans, "^ *([0-9]+) *C?M? *$")))
            dist = toint(m[1]);
        else
            s.tell("Distance must be either centimeters (cm) or meters (m).");
    }
    coordinates = [radial, azimuth, dist];
    return set.add('exit_coordinates);
};

public method .uninit_coord_exit() {
    (| clear_var('coordinates) |);
    
    // $#Moved 27 Nov 96 11:26 from $exit.uninit_coord_exit() by $brandon
};


new object $exit_frob: $thing_frob, $exit;

var $root manager = $exit_frob;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 849130536;
var $has_name name = ['prop, "Exit Frob", "Exit Frob"];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $described prose = [];
var $located location = $void;
var $located obvious = 1;
var $root inited = 1;
var $root managed = [$exit_frob];
var $root child_index = 3;
var $thing gender = $gender_neuter;

frob method .invoke() {
    arg this, @flags;
    var s, here, vars, m, actor, ln, v, dest;
    
    s = (actor = sender());
    if (dict_contains(this, 'closed)) {
        m = .eval_message(this, "exit-closed", $exit, .exit_msg_vars(this, s));
        return (this['source]).announce(m);
    }
    if (flags)
        flags = flags[1];
    else
        flags = #[];
    flags = flags.add('actor, s);
    flags = flags.add_elem('exclude, s);
    dest = this['dest];
    if (!valid(dest))
        return s.tell((.name(this)) + " has an invalid destination!");
    if (!(> .try_lock(this, s) <)) {
        v = #[["lock", (this['lock]).lock_name()]];
        m = .eval_message(this, "lock-fail", $exit, .exit_msg_vars(this, s, v));
        return (this['source]).announce(m);
    }
    s.move_to(dest);
    vars = .exit_msg_vars(this, s);
    m = .eval_message(this, "invoke", $exit, vars);
    dest.announce(m);
    (this['source]).announce(m);
};

public method .change_data() {
    arg this, what, new, @remove;
    
    if (this['source])
        return (this['source]).update_exit_frob(this, what, new, @remove);
    else if (remove)
        return (<this(), this.del(what)>);
    else
        return (<this(), this.add(what, new)>);
};

frob method .invoke_notify(): forked {
    arg this, actor, flags;
    var vars, m, name;
    
    name = .name(this);
    if (flags.contains('simple)) {
        actor.tell("You take " + name);
        (this['dest]).announce((actor.name()) + " arrives.");
        (this['source]).announce((((actor.name()) + " goes through ") + name) + ".");
    } else {
        // this does not let you set specific messages on each exit--
        // we need to add $has_messages_frob
        vars = #[["$actor", actor], ["actor", actor.name()], ["$source", this['source]], ["source", (this['source]).name()], ["$dest", this['dest]], ["dest", (this['dest]).name()], ["$exit", this()], ["exit", name]];
        m = .eval_message(this, "invoke", $exit, vars);
        (this['dest]).announce(m);
        (this['source]).announce(m);
    }
};

frob method .lock() {
    arg this;
    
    if ((this.contains('lock)) && (this['lock]))
        return this['lock];
    return $true_lock_frob.new();
};

frob method .attach() {
    arg this, source, dest, @ignore;
    
    (source.is($place)) || throw(~place, (source.namef('ref)) + " is not a place.");
    (dest.is($place)) || throw(~place, (dest.namef('ref)) + " is not a place.");
    (| .detach() |);
    (> source.will_attach('source, sender()) <);
    (> dest.will_attach('dest, sender()) <);
    this = this.del('location);
    this = this.add('source, source);
    this = this.add('dest, dest);
    (> source.attach_exit('source, (<this(), this>)) <);
    (> dest.attach_exit('dest, (<this(), this>)) <);
};

frob method .dest() {
    arg this;
    
    return this['dest];
};

frob method .source() {
    arg this;
    
    return this['source];
};

frob method .place_destroyed() {
    arg this, place;
    
    (> .perms(this, caller(), $place) <);
    .detach(this);
};

frob method .destination_destroyed() {
    arg this;
    
    if (!(caller().is($place)))
        throw(~perm, "Must be called by $place");
    (this['source]).detach_exit('source, (<this(), this>));
};

frob method .detach(): nooverride {
    arg this;
    
    (this['source]) && (| (this['source]).detach_exit('source, (<this(), this>)) |);
    (this['dest]) && (| (this['dest]).detach_exit('dest, (<this(), this>)) |);
};

frob method .lock_cmd() {
    arg this, cmdstr, cmd, ignore;
    
    if (!(| .perms(this, sender()) |))
        return ((("Only " + ((.manager(this)).name())) + " can lock ") + (.name(this))) + "!";
    .change_data(this, 'lock, $false_lock_frob.new());
    return "You lock " + (.name(this));
};

frob method .lock_with_cmd() {
    arg this, cmdstr, cmd, ignore, prep, str;
    var frob;
    
    if (!(| .perms(this, sender()) |))
        return ((("Only " + ((.manager(this)).name())) + " can lock ") + (.name(this))) + "!";
    catch ~objnf, ~parse {
        frob = .change_data(this, 'lock, $lock_parser.parse(str, sender()));
        return ((("You lock " + (.name(this))) + " to allow ") + ((frob.lock()).lock_name('exit))) + ".";
    } with {
        switch (error()) {
            case ~objnf:
                return "Object not found in lock string.";
            case ~parse:
                return "Invalid lock string.";
        }
    }
};

frob method .unlock_cmd() {
    arg this, cmdstr, cmd, ignore;
    
    if (!(| .perms(this, sender()) |))
        return ((("Only " + ((.manager(this)).name())) + " can lock ") + (.name(this))) + "!";
    .change_data(this, 'lock, $true_lock_frob.new());
    return "You unlock " + (.name(this));
};

frob method .is_visible_to() {
    arg this, whom;
    
    return (.visibility(this)) >= ((whom.location()).darkness());
};

frob method .description() {
    arg this, flags;
    var desc;
    
    if (dict_contains(this, 'closed))
        return (> pass(this, flags) <) + [(.name(this)) + " is closed."];
    if ((!(| flags['prose] |)) || (!valid(this['dest])))
        return (> pass(this, flags) <);
    return [(<$ctext_frob, [[(<$format, ["subj", [], [("Through " + (.name(this))) + " you see.."], 'do_subj]>)], #[]]>), (this['dest]).get_description(flags)];
};

public method .new() {
    var this;
    
    this = (> pass() <).value();
    this = this.add('source, 0);
    this = this.add('dest, 0);
    return (<this(), this>);
};

frob method .will_move() {
    arg this, mover, place;
    
    throw(~nomove, "You cannot do that to an exit!");
};

frob method .discard() {
    arg data;
    
    if (!(.is_writable_by(sender())))
        throw(~perm, "Only writers and managers can discard exits.");
    return (> .detach(data) <);
};

public method .open() {
    arg this;
    
    return .change_data(this, 'closed, 0);
};

frob method .perms() {
    arg this, what, @args;
    
    return (what == (this['manager])) || (> (this['source]).perms(what, @args) <);
};

public method .default_exit_msg_vars() {
    arg this, actor, @more;
    var vars;
    
    vars = #[["actor", actor.name()], ["source", (this['source]).name()], ["dest", (this['dest]).name()], ["this", name]];
    if (more)
        vars = dict_union(vars, more[1]);
    return vars;
};

frob method .exit_msg_vars() {
    arg this, actor, @more;
    var vars, s, d;
    
    s = this['source];
    d = this['dest];
    vars = #[["$actor", actor], ["actor", actor.name()], ["$source", s], ["source", s.name()], ["$dest", d], ["dest", d.name()], ["$this", this()], ["this", .name(this)]];
    if (more)
        vars = dict_union(vars, more[1]);
    return vars;
};

frob method .all_defined_settings(): nooverride {
    arg this;
    var sets;
    
    sets = pass(this());
    sets = dict_del(sets, "home");
    sets = dict_del(sets, "gender");
    sets = dict_del(sets, "visibility");
    return sets;
};

public method .try_lock() {
    arg this, @args;
    
    return (| this['lock] |) ? (this['lock]).try(@args) : 1;
    
    // $#Edited: 17 Mar 97 02:55 $miro
};

frob method .close_cmd() {
    arg frob, cmdstr, cmd, this;
    var vars, m, source, dest;
    
    catch ~locked
        .try_lock(frob, sender());
    with
        return (traceback()[1])[2];
    if (dict_contains(frob, 'closable)) {
        if (dict_contains(frob, 'closed)) {
            return ((.name(frob)).capitalize()) + " is already closed.";
        } else {
            source = frob['source];
            dest = frob['dest];
            frob = .change_data(frob, 'closed, 1);
            vars = #[["$actor", sender()], ["actor", sender().name()], ["$this", frob], ["this", frob.name()]];
            m = frob.eval_message("exit-close", $exit, vars);
            source.announce(m);
            dest.announce(m);
        }
    } else {
        return ((.name(frob)).capitalize()) + " cannot be closed.";
    }
};

frob method .open_cmd() {
    arg frob, cmdstr, cmd, this;
    var vars, m, source, dest;
    
    catch ~locked
        .try_lock(frob, sender());
    with
        return (traceback()[1])[2];
    if (dict_contains(frob, 'closable)) {
        if (dict_contains(frob, 'closed)) {
            source = frob['source];
            dest = frob['dest];
            frob = .change_data(frob, 'closed, 0, 'remove);
            vars = #[["$actor", sender()], ["actor", sender().name()], ["$this", frob], ["this", frob.name()]];
            m = frob.eval_message("exit-open", $exit, vars);
            source.announce(m);
            dest.announce(m);
        } else {
            return ((.name(frob)).capitalize()) + " is already opened.";
        }
    } else {
        return ((.name(frob)).capitalize()) + " cannot be opened.";
    }
};

frob method .get_closable() {
    arg this, name, definer;
    
    return (| this['closable] |) || 0;
};

frob method .clear_closable() {
    arg this, name;
    
    if (dict_contains(this, 'closed))
        this = .change_data(this, 'closed, 0, 'remove);
    return .change_data(this, 'closable, 0, 'remove);
};

frob method .set_closable() {
    arg this, name, definer, value;
    
    if (value) {
        return .change_data(this, 'closable, 1);
    } else if (dict_contains(this, 'closable)) {
        if (dict_contains(this, 'closed))
            this = .change_data(this, 'closed, 0, 'remove);
        return .change_data(this, 'closable, 0, 'remove);
    }
    return (<this(), this>);
};


new object $read_parser: $frob;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $read_parser;
var $root managed = [$read_parser];
var $root owned = [$read_parser];

public method .parse_line() {
    arg dict, line;
    var cmd;
    
    if (!line) {
        // we have to do this as such, because of logic (shrug)
        dict = dict.add('status, 'not_done);
        return dict.add_elem('lines, line);
    } else if ((line[1]) == ".") {
        if (((line.length()) > 1) && ((line[2]) == "."))
            line = line.subrange(2);
        else if ((line.length()) == 1)
            return dict.add('status, 'done);
    
        //// No, bad Brandon, Bad, no scooby snack
        //// Decomment this if you want '>' to escape commands when reading
        //   } else if (line[1] == ">") {
        //       if (line.length() > 1 && line[2] == ">") {
        //           line = line.subrange(2);
        //       } else {
        //           dict = dict.add('command, line.subrange(2));
        //           return dict.add('status, 'pass_command);
        //       }
    } else if (line == "@abort") {
        return dict.add('status, 'abort);
    }
    dict = dict.add('status, 'not_done);
    return dict.add_elem('lines, line);
};

public method .new_with() {
    arg task_id, count;
    
    return (<this(), #[['lines, []], ['status, 'not_done], ['count, count], ['task_id, task_id]]>);
};

public method .parse() {
    arg dict, line;
    var line, result;
    
    // checks the incoming line to see if its a keeper, or a command.
    if ((dict['count]) == 'one) {
        dict = dict.add_elem('lines, line);
        return (<this(), dict.add('status, 'done)>);
    } else {
        return (<this(), .parse_line(dict, line)>);
    }
    
    // $#Edited: 08 Jan 96 18:31 Lynx ($lynx)
};

public method .status() {
    arg dict;
    
    return dict['status];
};

public method .task_id() {
    arg dict;
    
    return dict['task_id];
};

public method .lines() {
    arg dict;
    
    return dict['lines];
};

public method .command() {
    arg dict;
    
    return (| dict['command] |) || "";
};

public method .add() {
    arg dict, @args;
    
    return (<this(), (> dict.add(@args) <)>);
};


new object $callback: $frob;

var $root manager = $callback;
var $root created_on = 799275808;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root managed = [$callback];
var $root owned = [$callback];

public method .new() {
    arg method, static_args;
    
    return (<this(), [sender(), method, static_args]>);
};

public method .exec() {
    arg self, @args;
    
    return (self[1]).(self[2])(self[3], args);
};


new object $message_frob: $frob;

var $root manager = $message_frob;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root managed = [$message_frob];
var $root owned = [$message_frob];

public method .add_entry() {
    arg this, key, what;
    var data;
    
    this = this.add(key, what);
    return (<this(), this>);
};

public method .del_entry() {
    arg this, key;
    
    this = this.del(key);
    return (<this(), this>);
};

public method .eval_ctext() {
    arg this, vars;
    var key, new, temp, t, list, vars;
    
    new = .new();
    vars = vars.add('this, sender());
    if ("general" in (this.keys()))
        vars = vars.add("$general", "general");
    list = this.keys();
    for key in (list) {
        temp = ((this[key]).set_var('this, vars['this])).eval_ctext();
        new = new.add_entry((| vars["$" + key] |) || (vars[key]), temp);
    }
    return new;
};

public method .has_entry() {
    arg this, name;
    
    return name in (this.keys());
};

public method .get_part() {
    arg this, part;
    
    return this[part];
};

public method .uncompile() {
    arg this;
    var key, output;
    
    output = #[];
    for key in (this)
        output = output.add(key[1], (key[2]).uncompile());
    return output;
};

public method .parts() {
    arg this;
    
    return this.keys();
};

public method .message() {
    arg name, @definer;
    var a, message, mes, m;
    
    //retrieve the specified message as ctext
    if (definer)
        definer = definer[1];
    else
        definer = (._find_message_definer(name))[2];
    message = $message_frob.new();
    for a in (.ancestors()) {
        catch ~methodnf, ~messagenf
            return a.local_message(name, definer);
    }
    throw(~messagenf, "No matching message.");
};

public method .set_vars() {
    arg this, new;
    var d;
    
    for d in (this.keys())
        this = this.add(d, (this[d]).set_vars(new));
    return (<this(), this>);
};

public method .format() {
    arg this, vars;
    var new;
    
    new = (| this[vars['receiver]] |) || ((| this["general"] |) || ($ctext_frob.new_with([""])));
    new = new.set_vars(vars);
    new = new.format();
    return new;
};

public method .change_entry() {
    arg this, old, new;
    var value;
    
    value = (> this[old] <);
    this = dict_del(this, old);
    this = dict_add(this, new, value);
    return (<this(), this>);
};


new object $trie: $frob;

var $root manager = $trie;
var $root help_node = $help_obj_trie;
var $root created_on = 800074237;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root managed = [$trie];
var $root owned = [$trie];

public method .match_begin() {
    arg trie, key;
    var n, t;
    
    if ((trie[1]) && ((key == ((trie[1])[1])) || (((trie.length()) == 2) && match_begin((trie[1])[1], key))))
        return trie[1];
    if (!key)
        throw(~ambig, "Trie: ambiguous match.");
    if (!(n = (key[1]) in (trie[2])))
        throw(~keynf, "Trie: key not found.");
    (> (t = .match_begin(trie[n + 2], key.subrange(2))) <);
    t = t.replace(1, (key[1]) + (t[1]));
    return t;
    
    // $#Edited: 21 Apr 96 14:20 Jenner ($jenner)
};

public method .add() {
    arg @args;
    
    return (<$trie, ._add(@args)>);
    
    // $#Edited: 18 Apr 96 23:59 Jenner ($jenner)
};

public method .del() {
    arg @args;
    
    return (<$trie, ._del(@args)>);
    
    // $#Edited: 21 Apr 96 13:47 Jenner ($jenner)
};

public method ._add() {
    arg trie, key, @values;
    var n, word;
    
    // This still ain't working. Current problem: values get mingled
    if (trie[1]) {
        if (key == ((trie[1])[1]))
            return trie.replace(1, [key, @values]);
        word = (trie[1])[1];
        if (word) {
            if (!(n = (word[1]) in (trie[2])))
                trie = [@trie.replace(2, (trie[2]) + (word[1])), ._add([0, ""], word.subrange(2), @(trie[1]).subrange(2))];
            else
                trie = trie.replace(n + 2, ._add(trie[n + 2], word.subrange(2), @(trie[1]).subrange(2), @values));
            trie = trie.replace(1, 0);
        }
    }
    if (((!(trie[1])) && ((trie.length()) == 2)) || (!key))
        return trie.replace(1, [key, @values]);
    if (!(n = (key[1]) in (trie[2])))
        return [@trie.replace(2, (trie[2]) + (key[1])), ._add([0, ""], key.subrange(2), @values)];
    return trie.replace(n + 2, ._add(trie[n + 2], key.subrange(2), @values));
    
    // $#Edited: 20 Apr 96 21:55 Jenner ($jenner)
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method ._del() {
    arg trie, key;
    var n, t1;
    
    if ((trie[1]) && (key == ((trie[1])[1]))) {
        trie = trie.replace(1, 0);
        if (((trie.length()) == 3) && (!((trie[3])[2])))
            trie = [((trie[3])[1]).replace(1, (trie[2]) + (((trie[3])[1])[1])), ""];
        return trie;
    }
    if (!key)
        throw(~ambig, "Trie: Can't delete more than one key.");
    if (!(n = (key[1]) in (trie[2])))
        throw(~keynf, "Trie: No such key.");
    t1 = (> ._del(trie[n + 2], key.subrange(2)) <);
    if (t1 == [0, ""])
        trie = (trie.delete(n + 2)).replace(2, ((trie[2]).subrange(1, n - 1)) + ((trie[2]).subrange(n + 1)));
    else
        trie = trie.replace(n + 2, t1);
    if (((trie.length()) == 3) && ((!(trie[1])) && (!((trie[3])[2]))))
        trie = [((trie[3])[1]).replace(1, (trie[2]) + (((trie[3])[1])[1])), ""];
    return trie;
    
    // $#Edited: 21 Apr 96 14:07 Jenner ($jenner)
};

public method .match_exact() {
    arg trie, key;
    var n, t;
    
    if ((trie[1]) && (key == ((trie[1])[1])))
        return trie[1];
    if ((!key) || (!(n = (key[1]) in (trie[2]))))
        throw(~keynf, "Trie: key not found.");
    (> (t = .match_exact(trie[n + 2], key.subrange(2))) <);
    t = t.replace(1, (key[1]) + (t[1]));
    return t;
    
    // $#Edited: 21 Apr 96 14:29 Jenner ($jenner)
};

public method .keys() {
    arg trie, @prefix;
    var n, i, l;
    
    [(prefix ?= "")] = prefix;
    l = (trie[1]) ? [prefix + ((trie[1])[1])] : [];
    if (trie[2]) {
        for i in [1 .. (trie[2]).length()]
            l += .keys(trie[2 + i], prefix + ((trie[2])[i]));
        refresh();
    }
    return l;
    
    // $#Edited: 21 Apr 96 14:37 Jenner ($jenner)
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .to_dict() {
    arg trie, @prefix;
    var n, i, dict;
    
    // This function will only convert single-valued tries (such as were probably obtained from dictionaries
    [(prefix ?= "")] = prefix;
    dict = (trie[1]) ? #[[prefix + ((trie[1])[1]), (trie[1])[2]]] : #[];
    if (trie[2]) {
        for i in [1 .. (trie[2]).length()]
            dict = dict.union(.to_dict(trie[2 + i], prefix + ((trie[2])[i])));
        refresh();
    }
    return dict;
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .new() {
    arg @ignore;
    
    return (<this(), [0, ""]>);
    
    // $#Edited: 06 Nov 96 16:52 $brandon
};


new object $ctext_frob: $frob;

var $root manager = $ctext_frob;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837584074;
var $root inited = 1;
var $root managed = [$ctext_frob];
var $root owned = [$ctext_frob];

public method .new_with() {
    arg data, @vars;
    
    [(vars ?= #[])] = vars;
    return (<this(), [data, vars]>);
    
    // $#Edited: 16 Jul 96 08:12 $kahuna
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:14 $jenner
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .eval_ctext() {
    arg this;
    var data, vars;
    
    vars = this[2];
    vars = vars.add('time, 'pre);
    if (!(| vars['sender] |))
        vars = vars.add('sender, sender());
    if (!(| vars['evaluator] |))
        vars = vars.add('evaluator, $bs_eval);
    vars = vars.union((vars['evaluator]).init());
    return .new_with(@(vars['evaluator])._eval_ctext(this[1], vars));
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .format() {
    arg this;
    var vars;
    
    vars = this[2];
    vars = vars.add('time, 'post);
    if (!(| vars['receiver] |))
        vars = vars.add('receiver, sender());
    if (!(| vars['formatter] |))
        vars = vars.add('formatter, $text_format);
    vars = vars.union((vars['formatter]).init());
    return (vars['formatter]).format(this[1], vars);
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .set_var() {
    arg this, name, value;
    var vars;
    
    vars = this[2];
    vars = vars.add(name, value);
    return (<this(), [this[1], vars]>);
    
    // $#Edited: 16 Jul 96 08:12 $kahuna
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:14 $jenner
};

public method .get_var() {
    arg this, name;
    
    return (this[2])[name];
    
    // $#Edited: 16 Jul 96 08:12 $kahuna
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:14 $jenner
};

public method .vars() {
    arg this;
    
    return this[2];
    
    // $#Edited: 16 Jul 96 08:12 $kahuna
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:14 $jenner
};

public method ._ctext() {
    arg this;
    
    return this[1];
    
    // $#Edited: 16 Jul 96 08:12 $kahuna
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:14 $jenner
};

public method .set_vars() {
    arg this, new;
    var vars, key;
    
    vars = this[2];
    for key in (new.keys())
        vars = vars.add(key, new[key]);
    return (<this(), [this[1], vars]>);
    
    // $# Edited 26 Oct 1995 00:35 Lynx ($lynx)
    // $#Edited: 16 Jul 96 08:12 $kahuna
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:14 $jenner
};

public method .uncompile() {
    arg this;
    var vars;
    
    vars = this[2];
    if (!(| vars['uncompiler] |))
        vars = vars.add('uncompiler, $uncompiler);
    vars = vars.union((vars['uncompiler]).init());
    return ((vars['uncompiler])._eval_ctext(this[1], vars))[1];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .append() {
    arg this, new, @br;
    var data, tmp;
    
    data = this[1];
    if (br) {
        switch (br[1]) {
            case "p":
                data += [(<$format, ["p", [], [], 'do_p]>)];
            case "br":
                data += [(<$format, ["br", [], [], 'do_br]>)];
            default:
                data += [$format.new_tag(br[1], [], [])];
        }
    }
    if (type(new) == 'list)
        data += new;
    else if ((type(new) == 'frob) && (class(new) == $ctext_frob))
        data += new._ctext();
    else
        data += [new];
    return (<this(), [data, this[2]]>);
    
    // $#Edited: 30 Nov 96 21:22 $miro
};


new object $tag: $frob;

var $root manager = $tag;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837584128;
var $root child_index = 2;
var $root inited = 1;
var $root managed = [$tag];
var $root owned = [$tag];

public method .new_tag() {
    arg name, flags, args, method;
    var item, eflags;
    
    eflags = [];
    for item in (flags) {
        switch (type(item)) {
            case 'string:
                eflags = eflags.addkey(item, 1);
            case 'list:
                if (type(item[1]) != 'string)
                    throw(~flagerr, "Flag name must be a string.");
                eflags = eflags.addkey(item[1], item[2]);
            default:
                throw(~flagerr, "Flag must be a string or key,value pair.");
        }
    }
    return (<this(), [name, eflags, args, method]>);
};

public method .name() {
    arg self;
    
    return self[1];
    
    // $#Edited: 13 Jul 96 17:12 Miro ($kahuna)
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:15 $jenner
};

public method .add_ctext_flag() {
    arg self, key, value;
    var efalgs, uflags;
    
    eflags = (self[2]).addkey(key, value);
    self = self.replace(2, eflags);
    return (<this(), self>);
    
    // $#Edited: 13 Jul 96 17:12 Miro ($kahuna)
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:15 $jenner
};

public method .args() {
    arg self;
    
    return self[3];
    
    // $#Edited: 13 Jul 96 17:12 Miro ($kahuna)
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:15 $jenner
};

public method .set_args() {
    arg self, args;
    
    return (<this(), self.replace(3, args)>);
    
    // $#Edited: 13 Jul 96 17:12 Miro ($kahuna)
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:15 $jenner
};

public method .append_arg() {
    arg self, new;
    var args;
    
    args = (self[3]) + [new];
    return (<this(), self.replace(3, args)>);
    
    // $#Edited: 13 Jul 96 17:12 Miro ($kahuna)
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:15 $jenner
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .method() {
    arg self;
    
    return self[4];
    
    // $#Edited: 13 Jul 96 17:12 Miro ($kahuna)
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:15 $jenner
};

public method .ctext_flags() {
    arg self;
    
    return self[2];
    
    // $#Edited: 13 Jul 96 17:12 Miro ($kahuna)
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:15 $jenner
};

public method .eval_flags() {
    arg this, vars;
    var flags, i, l, val, s;
    
    flags = this[2];
    l = [];
    s = sender();
    for i in (flags) {
        if (type(i[2]) == 'frob) {
            [val, vars] = s._eval_ctext(i[2], vars);
            l += [[i[1], val]];
        } else {
            l += [i];
        }
    }
    return [this[1], l, this[3], this[4]];
    
    // $#Edited: 29 Nov 96 16:22 $miro
    // $#Edited: 30 Nov 96 21:22 $miro
};


new object $format: $tag;

var $root manager = $format;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837584154;
var $root inited = 1;
var $root managed = [$format];
var $root owned = [$format];

public method .new_tag() {
    arg name, flags, args;
    
    return pass(name, flags, args, tosym("do_" + (name.strip())));
};


new object $generator: $tag;

var $root manager = $generator;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837584238;
var $root inited = 1;
var $root managed = [$generator];
var $root owned = [$generator];

public method .new_tag() {
    arg name, flags, args;
    
    return pass(name, flags, args, tosym("gen_" + (name.strip())));
};


new object $climate_frob: $frob;

var $root manager = $climate_frob;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837904716;
var $root inited = 1;
var $root managed = [$climate_frob];
var $root owned = [$climate_frob];

public method .new_with() {
    arg attributes, seasons;
    
    return (<this(), [attributes, seasons, #[]]>);
    
    // $#Edited: 20 Jul 96 18:47 $jenner
};

public method .add_weather() {
    arg self, name, attrs, probs, message, ch_messages;
    
    return (<this(), [self[1], self[2], (self[3]).add(name, [attrs, probs, message, ch_messages])]>);
    
    // $#Edited: 20 Jul 96 18:47 $jenner
};

public method .show() {
    arg self;
    var out, seasons, attrs, weathers, x, i;
    
    attrs = self[1];
    seasons = self[2];
    weathers = self[3];
    out = [("Attributes: " + (attrs.to_english())) + ".", ("Seasons: " + (seasons.to_english())) + "."];
    for x in (weathers) {
        out += [((((" * " + (x[1])) + "> (probs) ") + (map i in [1 .. seasons.length()] to ((tostr(seasons[i]) + ":") + (((x[2])[2])[i])).join(", "))) + " (attrs) ") + (map i in [1 .. attrs.length()] to ((tostr(attrs[i]) + ":") + (((x[2])[1])[i])).join(", "))];
        out += ["   Description = " + ((((x[2])[3]).uncompile()).join())];
        if ((x[2])[4]) {
            out += ["   Change messages:"];
            for i in ((x[2])[4])
                out += ["      " + ((i.uncompile()).join())];
        }
    }
    return out;
    
    // $#Edited: 20 Jul 96 18:47 $jenner
};

public method .read_new() {
    arg user;
    var attrs, seasons, i;
    
    attrs = user.prompt("Weather attribute names (default:visibility severity):");
    if (attrs == "@abort")
        throw(~abort, "User aborted.");
    if (type(attrs) == 'symbol)
        throw(~engaged, "Already reading.");
    attrs = attrs || "visibility severity";
    attrs = (attrs.explode()).mmap('to_symbol);
    seasons = user.prompt("Season list (default:winter spring summer fall):");
    if (seasons == "@abort")
        throw(~abort, "User @aborted.");
    if (type(seasons) == 'symbol)
        throw(~engaged, "Already reading.");
    seasons = seasons || "winter spring summer fall";
    seasons = (seasons.explode()).mmap('to_symbol);
    return .new_with(attrs, seasons);
};

public method .del_weather() {
    arg self, weather;
    
    return (<this(), [self[1], self[2], (self[3]).del(weather)]>);
    
    // $#Edited: 20 Jul 96 18:47 $jenner
};

public method .read_weather() {
    arg self, user, weather;
    var attrs, probs, message, ch_messages, i;
    
    attrs = user.prompt("Attributes:");
    if ((type(attrs) == 'symbol) || (attrs == "@abort"))
        throw(~stop, "");
    if (((self[1]).length()) != ((attrs = attrs.explode_quoted()).length()))
        throw(~parse, "Wrong number of attributes");
    attrs = map i in (attrs) to ((tostr(toint(i)) == i) ? toint(i) : i);
    probs = user.prompt("Seasonal probabilities [0-99]:");
    if ((type(probs) == 'symbol) || (probs == "@abort"))
        throw(~stop, "");
    if (((self[2]).length()) != ((probs = probs.explode()).length()))
        throw(~parse, "Wrong number of attributes");
    probs = map i in (probs) to (toint(i));
    message = user.prompt("Weather description:");
    if ((type(message) == 'symbol) || (message == "@abort"))
        throw(~stop, "");
    (> (message = $compiler.compile_cml(message)) <);
    ch_messages = user.read("Enter messages to be displayed during the change ('.' to finish)");
    if (type(ch_messages) == 'symbol)
        throw(~stop, "");
    (> (ch_messages = map i in (ch_messages) to ($compiler.compile_cml(i))) <);
    return .add_weather(self, weather, attrs, probs, message, ch_messages);
};

public method ._distances() {
    arg self, from, season;
    var i, j, attr, w, refattr;
    
    w = self[3];
    refattr = (w[from])[1];
    return map i in (w.keys()) to ([i, ((map j in [1 .. (attr = (w[i])[1]).length()] to (abs((attr[j]) - (refattr[j]))).sum()) * 100) / (((w[i])[2])[season])]);
    
    // $#Edited: 30 Jul 96 21:57 $jenner
};

public method .advance() {
    arg self, current, season, fuzz;
    var dists, i, w, s;
    
    w = self[3];
    dists = ._distances(self, current, season);
    dists = dists.sort(dists.slice(2));
    i = 1;
    while ((i < (dists.length())) && (random(20 + ((dists[i])[2])) < fuzz))
        i++;
    return (dists[i])[1];
    
    // $#Edited: 30 Jul 96 22:15 $jenner
};


new object $rect: $frob;

var $root manager = $rect;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 843360251;
var $root inited = 1;
var $root managed = [$rect];

public method .union() {
    arg r1, r2;
    
    return [$math.minor(r1[1], r2[1]), $math.major(r1[2], r2[2])];
    
    // $#Edited: 26 Oct 96 14:30 $miro
};

public method .intersection() {
    arg r1, r2;
    
    // Doesn't check for validity
    return [$math.major(r1[1], r2[1]), $math.minor(r1[2], r2[2])];
    
    // $#Edited: 26 Oct 96 14:30 $miro
};

public method .rect_size() {
    arg r1;
    var i, s;
    
    s = 0.0;
    for i in ($math.sub(@r1))
        s += i;
    return -s;
};

public method .nondegenerate() {
    arg r1;
    
    return $math.is_lower(@r1);
    
    // $#Edited: 26 Oct 96 14:30 $miro
};

public method .inside() {
    arg point, box;
    
    return ($math.is_lower(point, box[2])) && ($math.is_lower(box[1], point));
    
    // $#Edited: 26 Oct 96 17:57 $miro
};


new object $rtree: $frob;

var $root manager = $rtree;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 843361817;
var $rtree max_length = 4;
var $root inited = 1;
var $root managed = [$rtree];

public method ._insert_where() {
    arg rlist, new;
    var i, u, min, t;
    
    u = 0;
    min = 1e+27;
    for i in [1 .. rlist.length()] {
        if ((t = $rect.rect_size($rect.union(rlist[i], new))) < min) {
            min = t;
            u = i;
        }
    }
    return u;
    
    // $#Edited: 01 Nov 96 15:48 $miro
};

public method ._insert() {
    arg tree, box, obj;
    var u, ret, xret, boxes, trees;
    
    trees = tree[2];
    boxes = tree[1];
    if (((trees[1]).length()) == 1) {
        // add leaf node to boxes and trees
        if ((trees.length()) < max_length) {
            return [[boxes + [box], trees + [obj]]];
        } else {
            // return two nodes:
            return ._split(boxes + [box], trees + [obj]);
        }
    } else {
        u = ._insert_where(boxes, box);
        ret = ._insert(trees[u], box, obj);
        if ((ret.length()) == 1)
            return [[boxes.replace(u, $rect.union(box, boxes[u])), trees.replace(u, ret[1])]];
        else if ((trees.length()) < max_length)
            return [[(boxes.delete(u)) + (ret.slice(3)), (trees.delete(u)) + [[(ret[1])[1], (ret[1])[2]], [(ret[2])[1], (ret[2])[2]]]]];
        else
            return ._split((boxes.delete(u)) + (ret.slice(3)), (trees.delete(u)) + [[(ret[1])[1], (ret[1])[2]], [(ret[2])[1], (ret[2])[2]]]);
    }
    
    // $#Edited: 01 Nov 96 15:48 $miro
};

public method ._split() {
    arg rlist, nlist;
    var i, j, m1, m2, r1, r2, l1, l2, n1, n2, len, min, seed1, seed2, min1, box;
    
    // First find the two rects that unioned create the greatest size...
    len = rlist.length();
    min = 1e+27;
    for i in [1 .. len - 1] {
        for j in [i + 1 .. len] {
            if (min > (min1 = $rect.rect_size($rect.union(rlist[i], rlist[j])))) {
                min = min1;
                seed1 = i;
                seed2 = j;
            }
        }
    }
    l1 = [(r1 = rlist[seed1])];
    l2 = [(r2 = rlist[seed2])];
    n1 = [nlist[seed1]];
    n2 = [nlist[seed2]];
    rlist = rlist.delete(seed2);
    rlist = rlist.delete(seed1);
    nlist = nlist.delete(seed2);
    nlist = nlist.delete(seed1);
    
    // Now add to the list that shows lower increase in size
    // l1,l2 are rectangle lists, n1,n2 are node lists, and r1, r2 are
    // current bounding rectangles
    for i in [1 .. rlist.length()] {
        box = rlist[i];
        m1 = $rect.union(r1, box);
        m2 = $rect.union(r2, box);
        if (($rect.rect_size(m1)) < ($rect.rect_size(m2))) {
            r1 = m1;
            l1 += [box];
            n1 += [nlist[i]];
        } else {
            r2 = m2;
            l2 += [box];
            n2 += [nlist[i]];
        }
    }
    return [[l1, n1, r1], [l2, n2, r2]];
    
    // $#Edited: 01 Nov 96 15:48 $miro
};

public method .insert() {
    arg self, box, obj;
    var ret;
    
    if (!(self[1]))
        return (<$rtree, [[box], [obj]]>);
    ret = ._insert(self, box, obj);
    if ((ret.length()) == 1)
        return (<$rtree, ret[1]>);
    else
        return (<$rtree, [ret.slice(3), [[(ret[1])[1], (ret[1])[2]], [(ret[2])[1], (ret[2])[2]]]]>);
    
    // $#Edited: 01 Nov 96 15:48 $miro
};

public method .empty() {
    return (<$rtree, [[], []]>);
    
    // $#Edited: 01 Nov 96 15:48 $miro
};

public method .search() {
    arg self, point;
    var boxes, trees, i, l;
    
    if ((self.length()) == 1)
        return self;
    boxes = self[1];
    trees = self[2];
    l = [];
    for i in [1 .. boxes.length()] {
        if ($rect.inside(point, boxes[i]))
            l += .search(trees[i], point);
    }
    return l;
    
    // $#Edited: 01 Nov 96 15:48 $miro
};

public method ._delete() {
    arg self, key, point;
    var i, trees, boxes, ret, l, b, mod, box;
    
    if ((self.length()) == 1) {
        if (self == key)
            return [0, 1, 0];
        else
            return [self, 0, 0];
    }
    trees = self[2];
    boxes = self[1];
    l = [];
    b = [];
    mod = 0;
    for i in [1 .. boxes.length()] {
        if ($rect.inside(point, boxes[i])) {
            ret = ._delete(trees[i], key, point);
            if ((ret[1]) == 0) {
                mod = 1;
                continue;
            }
            l += [ret[1]];
            mod = mod || (ret[2]);
            b += [(ret[3]) ? ret[3] : (boxes[i])];
        } else {
            l += [trees[i]];
            b += [boxes[i]];
        }
    }
    if (!l)
        return [0, 1];
    if (mod) {
        box = b[1];
        for i in (b.subrange(2))
            box = box.union(i);
        return [[b, l], 1, box];
    }
    return [self, 0, 0];
    
    // $#Edited: 01 Nov 96 15:48 $miro
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .delete() {
    arg self, point, box;
    var ret;
    
    ret = ._delete(self, point, box);
    return (ret[1]) ? (<this(), ret[1]>) : (.empty());
    
    // $#Edited: 01 Nov 96 15:48 $miro
};


new object $mail_list_news: $mail_list;

var $root fertile = 1;
var $root manager = $mail_list_news;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $has_name name = ['prop, "news", "news"];
var $mail_list mail = [];
var $mail_list senders = [];
var $mail_list readers = 1;
var $mail_list notify = [];
var $mail_list last_received_on = 0;
var $root managed = [$mail_list_news];
var $root owned = [$mail_list_news];


new object $mail_list_bugs: $mail_list;

var $root manager = $mail_list_bugs;
var $root created_on = 811630223;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "bugs", "bugs"];
var $mail_list mail = [];
var $mail_list senders = 1;
var $mail_list readers = 1;
var $mail_list notify = [];
var $mail_list last_received_on = 0;
var $root managed = [$mail_list_bugs];


new object $has_text: $foundation;

var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $has_text text = 0;
var $root manager = $has_text;
var $root child_index = 1;
var $root managed = [$has_text];
var $root owned = [$has_text];

root method .init_has_text() {
    text = [];
};

root method .uninit_has_text() {
    perm = [];
};

public method .text() {
    // returns text
    if ((!(.is_writable_by(sender()))) && (sender() != this()))
        throw(~perm, "Permission Denied.");
    return text;
};

public method .set_text() {
    arg txt;
    
    // resets ,text to the list sent
    if ((!(.is_writable_by(sender()))) && (sender() != this()))
        throw(~perm, "Permission Denied.");
    text = txt;
};

public method .ins_line() {
    arg txt, @loc;
    
    // inserts txt at loc (where loc is an integer)
    if ((!(.is_writable_by(sender()))) && (sender() != this()))
        throw(~perm, "Permission Denied.");
    if (!loc)
        text += [txt];
    else
        text = (> text.insert(loc, txt) <);
    
    // $#Edited: 22 Nov 96 17:42 $miro
};

public method .del_text() {
    // deletes all text
    if ((!(.is_writable_by(sender()))) && (sender() != this()))
        throw(~perm, "Permission Denied.");
    text = [];
};

public method .del_line() {
    arg linestr;
    
    // deletes "line" where line is the actual line to delete
    if ((!(.is_writable_by(sender()))) && (sender() != this()))
        throw(~perm, "Permission Denied.");
    text = text.setremove(line);
};

public method .del_nline() {
    arg nline;
    
    // deletes nline where nline is an integer reference to a list location
    if ((!(.is_writable_by(sender()))) && (sender() != this()))
        throw(~perm, "Permission Denied.");
    text = (> text.delete(nline) <);
};

public method .ins_lines() {
    arg lines, loc;
    var line;
    
    // inserts txt at loc (where loc is an integer)
    if ((!(.is_writable_by(sender()))) && (sender() != this()))
        throw(~perm, "Permission Denied.");
    if (type(lines) != 'list)
        throw(~type, "Lines should be passed as a list of strings.");
    for line in (lines) {
        text = (> text.insert(loc, line) <);
        ++loc;
    }
};

public method .edit_text() {
    var p;
    
    (> .perms(sender()) <);
    p = .text();
    (> sender().invoke_editor(this(), '_edit_text_callback, p, []) <);
    
    // $#Edited: 18 Aug 96 21:02 $jenner
};

public method ._edit_text_callback() {
    arg t, client_data;
    
    (> .perms(sender()) <);
    .set_text(t);
    return "Text set.";
    
    // $#Edited: 18 Aug 96 20:26 $jenner
};


new object $note: $thing, $has_text;

var $root child_index = 63;
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $has_text text = [];
var $located location = $void;
var $located obvious = 1;
var $described prose = [];
var $has_name name = ['uniq, "Generic Note", "the Generic Note"];
var $note seperator = 0;
var $foundation edit_types = ["text"];
var $has_commands remote = #[["erase", [["erase", "*", "erase <this>", 'erase_cmd, #[[1, ['this, []]]]], ["erase", "* on|from *", "erase <string> on|from <this>", 'erase_on_cmd, #[[1, ['any, []]], [3, ['this, []]]]]]], ["read|nread", [["read|nread", "*", "read|nread <this>", 'read_cmd, #[[1, ['this, []]]]]]], ["write", [["write", "on *", "write on <this>", 'write_cmd, #[[2, ['this, []]]]], ["write", "at * on *", "write at <string> on <this>", 'write_at_cmd, #[[2, ['any, []]], [4, ['this, []]]]]]], ["copy", [["copy", "from * to *", "copy from <this> to <any>", 'copy_cmd, #[[2, ['this, []]], [4, ['any, []]]]]]]];
var $root manager = $note;
var $root owned = [$note];
var $root defined_settings = #[["private", #[['parse, ['is_boolean]], ['format, ['format_boolean]]]]];
var $thing gender = $gender_neuter;
var $root settings = #[["private", 1]];
var $root managed = [$note];

protected method .add_text() {
    arg ntext, who, @args;
    
    // if at they should be an int defining where to insert.
    if (ntext) {
        if (ntext == 'aborted)
            return;
        if (args) {
            if (!(| .ins_lines(ntext, args[1]) |))
                who.tell(("There are not that many lines in " + (.name())) + ".");
        } else {
            .set_text((.text()) + ntext);
        }
        who.tell(((("Line" + (((ntext.length()) == 1) ? "" : "s")) + " added to ") + (.name())) + ".");
    } else {
        who.tell("Text not added.");
    }
    
    // $#Edited: 07 Nov 96 11:01 $brandon
};

public method .seperator() {
    return (type(seperator) == 'string) ? seperator : "---";
    
    // $#Edited: 07 Nov 96 11:01 $brandon
};

root method .init_note() {
    .del_flag('variables);
};

public method .init_for_core() {
    .perms(caller(), $sys);
    
    // $#Edited: 07 Nov 96 11:01 $brandon
};

public method .set_seperator() {
    arg newsep;
    
    .perms(sender(), 'manager);
    seperator = newsep;
    
    // $#Edited: 07 Nov 96 11:01 $brandon
};

public method .read_cmd() {
    arg cmdstr, cmd, @args;
    var who, text, prose;
    
    who = sender();
    if ((.get_setting("private", $note)) && (!(.trusts(who))))
        return who.tell(("You cannot read " + (.name())) + ".");
    who.tell(.name());
    who.tell(.prose());
    who.tell(.seperator());
    text = .text();
    if ((cmd == "nread") && text)
        text = $list.numbered_text(text);
    who.tell(text ? text : ["", "(nothing)", ""]);
    who.tell(.seperator());
    who.tell(("You finish reading " + (.name())) + ".");
};

public method .write_cmd() {
    arg cmdstr, cmd, @args;
    var who, line;
    
    if (!(.is_writable_by(sender())))
        return ("You do not have permission to write on " + (.name())) + ".";
    who = sender();
    
    // because I'm odd lets do this all 1 one command.
    if ((args.length()) == 2) {
        line = "Now writing on " + (.name());
        line += ", enter \".\" to finish and \"@abort\" to abort.";
    
        //      who.tell(line);
        .add_text(who.read(line), who);
    } else {
        args = (args[1]).explode();
        who.debug(args);
    }
};

public method .erase_on_cmd() {
    arg cmdstr, cmd, str, prep, this;
    var line, nline, who, len, oldline;
    
    (> .perms(sender()) <);
    who = sender();
    if (!str)
        return who.tell("You must erase either a line, line number, or all");
    catch any {
        if ($string.match_begin("all", str)) {
            .del_text();
    
            // if cmd is null, this method was called by an editor
            if (cmd)
                who.tell(("All text cleared from " + (.name())) + ".");
        } else {
            if (((str.explode()).length()) > 1)
                nline = toint((str.explode())[2]);
            else
                nline = toint(str);
            oldline = (.text())[nline];
            .del_nline(nline);
            line = ("Line " + tostr(nline)) + " (\"";
            len = (who.linelen()) - (25 + ((.name()).length()));
            line += $string.chop(oldline, len);
            line = (line + "\") erased from ") + (.name());
            who.tell(line);
        }
    } with {
        switch (error()) {
            case ~range:
                who.tell("There are not that many lines in the text.");
            default:
                who.tell("Oops: " + ((traceback()[1])[2]));
        }
    }
    
    // $#Edited: 07 Nov 96 11:01 $brandon
};

public method .erase_cmd() {
    arg cmdstr, cmd, this;
    var line, nline, len;
    
    (> .perms(sender()) <);
    .del_text();
    
    // if cmd is null, this method was called by an editor originally.
    if (cmd)
        sender().tell(("All text cleared from " + (.name())) + ".");
    
    // $#Edited: 07 Nov 96 11:01 $brandon
};

public method .write_str_cmd() {
    arg cmdstr, cmd, str, prep, this;
    
    (> .perms(sender()) <);
    if (!str)
        return ("Nothing to write on " + (.name())) + "!";
    .add_text([str], sender());
    
    // $#Edited: 07 Nov 96 11:01 $brandon
};

public method .write_at_cmd() {
    arg cmdstr, cmd, at, str, prep, this;
    var who, line, lines, syn;
    
    (> .perms(sender()) <);
    who = sender();
    syn = ((("`" + cmd) + " at [line] <line number> on ") + this) + "`";
    str = str.explode();
    if ((str[1]) == "line")
        str = str.delete(1);
    line = $string.is_numeric(str[1]);
    if (!at)
        $parse_lib.tell_error(("Unknown line \"" + (str[1])) + "\".", syn, who);
    lines = (.text()).length();
    if (line > (lines + 1))
        $parse_lib.tell_error(("There are only " + tostr(lines)) + " lines!", syn, who);
    .add_text(who.read(), who, line);
    
    // $#Edited: 07 Nov 96 11:01 $brandon
};

public method .copy_cmd() {
    arg cmdstr, cmd, from, this, prep, dest;
    var obj, what;
    
    // this method is outdated, needs to be rewritten.
    // it probably doesn't even work.
    if (!(.trusts(who)))
        return sender().tell(("You cannot read the text on " + (.namef('ref))) + ".");
    dest = $parse_lib.ref(dest);
    obj = dest[3];
    if (!(obj.is_writable_by(sender())))
        return .tell(("!  " + (obj.namef('ref))) + " is not writable by you.");
    if ((obj.has_ancestor($note)) && (!(dest[4])))
        obj.add_text(text, sender());
    if ((dest[1]) == 'method) {
        catch any {
            dest = (> tosym(dest[4]) <);
            if (what) {
                obj.(dest)(text, sender());
                sender().tell(((("Text copied to " + obj) + ".") + dest) + "().");
            } else {
                if (!((| tosym(dest) |) in (obj.variables())))
                    return .tell(("!  variable '" + dest) + " not found");
                obj.eval([(dest + " = ") + (.text())]);
            }
        } with {
            sender().tell_error((traceback()[1])[2]);
        }
    }
    sender().tell("Text copied from " + (.name()));
    
    // $#Edited: 07 Nov 96 11:01 $brandon
};

public method .description() {
    arg flags;
    
    if (dict_contains(flags, 'nonote))
        return (> pass(flags) <);
    return (> pass(flags) <) + ["You see some writing on the note, and may be able to read it..."];
};


new object $log: $note;

var $root child_index = 4;
var $root fertile = 1;
var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core];
var $described prose = ["the place that Ye administrators should be logging somewhat impacting changes that others would like to know about."];
var $located location = $void;
var $located obvious = 1;
var $has_name name = ['uniq, "Generic Log", "the Generic Log"];
var $has_text text = ["9-28-94/22:33:17> foo"];
var $has_commands remote = #[["read", [["read", "* on *", "read <any> on <this>", 'read_cmd, #[[1, ['any, []]], [3, ['this, []]]]]]]];
var $root manager = $log;
var $root managed = [$log];
var $root owned = [$log];
var $thing gender = $gender_neuter;

public method .read_cmd() {
    arg @args;
    var loglen, text;
    
    if (0) {
        // later on i'll adjust this so you can 'read from line 12 on log'
        return;
    } else {
        text = .text();
        loglen = text.length();
        sender().tell(["---", (((((.name()) + ", entries ") + tostr(loglen - 10)) + " to ") + tostr(loglen)) + " (last 10 lines).", "---"]);
        sender().tell(text.subrange(loglen - 10));
        sender().tell("---");
    }
    
    // $# Edited 05 Nov 1995 14:03 Lynx ($lynx)
};

public method .log() {
    arg line;
    var l;
    
    (> .perms(caller(), 'trusts) <);
    if (type(line) == 'list) {
        for l in (line)
            .ins_line((($time.format("%d %h %y %H:%M")) + "> ") + l);
    } else {
        .ins_line((($time.format("%d %h %y %H:%M")) + "> ") + line);
    }
};

root method .uninit_log() {
    .set_text([]);
};


new object $http_log: $log;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core];
var $has_text text = [];
var $has_name name = ['prop, "HTTP Log", "HTTP Log"];
var $described prose = [];
var $located location = $void;
var $located obvious = 1;
var $http_log tally = 3896;
var $root manager = $http_log;
var $root managed = [$http_log];
var $root owned = [$http_log];
var $thing gender = $gender_neuter;

public method .log() {
    arg @args;
    
    ++tally;
};

public method .tally() {
    return tally;
};


new object $reaper_log: $log;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core];
var $has_text text = [];
var $has_name name = ['prop, "Reaper Logfile", "Reaper Logfile"];
var $described prose = [];
var $located location = $void;
var $located obvious = 1;
var $root manager = $reaper_log;
var $root managed = [$reaper_log];
var $root owned = [$reaper_log];
var $thing gender = $gender_neuter;


new object $login_log: $log;

var $root manager = $login_log;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core];
var $has_text text = [];
var $has_name name = ['uniq, "log_3", "the log_3"];
var $described prose = [];
var $located location = $void;
var $located obvious = 1;
var $root managed = [$login_log];
var $root owned = [$login_log];
var $thing gender = $gender_neuter;


new object $generic_map: $note;

var $root manager = $generic_map;
var $located obvious = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 840768594;
var $located location = $void;
var $has_text text = [];
var $root inited = 1;
var $described prose = <$ctext_frob, [["This is generic map object - it's generic holder for area maps."], #[['this, $generic_map]]]>;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['uniq, "Generic Map", "the Generic Map"];
var $root child_index = 1;
var $root managed = [$generic_map];
var $root owned = [$generic_map];
var $thing gender = $gender_neuter;

public method .view() {
    arg x, y, code, height, width;
    var text, i, out, pos, line;
    
    text = .text();
    pos = 0;
    out = [];
    for i in [y .. y + height] {
        line = (| ((text[i]).subrange(x + 1)).pad(width) |) || "";
        pos = pos || (code in line);
        out += [((line.left(width)).replace(code, "[]")).sed("[0-9]", " ", "g")];
    }
    return [@out, pos ? "Your position is '[]'." : "Your position is not shown on this map."];
    
    // $#Edited: 15 Feb 97 20:48 $miro
};


new object $map_of_taobh_thiar: $generic_map;

var $root manager = $map_of_taobh_thiar;
var $root flags = ['methods, 'code, 'core];
var $root created_on = 841020994;
var $has_text text = ["", "", "                                                       *", "                                          *            |", "                                          |          Ladder 09", "                                      Under The        /", "                Steam Tunnel 10       Fountain 05 Steam Tunnel 06", "                        \                   |     /     \\", "                  Steam Tunnel 03    Steam Tunnel 04 Steam Tunnel 07", "                          \            /                |", "                           Steam Tunnel 02       Secret Staicase 08", "                                /                       |", "                   Steam Tunnel 01                      *", "                        |", "                     The Pit", "                       00"];
var $has_name name = ['uniq, "Map of Taobh Thiar", "the Map of Taobh Thiar"];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $described prose = <$ctext_frob, [["This map shows the Taobh Thiar."], #[['this, $map_of_taobh_thiar]]]>;
var $located location = $lost_and_found;
var $located obvious = 1;
var $root inited = 1;
var $root managed = [$map_of_taobh_thiar];
var $root owned = [$map_of_taobh_thiar];
var $thing gender = $gender_neuter;


new object $mail_message: $has_text, $mail_root;

var $root child_index = 777;
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root owned = [#348, #129, #143, #144, #254, #161, #397, #398, #399, #354, #355, #349, #158, #119, #145, #311, #312, #562, #400, #313, #314, #315, #316, #147, #566, #317, #401, #184, #318, #159, #255, #203, #402, #188, #403, #365, #366, #350, #351, #375, #404, #405, $mail_message, #120, #215, #406, #407, #204, #408, #256, #216, #376, #319, #392, #377, #378, #379, #380, #217, #257, #258, #409, #410, #367, #356, #411, #412, #189, #413, #414, #415, #416, #417, #418, #419, #420, #421, #422, #259, #260, #261, #423, #359, #424, #425, #426, #190, #262, #427, #428, #429, #430, #431, #432, #218, #219, #320, #321, #433, #551, #322, #263, #434, #435, #436, #437, #438, #439, #440, #441, #442, #443, #381, #444, #445, #446, #447, #448, #449, #264, #450, #265, #323, #220, #266, #267, #268, #123, #451, #452, #382, #221, #222, #453, #269, #201, #552, #553, #454, #545, #270, #271, #272, #273, #274, #622, #223, #455, #324, #554, #224, #275, #276, #277, #456, #325, #383, #384];
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root quota_exempt = 1;
var $mail_message readers = [];
var $mail_message header = #[];
var $mail_message delivered = 0;
var $root manager = $mail_message;
var $root managed = [$mail_message];
var $mail_message creator = 0;

public method .del_recipient(): nooverride {
    arg whom;
    var rcpts;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    rcpts = (header['rcpt]).setremove(whom);
    if (!rcpts)
        .destroy();
    else
        header = header.add('rcpt, rcpts);
};

public method .add_recipient(): nooverride {
    arg whom;
    var current;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    current = (| header['rcpt] |) || [];
    if ((| whom in current |))
        throw(~type, "Recipient is already in the list of recipients");
    header = header.add('rcpt, current.union([whom]));
};

public method .letter(): nooverride {
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    return (.header()).add('text, .text());
};

public method .readers(): nooverride {
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    return readers;
};

public method .did_read(): nooverride {
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    if ($guest in (sender().parents()))
        return;
    readers = setadd(readers, sender());
};

public method .set_time(): nooverride {
    arg time;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    header = header.add('time, time);
};

public method .set_recipients(): nooverride {
    arg whom;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    header = header.add('rcpt, whom);
};

public method .set_subject(): nooverride {
    arg what;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    header = header.add('subj, what);
};

public method .set_from(): nooverride {
    arg whom;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    header = header.add('from, whom);
};

public method .add_reader(): nooverride {
    arg who;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    readers = readers.union([who]);
};

public method .recipients(): nooverride {
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    return (| header['rcpt] |) || [$no_one];
};

public method .from(): nooverride {
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    return (| header['from] |) || $no_one;
};

public method .subject(): nooverride {
    return (| header['subj] |) || "<none>";
};

public method .time(): nooverride {
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    return (| header['time] |) || 0;
};

public method .format(): nooverride {
    var output, o, h;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    h = .header();
    return (["From:    " + ($object_lib.get_name(h['from], 'namef, ['ref])), "To:      " + (((h['rcpt]).omap($mail_lib, 'mail_name)).to_english()), "When:    " + ($time.format("%I:%M %p %v", h['time])), "Subject: " + (h['subj]), "---"] + (.text())) + ["---"];
};

public method .header(): nooverride {
    var h, d;
    
    (> .perms(sender()) <);
    h = #[['from, $no_one], ['rcpt, [$no_one]], ['subj, "<none>"], ['time, 0]];
    for d in (header)
        h = h.add(@d);
    return h;
};

root method .uninit_mail_message() {
    var r;
    
    for r in (.recipients())
        (| r.del_mail(this(), (| (.from()) || this() |)) |);
    header = #[];
    readers = [];
};

root method .init_mail_message() {
    header = #[];
    readers = [];
    .set_flags([]);
};

public method .has_read(): nooverride {
    arg who;
    
    return who in readers;
};

public method .text() {
    return (> pass() <) || ["", "(no message)", ""];
};

public method .send() {
    arg @recips;
    var r, valid, invalid;
    
    if (!($mail_lib.has_mail_perms(caller())))
        (> .perms(sender()) <);
    if (delivered)
        throw(~delivered, "This mail has already been delivered.");
    if (!recips)
        recips = .recipients();
    if (((recips.length()) == 1) && ((recips[1]) == $no_one))
        throw(~norcpt, "No recipients specified.");
    valid = [];
    invalid = [];
    for r in (recips) {
        if (r.has_ancestor($mail_list))
            valid += [r];
        else
            invalid += [r];
    }
    if (invalid)
        throw(~invrcpt, "Invalid mail recipients: " + (invalid.mmap('name)), invalid);
    recips = valid;
    invalid = [];
    
    // ok, now that we have that cleared up, lets set pertinent info...
    .set_time(time());
    .set_from(sender());
    
    // and now to finalize the recipients
    for r in (recips) {
        if (r.list_is_sendable_by(sender())) {
            r.add_mail();
            .add_recipient(r);
        } else {
            invalid += [r];
        }
    }
    delivered = 1;
    return invalid;
    
    // $#Edited: 22 Nov 96 17:54 $miro
};

public method .new_mail(): nooverride {
    var new;
    
    // if (!$mail_lib.has_mail_perms(caller()))
    //     (> .perms(sender()) <);
    if (definer() != this())
        throw(~perm, "Only spawn mail from $mail_message.");
    new = .spawn();
    new.add_writer(sender());
    
    // since anybody can create mail, do some tracking..
    new.set_creator(user());
    return new;
};

public method .creator() {
    return creator;
    
    // $#Edited: 02 Nov 96 12:28 $brandon
};

public method .set_creator() {
    arg who;
    
    (> .perms(caller(), definer()) <);
    creator = who;
};


new object $itext: $has_text;

var $root child_index = 2;
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $has_text text = ["hello", "this", "world"];
var $itext all_text = #[["foo", [["hello", "world"], ""]], ["bar", [["hello", "this", "world"], ""]]];
var $itext current = "foo";
var $root manager = $itext;
var $root owned = [$itext];
var $root managed = [$itext];

public method .current() {
    return current;
};

public method .topics() {
    return all_text.keys();
};

public method .set_desc() {
    arg desc, @topic;
    
    // set the description for a topic
    // The description is a short text string meant for use in an index
    // if <topic> is not given assume current
    [(topic ?= current)] = topic;
    if (topic in (all_text.keys()))
        all_text = all_text.add(topic, (all_text[topic]).replace(2, short_desc));
    else
        throw(~topicnf, ("Topic " + topic) + " not found.");
    
    // $#Edited: 22 Nov 96 17:54 $miro
    // $#Edited: 30 Nov 96 20:00 $miro
};

public method .store() {
    arg @topic;
    
    [(topic ?= current)] = topic;
    if (!(topic in (all_text.keys())))
        all_text = all_text.add(topic, [.text(), ""]);
    all_text = all_text.add(topic, (all_text[topic]).replace(1, .text()));
    
    // $#Edited: 30 Nov 96 20:00 $miro
};

public method .set_current() {
    arg topic;
    
    current = topic;
    if (topic in (all_text.keys()))
        .set_text((all_text[topic])[1]);
    else
        .set_text([]);
};

public method .get_topic() {
    arg topic, @who;
    
    if (topic in (all_text.keys()))
        return (all_text[topic])[1];
    else
        throw(~topicnf, ("Topic " + topic) + " not found.");
};

root method .init_itext() {
    current = "";
    all_text = #[];
};

public method .get_desc() {
    arg topic, @who;
    
    if (topic in (all_text.keys()))
        return (all_text[topic])[2];
    else
        throw(~topicnf, ("Topic " + topic) + " not found.");
};


new object $db: $misc;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $db database = #[];
var $root manager = $db;
var $root child_index = 1;
var $root owned = [$db];
var $root managed = [$db];

root method .init_db() {
    database = #[];
    
    // $#Edited: 09 May 96 20:48 $jenner
};

public method .database() {
    return database;
    
    // $#Edited: 09 May 96 20:48 $jenner
};

public method .value_changed() {
    arg key, new_value;
    
    // change the value of a key.
    if ((!(sender() == this())) && (!(.trusts(caller()))))
        (> .perms(sender(), 'writer) <);
    (> .remove(key) <);
    (> .insert(key, new_value) <);
    
    // $#Edited: 09 May 96 20:48 $jenner
};

public method .remove() {
    arg key;
    
    // remove a key/value from the database
    if ((!(sender() == this())) && (!(.trusts(caller()))))
        (> .perms(sender(), 'writer) <);
    database = database.del(key);
    
    // $#Edited: 09 May 96 20:48 $jenner
};

public method .exact_match() {
    arg key;
    var match;
    
    // get an exact match of a key, return the value
    match = (| (type(database) == 'dictionary) ? database[key] : ((database.match_exact(key))[2]) |);
    if (match == ~keynf)
        throw(~matchnf, "No object by that key exists in the database.");
    return match;
    
    // $#Edited: 09 May 96 20:48 $jenner
};

public method .match_begin() {
    arg key;
    var matches, entry;
    
    // First check if we're using $trie frob
    if (type(database) == 'frob) {
        matches = (| (database.match_begin(key))[2] |);
        if (matches == ~keynf)
            throw(~matchnf, "No entries in the database match that key.");
        if (matches == ~ambig)
            throw(~ambig, "More than one object matches that key.");
        return matches;
    }
    
    // use match_begin of the key, return the value
    matches = [(| .exact_match(key) |)];
    if (!(matches[1])) {
        matches = [];
        for entry in (database) {
            if (match_begin(entry[1], key))
                matches = setadd(matches, entry[2]);
        }
    }
    if (matches) {
        if ((matches.length()) == 1)
            return matches[1];
        else
            throw(~ambig, "More than one object matches that key.", matches);
    } else {
        throw(~matchnf, "No entries in the database match that key.");
    }
};

public method .insert() {
    arg key, value;
    
    // insert a key/value to the database
    if ((!(sender() == this())) && (!(.trusts(caller()))))
        (> .perms(sender(), 'writer) <);
    database = database.add(key, value);
};

root method .uninit_db() {
    database = 0;
    
    // $#Edited: 09 May 96 20:48 $jenner
};

public method .key_changed() {
    arg old_key, new_key;
    var val;
    
    // change the value of a key.
    if ((!(sender() == this())) && (!(.trusts(caller()))))
        (> .perms(sender(), 'writer) <);
    val = (> .exact_match(old_key) <);
    .remove(old_key);
    .insert(new_key, val);
    
    // $#Edited: 09 May 96 20:48 $jenner
    // $#Edited: 20 Jul 96 16:37 $jenner
};

protected method .set_database() {
    arg newdb;
    
    // this should not be called often, its primarily for corification
    database = newdb;
};

protected method .clean_database() {
    var elem;
    
    // clean up a  "STR"=>$obj  style database
    for elem in (database) {
        if (!valid(elem[2]))
            database = database.del(elem[1]);
    }
};


new object $registry: $db;

var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $db database = #[];
var $registry stripped_characters = "";
var $registry min_char_len = 0;
var $registry max_char_len = 0;
var $registry max_word_len = 0;
var $registry reserved_names = [];
var $registry invalid_names = [];
var $root manager = $registry;
var $root managed = [$registry];
var $root owned = [$registry];
var $registry stripped = 0;
var $root child_index = 1;

public method .set_max_word_len() {
    arg value;
    
    (> .perms(sender(), 'manager) <);
    if (type(value) != 'integer)
        throw(~type, "Value is not an integer");
    max_word_len = value;
};

public method .set_max_char_len() {
    arg value;
    
    (> .perms(sender(), 'manager) <);
    if (type(value) != 'integer)
        throw(~type, "Value is not an integer");
    max_char_len = value;
};

public method .set_min_char_len() {
    arg value;
    
    (> .perms(sender(), 'manager) <);
    if (type(value) != 'integer)
        throw(~type, "Value is not an integer");
    min_char_len = value;
};

public method .insert() {
    arg name, obj;
    
    // registers obj with obj.name
    if ((!(.trusts(caller()))) && ((!sender()) == this()))
        throw(~perm, "Permission denied.");
    name = .strip_key(name);
    (> pass(name, obj) <);
};

public method .remove() {
    arg name;
    
    // removes the object from the database.
    // THIS: is what is broken with guests, should fix it.
    if ((!(.trusts(caller()))) && (sender() != this()))
        throw(~perm, "Permission denied.");
    name = .strip_key(name);
    (> pass(name) <);
};

public method .database() {
    if (!(.has_flag('variables, sender())))
        throw(~perm, "Database is not readable by sender.");
    return (> pass() <);
};

public method .exact_match() {
    arg name;
    
    // returns a direct match of the name (if there is one)
    if (!(.has_flag('variables, sender())))
        throw(~perm, "Database is not readable by sender.");
    name = .strip_key(name);
    return (> pass(name) <);
};

public method .valid_name() {
    arg name;
    var word, sname, matched_obj, m;
    
    // returns 1 if the name is valid
    /// if (!.has_flag('variables,sender()))
    //    throw(~perm, "Database is not readable by sender.");
    (> .perms(caller(), 'trusts) <);
    
    // check name itself first
    sname = .strip_key(name);
    if (max_word_len && (listlen(name.explode()) > max_word_len))
        throw(~invname, ("Names can only be " + max_word_len) + " words long.");
    if (min_char_len && (strlen(sname) < min_char_len))
        throw(~invname, ("Names must have at least " + min_char_len) + " alpha-numeric characters in them");
    if (max_char_len && ((name.length()) > max_char_len))
        throw(~invname, ("Names can only be " + max_char_len) + " characters long.");
    
    // see if it already exists
    if ((| (matched_obj = .exact_match(name)) |)) {
        if (matched_obj != sender())
            throw(~invname, ((("The name \"" + name) + "\" conflicts with the existing user \"") + (matched_obj.name())) + "\"");
    }
    
    // check reserved and invalid names
    if (reserved_names && (sname in reserved_names))
        throw(~invname, ("`" + name) + "' is a reserved name.");
    if (invalid_names && (m = regexp(sname, invalid_names)))
        throw(~invname, ("`" + (m[2])) + "' is not allowed as part of a name.");
};

public method .match_begin() {
    arg name;
    var matches, obj;
    
    // returns a direct match, or partial matches
    name = .strip_key(name);
    if (!name)
        throw(~matchnf, "No entries in the database match that key.");
    return (> pass(name) <);
};

public method .strip_key() {
    arg key;
    
    anticipate_assignment();
    if (stripped)
        return key.strip();
    return key;
};

public method .key_changed() {
    arg old_name, new_name;
    
    // adjusts the database for the new name
    if ((!(.trusts(caller()))) && (sender() != this()))
        throw(~perm, "Permission denied.");
    old_name = .strip_key(old_name);
    new_name = .strip_key(new_name);
    (> pass(old_name, new_name) <);
};

public method .search() {
    arg name;
    var tmp;
    
    name = .strip_key(name);
    name || throw(~namenf, "No matches found.");
    tmp = (| .exact_match(name) |);
    if (tmp)
        return tmp;
    catch any {
        tmp = (> .match_begin(name) <);
    } with {
        switch (error()) {
            case ~ambig:
                rethrow(error());
            default:
                throw(~namenf, "No matches found.");
        }
    }
    return tmp;
};


new object $mail_db: $registry, $mail_root;

var $root trusted = [$mail_list];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $db database = #[["news", $mail_list_news], ["bugs", $mail_list_bugs]];
var $root manager = $mail_db;
var $root managed = [$mail_db];
var $root owned = [$mail_db];

public method .valid_recipient() {
    arg recip;
    
    if (recip.has_ancestor($mail_list))
        return 1;
    return 0;
};

public method .mail_name() {
    arg obj;
    
    return "*" + (obj.name());
    
    // $# Edited 05 Nov 1995 14:04 Lynx ($lynx)
};

root method .core_mail_db() {
    .set_database(#[["news", $mail_list_news], ["bugs", $mail_list_bugs]]);
    
    // $#Edited: 17 Feb 97 02:58 $user_vang
};


new object $place_db: $registry;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $db database = #[["void", $void], ["nowhere", $nowhere], ["The Pit", $the_pit]];
var $registry stripped_characters = "!@#$%^&*()_+-=~`'{}[]|/?\",.<>;:";
var $root manager = $place_db;
var $root managed = [$place_db];
var $root owned = [$place_db];

public method .place_destroyed() {
    arg @args;
    
    // called in $place.uninit_place (incase the place is in the db)
};


new object $user_db: $registry;

var $root trusted = [$user];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'variables, 'code, 'core];
var $db database = <$trie, [0, "GRNps", [0, "e", [0, "n", [0, "e", [0, "r", [0, "i", [0, "c", [0, "GBPAU", [["uestObject", $guest], ""], [["uilder", $builder], ""], [["rogrammer", $programmer], ""], [["dmin", $admin], ""], [["serObject", $user], ""]]]]]]]], [["eaper", $reaper], ""], [["oOne", $no_one], ""], [["layer", $player], ""], [["toryteller", $storyteller], ""]]>;
var $user_db connected = [];
var $user_db invalid_chars = "$#@!^&%~";
var $registry stripped_characters = "!@#$%^&*()_+-=~`'{}[]|/?\",.<>;: ";
var $registry reserved_names = ["user", "builder", "programmer", "admin", "housekeeper", "Reaper", "noone", "guest", "a", "i", "an", "your", "you'r", "me", "god"];
var $registry invalid_names = "(^| )(ass|cunt|fuck|shit|damn)( |$)";
var $registry min_char_len = 3;
var $registry max_char_len = 20;
var $root manager = $user_db;
var $root managed = [$user_db];
var $root owned = [$user_db];
var $registry stripped = 1;

public method .users() {
    return (.database()).keys();
};

public method .connected() {
    var x;
    
    for x in (connected) {
        if ((!valid(x)) || (| !(x.connections()) |))
            connected = connected.setremove(x);
    }
    return connected;
};

public method .did_connect() {
    (> .perms(caller(), $user) <);
    connected = connected.setadd(sender());
};

public method .did_disconnect() {
    .perms(caller(), $user);
    connected = connected.setremove(sender());
};

public method .valid_name() {
    arg name;
    
    if (((name.strip(invalid_chars)).length()) < (name.length()))
        throw(~invname, ("Names cannot contain any of '" + invalid_chars) + "'.");
    return (> pass(name) <);
};

public method .match() {
    arg name;
    
    return (> .search(name) <);
};

public method .total_connected() {
    return (.connected()).length();
};

public method .clean_user_db() {
    var key, db, invalid;
    
    db = .database();
    invalid = [];
    for key in ((.database()).keys()) {
        if (!valid(db[key])) {
            .remove(key);
            connected = connected.setremove(key);
            invalid += [key];
        }
    }
    return ["Invalid $user_db entries: " + (invalid.to_english())];
};

root method .core_user_db(): nooverride {
    var o;
    
    .set_database($trie.new());
    for o in (($user.descendants()) + [$user])
        .insert(o.name(), o);
};


new object $help_node: $has_name;

var $root child_index = 9;
var $root fertile = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $has_name name = ['uniq, "help_node", "the help_node"];
var $help_node links = 0;
var $help_node body = 0;
var $root trusted_by = [$help_index_driver, $help_index_core, $help_index_cmds, $help_index_subsystem, $help_index_function, $help_index_objects, $help_updates, $help_sys_weather, $help_sys_weather_attributes, $help_sys_climate, $help_weather_system];
var $root manager = $help_node;
var $help_node group = 0;
var $root owned = [$help_node];
var $foundation edit_types = ["help"];
var $help_node nolist = 1;
var $help_node index = 0;
var $help_node holder = 0;
var $root defined_settings = #[["nolist", #[['get, ['nolist]], ['set, ['set_nolist]], ['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["group", #[['get, ['group]], ['set, ['set_group]], ['parse, ['is_boolean]], ['format, ['format_boolean]]]], ["index", #[['get, ['get_index_setting]], ['set, ['set_index_setting]], ['parse, ['parse_index_setting]], ['format, ['format_index]]]], ["holder", #[['get, ['get_holder_setting]], ['set, ['set_holder_setting]], ['parse, ['is_boolean]], ['format, ['format_boolean]]]]];
var $root managed = [$help_node];

root method .init_help_node() {
    links = #[];
    .set_body(["This node isn't written yet"]);
};

root method .uninit_help_node() {
    var obj;
    
    if (index) {
        catch any
            (> index.node_going_away() <);
        with
            $brandon.tell_traceback(traceback());
    }
    links = #[];
    title = "";
    body = [];
};

public method .index_going_away() {
    (> .perms(caller(), $help_index) <);
    (| clear_var('index) |);
};

public method .set_body() {
    arg new_body;
    var new_body, anchors, key, keys, values, value;
    
    (> .perms(sender()) <);
    
    // Compile a string into help ctext
    new_body = $compiler.compile_cml(new_body);
    body = new_body;
    anchors = (| new_body.get_var('links) |) || #[];
    body = (<$ctext_frob, [body._ctext(), (| (body.vars()).del('links) |) || (body.vars())]>);
    keys = anchors.keys();
    values = anchors.values();
    links = #[];
    for key in (keys)
        links = links.add(key, $object_lib.to_dbref(anchors[key]));
    if ((!(.has_ancestor($help_index))) && (!(this() == $help_updates)))
        $help_updates.touched();
    
    // $#Edited: 20 Nov 96 18:42 $miro
};

public method .body() {
    return body;
};

public method .links() {
    return links || #[];
};

public method .node_going_away() {
    var node;
    
    (> .perms(caller(), $help_node) <);
    node = sender();
    
    // do something intelligent with the text body as well
    links = links.del(node);
};

protected method .get_index_setting() {
    arg @args;
    
    return index || 0;
};

public method .traverse() {
    var n, out;
    
    // traverse the higherarchy with a depth-first priority rather than width
    out = [this()];
    for n in (children())
        out += n.traverse();
    return out;
    
    // $#Edited: 17 Mar 97 09:10 $brandon
};

protected method .set_index_setting() {
    arg name, definer, value, @args;
    
    ._set_index(value);
};

public method .node_name() {
    var name;
    
    if (this() == definer())
        return "";
    name = ((.parents())[1]).node_name();
    if (!name)
        return (.name()).word(1, "|");
    return (name + ": ") + ((.name()).word(1, "|"));
};

public method .html_node_name() {
    arg @this;
    var name, index, hname;
    
    if (this() == definer())
        return "";
    name = ((.parents())[1]).html_node_name();
    if (this)
        hname = (.name()).word(1, "|");
    else if (holder)
        hname = ("<i>" + ((.name()).word(1, "|"))) + "</i>";
    else
        hname = ((("<a href=\"/bin/help?node=" + this()) + "\">") + ((.name()).word(1, "|"))) + "</a>";
    if (!name)
        return hname;
    return (name + ": ") + hname;
};

public method .set_name() {
    arg new, @ignore;
    var old;
    
    if ("=" in new)
        throw(~perm, "You cannot have \"=\" in a help node name.");
    old = .name();
    (> pass(new, 'prop) <);
    if (index)
        index.node_changed_name(old);
};

public method .edit_help() {
    var p;
    
    (> .perms(sender()) <);
    p = (.body()).uncompile();
    (> sender().invoke_editor(this(), '_edit_help_callback, p, []) <);
    
    // $#Edited: 18 Aug 96 21:02 $jenner
};

public method ._edit_help_callback() {
    arg text, client_data;
    
    (> .perms(sender()) <);
    .set_body(text);
    return "Help node body set.";
};

public method .group() {
    arg @args;
    
    return !group;
};

public method .nolist() {
    arg @args;
    
    return nolist;
    
    // whether or not this node should be listed as a 'descendant' node of
    // its parent.
};

protected method .set_group() {
    arg name, definer, value, @args;
    
    // invert it, more db friendly this way since 99% of the nodes want groups
    value = !value;
    if (value)
        group = value;
    else
        (| clear_var('group) |);
};

protected method .set_nolist() {
    arg name, definer, value, @args;
    
    nolist = value;
};

public method .top_of_help_heirarchy() {
    return definer() == this();
    
    // $#Edited: 11 Nov 96 22:40 $brandon
};

public method .index() {
    return index;
    
    // $#Edited: 13 Nov 96 13:46 $brandon
};

public method .set_index() {
    arg index;
    
    (> .perms(sender()) <);
    return (> ._set_index(index) <);
};

protected method ._set_index() {
    arg i;
    
    if (index)
        (| index.del_help_node(this()) |);
    if (!i) {
        clear_var('index);
        return;
    }
    index = i;
    (> index.add_help_node(this()) <);
};

protected method .set_holder_setting() {
    arg name, definer, value, @args;
    
    if (value)
        holder = 1;
    else if (holder)
        clear_var('holder);
    
    // $#Edited: 19 Jan 97 15:57 $brandon
};

protected method .get_holder_setting() {
    arg @args;
    
    return holder;
};

public method .holder() {
    return holder;
    
    // $#Edited: 20 Jan 97 20:44 $brandon
};

public method .small_name() {
    return ((.name()).word(1, "|")).word(1);
    
    // $#Edited: 20 Jan 97 22:30 $brandon
};

protected method .parse_index_setting() {
    arg value, @args;
    var i;
    
    if (!value)
        return 0;
    if ((value[1]) == "$") {
        i = (> $object_lib.to_dbref(value) <);
        if (!(i.has_ancestor($help_index)))
            throw(~bad, ("\"" + (i.namef('ref))) + "\" is not a help index.");
    } else {
        value = strsed(value, " *index *", "");
        if (!(i = $help_index.match_children(value)))
            throw(~bad, ("\"" + value) + "\" is not a help index.");
    }
    return i;
};

public method .format_index() {
    arg value;
    
    if (!value)
        return "";
    return (((value.name()) + " INDEX (") + value) + ")";
};


new object $help_coldcore: $help_node;

var $root manager = $help_coldcore;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Cold Help System", "Cold Help System"];
var $help_node links = #[["Help", $help_help], ["General", $help_general], ["Building", $help_building], ["Programming", $help_prog], ["Reference", $help_reference], ["Updates", $help_updates]];
var $help_node body = <$ctext_frob, [[<$format, ["quote", [], ["\n        ___     _    _   _  _     _        ___         _\n       / __|___| |__| | | || |___| |_ __  / __|_  _ __| |_ ___ _ __\n      | (__/ _ \ / _` | | __ / -_) | '_ \ \__ \ || (_-<  _/ -_) '  \ \n       \___\___/_\__,_| |_||_\___|_| .__/ |___/\_, /__/\__\___|_|_|_|\n                                   |_|         |__/\n"], 'do_quote]>, <$format, ["p", [], [], 'do_p]>, "Welcome to ", <$generator, ["servname", [], [], 'gen_servname]>, ". This is a hypertext help system. If you are on an interactive login you can type ", <$format, ["tt", [], ["@help help"], 'do_tt]>, " for help on how to use this help system. Following is a list of Launch Points to the help system:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_help"]], ["Help"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["How to use this help system"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_general"]], ["General"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["General Information"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_building"]], ["Building"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Extending your Environment"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_prog"]], ["Programming"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Topics about programming"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_reference"]], ["Reference"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Core Reference Information"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_updates"]], ["Updates"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["ChangeLog for this system"], 'do_dd]>], 'do_dl]>], #[['this, $help_coldcore]]]>;
var $root managed = [$help_coldcore];
var $root owned = [$help_coldcore];
var $help_node group = 1;
var $help_node index = $help_index_core;
var $root child_index = 3;
var $help_node nolist = 0;


new object $help_help: $help_coldcore;

var $root manager = $help_help;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Help", "Help"];
var $help_node links = #[["Help", $help_help], ["Options", $help_help_options], ["Navigating", $help_help_navigating]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "This is a hypertextual help system. Hypertext is simply a dynamic form of text, where words within a document may have special meaning, and point to other documents or portions of the document. These words are called ", <$format, ["i", [], ["hyperlinks"], 'do_i]>, ". In a windowed browser hyperlinks may be displayed differently from the regular text by colorization. Over a terminal we specify hyperlinks by enclosing them in square brackets (", <$format, ["tt", [], ["[]"], 'do_tt]>, "), such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["link", [["node", "$help_help"]], ["Help"], 'do_link]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "You can use the command ", <$format, ["tt", [], ["@help"], 'do_tt]>, " to navigate the ", <$generator, ["servname", [], [], 'gen_servname]>, "'s help system, when on an interactive connection. If this command is used with a word or group of words, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@help VR Commands"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "It will first attempt to find the word(s) as one of the hyperlinks from your current page. If it fails at this, it will attempt to lookup the word as a topic in the help indices. If this also fails, it will return a message explaining that it could not find help on that topic. ", <$format, ["np", [], [], 'do_np]>, "Therefore, to activate a hyperlink from a page you are reading, simply type ", <$format, ["tt", [], ["@help"], 'do_tt]>, " and the name of the hyperlink. For instance, if the hyperlink was ", <$format, ["link", [["node", "$help_help"]], ["Help"], 'do_link]>, ", typing ", <$format, ["tt", [], ["@help help"], 'do_tt]>, " would activate the link. For convenience, you can use the command shortcut ", <$format, ["tt", [], ["?"], 'do_tt]>, " instead of ", <$format, ["tt", [], ["@help"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "Other Help topics:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_help_options"]], ["Options"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Options and shortcuts to @help"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_help_navigating"]], ["Navigating"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Hints on navigating Help"], 'do_dd]>], 'do_dl]>], #[['this, $help_help]]]>;
var $root managed = [$help_help];
var $root owned = [$help_help];
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_help_options: $help_help;

var $root manager = $help_help_options;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847650584;
var $has_name name = ['prop, "Help Options", "Help Options"];
var $help_node links = #[["Command Matching Conventions", $help_commands_matching]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Available options for the command ", <$format, ["tt", [], ["@help"], 'do_tt]>, " are:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], ["-h?istory"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Display your help page history"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["-b?ack"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Go back one page in your history"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["-b?ack ", <$format, ["i", [], ["name"], 'do_i]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Go back to page ", <$format, ["i", [], ["name"], 'do_i]>, " in your history"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["-f?orward"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Go forward one page your history"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["-f?orward ", <$format, ["i", [], ["name"], 'do_i]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Go forward to page ", <$format, ["i", [], ["name"], 'do_i]>, " in your history"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["-u?p"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Go up to the parent node of the current node"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["-fix"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Fix your history, useful if it becomes corrupt"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["-l?inks"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["List all of the links off the current help page"], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "The question mark ", <$format, ["tt", [], ["?"], 'do_tt]>, " in the above options specifies that characters following it are optional, (following the standard ", <$format, ["link", [["node", "$help_commands_matching"]], ["Command Matching Conventions"], 'do_link]>, "). ", <$format, ["subj", [["level", "3"]], ["Option Shortcuts"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Options have shorthand equivalents, as follows:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], ["?"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["-history"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["<"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["-back"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["<", <$format, ["i", [], ["name"], 'do_i]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["-back ", <$format, ["i", [], ["name"], 'do_i]>], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [">"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["-forward"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [">", <$format, ["i", [], ["name"], 'do_i]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["-forward ", <$format, ["i", [], ["name"], 'do_i]>], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["^"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["-up"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["!"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["-fix"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["#"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["-links"], 'do_dd]>], 'do_dl]>], #[['this, $help_help_options]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_help_options];
var $root owned = [$help_help_options];
var $help_node nolist = 0;


new object $help_help_navigating: $help_help;

var $root manager = $help_help_navigating;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847650599;
var $has_name name = ['prop, "Navigating Help", "Navigating Help"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "You may encounter conflicts of link and node names while navigating help. This may occur if you do not specify the entire link name. Make sure when you activate a link you include enough of the link name to get a precise match (you do not always need to specify the entire link name). If you are still getting a conflict you can narrow the search parameters. First, to better understand what happens when you activate a link keep in mind the following search order:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["Search in current page links"], 'do_li]>, <$format, ["li", [], ["Search in current page group"], 'do_li]>, <$format, ["li", [], ["Search in current page's index"], 'do_li]>, <$format, ["li", [], ["Search in all other help indices"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "If you are having a conflict you can prefix what you are searching for with either ", <$format, ["tt", [], ["group="], 'do_tt]>, ", ", <$format, ["tt", [], ["link="], 'do_tt]>, " or ", <$format, ["tt", [], ["index="], 'do_tt]>, " and it will search only in the respective area. For instance, if you were to type:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["?index=narf"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "It would bypass any links or group nodes to ", <$format, ["tt", [], ["narf"], 'do_tt]>, ", and only search in the current index and subsequent indices. Furthermore, if you specify a word other than the above, it will attempt to match only in the relevant index. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["?core=narf"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Would search only in the core index, assuming it existed. Furthermore, when searching a specific index if the search word you specify is simply a hash-mark ", <$format, ["tt", [], ["#"], 'do_tt]>, ", it will set the current index as the help node."], #[['this, $help_help_navigating]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_help_navigating];
var $root owned = [$help_help_navigating];
var $help_node nolist = 0;


new object $help_general: $help_coldcore;

var $root manager = $help_general;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847218948;
var $has_name name = ['prop, "General Information", "General Information"];
var $help_node links = #[["Building and Extending", $help_building], ["@help", $help_help], ["Programming", $help_prog], ["Conventions", $help_conventions], ["Objects", $help_objects], ["Environment", $help_environment], ["Appearance", $help_appearance], ["Security", $help_security], ["Commands", $help_commands], ["Interaction", $help_interaction], ["Interface", $help_interface]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "General topics are covered in this area. If you need to know about describing and extending your Virtual Environment read about ", <$format, ["link", [["node", "$help_building"]], ["Building and Extending"], 'do_link]>, ". Help on a specific object may be obtained by typing ", <$format, ["link", [["node", "$help_help"]], ["@help"], 'do_link]>, " followed by the full object name. ", <$format, ["link", [["node", "$help_prog"]], ["Programming"], 'do_link]>, " help is also available.", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_conventions"]], ["Conventions"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Conventions used in these documents"], 'do_dd]>, <$format, ["br", [], [], 'do_br]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_objects"]], ["Objects"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Learn about Objects"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_environment"]], ["Environment"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["How Objects are used in your Environment"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_appearance"]], ["Appearance"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Changing something's appearance"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_security"]], ["Security"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["How ColdCore security works"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_commands"]], ["Commands"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Learn about commands"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_interaction"]], ["Interaction"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["How to interact with others"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_interface"]], ["Interface"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["How to personalize your interface"], 'do_dd]>], 'do_dl]>], #[['this, $help_general]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_general];
var $root owned = [$help_general];
var $help_node nolist = 0;


new object $help_conventions: $help_general;

var $root manager = $help_conventions;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847225687;
var $has_name name = ['prop, "Conventions", "Conventions"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Througout these documents certain conventions are used. If a document is explaining a command to be typed, it will begin with a greater-than sign (", <$format, ["tt", [], [">"], 'do_tt]>, "), such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> command"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If a document shows the syntax for a command a few conventions are used. First, words grouped within greater-than and less-than (", <$format, ["tt", [], ["<>"], 'do_tt]>, ") signs are ", <$format, ["i", [], ["variables"], 'do_i]>, " and should be replaced with what you actually type. Second, words or ", <$format, ["i", [], ["variables"], 'do_i]>, " within square brackets (", <$format, ["tt", [], ["[]"], 'do_tt]>, ") are optional. You may also see an elipse (", <$format, ["tt", [], ["..."], 'do_tt]>, ") inside square brackets. This simply means that it will accept multiple instances of the last word or ", <$format, ["i", [], ["variable"], 'do_i]>, ". The following example shows the first ", <$format, ["i", [], ["variable"], 'do_i]>, " argument is required, and more may be added:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: @command <arg1> [<arg2> ...]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If a document is explaining how ColdC code may be evaluated when interpreted, the first line is the ColdC code and the second line begins with a text arrow pointing to the right (", <$format, ["tt", [], ["=>"], 'do_tt]>, ") and is followed by a ColdC data value. This represents what the example would evaluate to and return. For instance, calling the function ", <$format, ["tt", [], ["ctime()"], 'do_tt]>, " could return the value ", <$format, ["tt", [], ["\"Sun Feb 25 17:06:38 1996\""], 'do_tt]>, ". The function call and resulting value would be listed using this convention as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["ctime()\n=> \"Sun Feb 25 17:06:38 1996\""], 'do_quote]>], 'do_dfn]>], #[['this, $help_conventions]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_conventions];
var $root owned = [$help_conventions];
var $help_node nolist = 0;


new object $help_objects: $help_general;

var $root manager = $help_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 846994462;
var $has_name name = ['prop, "Objects", "Objects"];
var $help_node links = #[["Object Oriented Programming", $help_coldc_oop], ["Environment", $help_environment]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Objects are the primary element of Cold. An object is an abstract concept used to aid in program design. In simple terms an object is something which contains information (data) and instructions for manipulating this information (methods or functions). ", <$format, ["np", [], [], 'do_np]>, "If you are unfamiliar with the concepts of Objects, and Object Oriented Programming, you may want to read about ", <$format, ["link", [["node", "$help_coldc_oop"]], ["Object Oriented Programming"], 'do_link]>, " in the ColdC Reference Manual. ", <$format, ["np", [], [], 'do_np]>, "Even if you do not intend to program, it is important to know about objects. If you want to specify an object that is not in your ", <$format, ["link", [["node", "$help_environment"]], ["Environment"], 'do_link]>, ", you can do it by using the object name. Object names are single words (no spaces), beginning with a dollar sign ", <$format, ["tt", [], ["$"], 'do_tt]>, ". The following are all object names:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["$root, $sys, $user_joe"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Using objects as a foundation, the Cold Core creates locations and rooms ($place), generic items which can be found in a physical environment ($thing) and more."], #[['this, $help_objects]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_objects];
var $root owned = [$help_objects];
var $help_node nolist = 0;


new object $help_environment: $help_general;

var $root manager = $help_environment;
var $root created_on = 810254707;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Environment", "Environment"];
var $help_node links = #[["@remember", $help_cmd_remember]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Your environment is where the system tries to find things, when you name something. It does this by first checking everything in your contents, and everything in the location you are in. ", <$format, ["np", [], [], 'do_np]>, "The system will also check your recent context. The server records the last object you named, as well as all of the last objects you named (with a gender). You can list your recent context with the command @context, receiving a result similar to:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["Last thing: the Magazine Rack\nLast it:    the Magazine Rack      \nLast her:   Squeak the lemming\nLast him:   Miro"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When the system is attempting to find a named object, it first checks in your context. This allows you to name objects by their gender (if you remember it correctly). For instance:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["> get bottle\nYou take the bottle.\n> drop it\nYou drop the bottle."], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Furthermore, if you do not name an object, it will return the last object you named:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["> get bottle\nYou take the bottle.\n> drop\nYou drop the bottle."], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "There are also two words known by the system. The first is ", <$format, ["tt", [], ["me"], 'do_tt]>, ", which is always you. The second is ", <$format, ["tt", [], ["here"], 'do_tt]>, ", which is always your location. ", <$format, ["np", [], [], 'do_np]>, "If you are having a hard time remembering an items object name, or typing it's full name, you can remember it as a shorter name, with the command ", <$format, ["link", [["node", "$help_cmd_remember"]], ["@remember"], 'do_link]>, "."], #[['this, $help_environment]]]>;
var $root managed = [$help_environment];
var $root owned = [$help_environment];
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_appearance: $help_general;

var $root manager = $help_appearance;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855981674;
var $root managed = [$help_appearance];
var $has_name name = ['prop, "Appearance", "Appearance"];
var $help_node links = #[["Names", $help_app_names], ["Description", $help_app_desc], ["Gender", $help_app_gender], ["Wearing", $help_app_wearing]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Anything in the virtual environment will always have some common attributes, such as name, description and gender. If you manage the item, you can chance these attributes and alter it's appearance (this includes yourself). Everything that can be changed is described in more detail in the following sections:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_app_names"]], ["Names"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_app_desc"]], ["Description"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_app_gender"]], ["Gender"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_app_wearing"]], ["Wearing"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_appearance]]]>;
var $root inited = 1;
var $root child_index = 4;
var $help_node nolist = 0;


new object $help_app_names: $help_appearance;

var $root manager = $help_app_names;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856649225;
var $root managed = [$help_app_names];
var $has_name name = ['prop, "Names", "Names"];
var $help_node links = #[["@rename", $help_cmd_rename], ["Matching", $help_commands_matching], ["@add-name-template", $help_cmd_ant], ["@del-name-template", $help_cmd_dnt]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "If you are the manager of an item you can change it's name, name templates, and possibly even its object name. First, you can change its name with the command ", <$format, ["link", [["node", "$help_cmd_rename"]], ["@rename"], 'do_link]>, ", such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@rename thing_7 to Bat"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Be sure to read the manual on ", <$format, ["link", [["node", "$help_cmd_rename"]], ["@rename"], 'do_link]>, ", as it will explain how to set the article for a name and how to change the object name. ", <$format, ["np", [], [], 'do_np]>, "Name templates exist in order to help name matching. Keep in mind that Cold will match the beginning of any word in a name, so if you have the name ", <$format, ["tt", [], ["\"Red Hat\""], 'do_tt]>, " both ", <$format, ["tt", [], ["\"red\""], 'do_tt]>, " and ", <$format, ["tt", [], ["\"hat\""], 'do_tt]>, " would match. This makes it unecessary and redundant to add a template ", <$format, ["tt", [], ["\"hat\""], 'do_tt]>, ". Template matching is used for name templates. For more information on template matching read the section ", <$format, ["link", [["node", "$help_commands_matching"]], ["Matching"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "An example of good name template use is a door, with the name ", <$format, ["tt", [], ["\"Oaken Door\""], 'do_tt]>, " and with the name template ", <$format, ["tt", [], ["\"e?ast\""], 'do_tt]>, ". The commands ", <$format, ["link", [["node", "$help_cmd_ant"]], ["@add-name-template"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_cmd_dnt"]], ["@del-name-template"], 'do_link]>, " are used to add and remove name templates--or they can be included when you change the name with ", <$format, ["link", [["node", "$help_cmd_rename"]], ["@rename"], 'do_link]>, " by seperating each template with a comma, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@rename door to Oaken Door, e?ast"], 'do_dfn]>], #[['this, $help_app_names]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_app_desc: $help_appearance;

var $root manager = $help_app_desc;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856649225;
var $root managed = [$help_app_desc];
var $has_name name = ['prop, "Description", "Description"];
var $help_node links = #[["@describe", $help_cmd_describe], ["CML", $help_cml]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "If you are the manager of an item you can change it's description with the command ", <$format, ["link", [["node", "$help_cmd_describe"]], ["@describe"], 'do_link]>, ". Descriptions are entered as ", <$format, ["link", [["node", "$help_cml"]], ["CML"], 'do_link]>, ", but you do not need to know CML to describe something--just to use its features."], #[['this, $help_app_desc]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_app_gender: $help_appearance;

var $root manager = $help_app_gender;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856649225;
var $root managed = [$help_app_gender];
var $has_name name = ['prop, "Gender", "Gender"];
var $help_node links = #[["@set", $help_cmd_set]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "If you are the manager of an item you can change it's gender. By default all genders are neuter. An item's gender is changed using the command ", <$format, ["link", [["node", "$help_cmd_set"]], ["@set"], 'do_link]>, " with the ", <$format, ["tt", [], ["gender"], 'do_tt]>, " setting, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set me:gender=male"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If you do not specify a gender, all of the possibilities will be listed."], #[['this, $help_app_gender]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_app_wearing: $help_appearance;

var $root manager = $help_app_wearing;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856649225;
var $root managed = [$help_app_wearing];
var $has_name name = ['prop, "Wearing", "Wearing"];
var $help_node links = #[["wear", $help_cmd_wear], ["shed", $help_cmd_wear]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Any virtually alive item (something which is descended from the ", <$format, ["tt", [], ["$body"], 'do_tt]>, " object) can wear things--generally clothing. Anything worn is a ", <$format, ["i", [], ["Wearable Frob"], 'do_i]>, ", and must be from the object ", <$format, ["tt", [], ["$wearable_frob"], 'do_tt]>, " or one of its descendants. A new article of clothing can be created by typing:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@new $wearable_frob named Trenchcoat"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "After it is created you will be holding it. At this point it is worn with the command ", <$format, ["link", [["node", "$help_cmd_wear"]], ["wear"], 'do_link]>, " and removed with the command ", <$format, ["link", [["node", "$help_cmd_wear"]], ["shed"], 'do_link]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["wear trenchoat"], 'do_dfn]>], #[['this, $help_app_wearing]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_security: $help_general;

var $root manager = $help_security;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853888954;
var $has_name name = ['prop, "Security", "Security"];
var $help_node links = #[["@mojo", $help_cmd_mojo]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Security in the ColdCore is setup in a level structure, with each subsequent level encompasing the previous. All access is on a per-object basis, with the exception of the top level (System Level) which is globally encompassing. Basically, you can manage several objects, be a writer on a few more and a trustee on some others. User classes (i.e. builder, programmer, admin) are not associated with any security level, they exist simply to group commands and more powerful interfaces. The levels are:", <$format, ["p", [], [], 'do_p]>, <$format, ["table", [["cols", "20%,80%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["System Level"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["This level is the top level, encompassing administrators and system-level objects (such as ", <$format, ["tt", [], ["$root"], 'do_tt]>, " and ", <$format, ["tt", [], ["$sys"], 'do_tt]>, "). By default Administrators do not have this level enabled (it can be enabled each session with the command ", <$format, ["link", [["node", "$help_cmd_mojo"]], ["@mojo"], 'do_link]>, ")."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["Manager Level"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Every object has a manager. The manager has full permissions on the specific object. Quota usage is also based off the object Manager."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["Writer Level"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["An object can have any number of writers. Writer Level permissions give full access to an object, with a few exceptions:", <$format, ["ul", [], [<$format, ["li", [], ["Writers cannot change any access permissions on an object (this includes adding other writers or changing the Manager)."], 'do_li]>, <$format, ["li", [], ["Writers cannot change the object's parents."], 'do_li]>], 'do_ul]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["Trustee Level"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["An object trustee is simply another object that is trusted more than random objects but less than a writer. The amount of access given depends upon the subsystem. For instance, adding a user as a trustee to a location they are not a Manager or Writer of will give them the ability to extend other rooms from it."], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_security]]]>;
var $root inited = 1;
var $root managed = [$help_security];
var $help_node nolist = 0;


new object $help_commands: $help_general;

var $root child_index = 7;
var $root fertile = 1;
var $root manager = $help_commands;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $has_name name = ['prop, "Commands", "Commands"];
var $help_node links = #[["VR vs Non-VR", $help_commands_vr], ["Types", $help_commands_types], ["Matching", $help_commands_matching], ["Enhanced", $help_commands_enhanced], ["All Commands", $help_index_cmds], ["Programming", $help_prog_commands]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "This section outlines some of the basics of commands, from understanding the logic behind why they are named what they are, to using them, to programming them. (Programmer's note: Commands in the Cold Dark are handled entirely in the database, the driver is oblivious to the intent or meaning of what it is you type).", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_commands_vr"]], ["VR vs Non-VR"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["The difference between the two"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_commands_types"]], ["Types"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["The three types of commands"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_commands_matching"]], ["Matching"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Conventions used in matching commands"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_commands_enhanced"]], ["Enhanced"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["ColdCore's Enhanced Commands"], 'do_dd]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_index_cmds"]], ["All Commands"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["An index of all commands"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_prog_commands"]], ["Programming"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Programming Commands"], 'do_dd]>], 'do_dl]>], #[['this, $help_commands]]]>;
var $root managed = [$help_commands];
var $root owned = [$help_commands];
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_commands_vr: $help_commands;

var $root manager = $help_commands_vr;
var $root created_on = 810075673;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "VR vs Non-VR", "VR vs Non-VR"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "To help classify commands, a distinction has been made. This distinction is based upon how the command is used, and what it effects. If the command is a Non-VR command (it does not follow the Virtual Environment guidelines) it begins with an at-sign ('@'). Otherwise, it does not. ", <$format, ["np", [], [], 'do_np]>, "The best way to decide if a command is VR or Non-VR is to ask yourself the question: ", <$format, ["i", [], ["Is it something I could do in real-life?"], 'do_i]>, " For instance, you do not simply declare, \"", <$format, ["i", [], ["I am wearing pink polka dotted clothes"], 'do_i]>, "\", and suddenly you are. However, in the Cold Dark you have the ability to directly change how you look from moment to moment. Therefore this command (@describe) is a Non-VR command, and begins with an at-sign."], #[['this, $help_commands_vr]]]>;
var $root managed = [$help_commands_vr];
var $root owned = [$help_commands_vr];
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_commands_types: $help_commands;

var $root manager = $help_commands_types;
var $root created_on = 810075676;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Types", "Types"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Each command is associated with a specific method. When a command match is found, that method is executed with arguments depending upon what you typed. The Cold Dark recognizes three types of commands:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["b", [], ["Local Commands"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], [<$format, ["p", [], [], 'do_p]>, "Local commands are any non-directed command, or any command which does not require a target in the command line. Matching for local commands uses ColdC template matching.", <$format, ["p", [], [], 'do_p]>], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["Remote Commands"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], [<$format, ["p", [], [], 'do_p]>, "Remote commands differ from Local Commands in that they require the target of the command, in the command string. For instance, \"get button\" would be a remote command, because it requires the target of button to function correctly. Matching for Remote Commands uses ColdC template matching", <$format, ["p", [], [], 'do_p]>], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["Shortcuts"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], [<$format, ["p", [], [], 'do_p]>, "Shortcuts are intented as wrap-arounds for commands, using ColdC pattern matching instead of template matching."], 'do_dd]>], 'do_dl]>], #[['this, $help_commands_types]]]>;
var $root managed = [$help_commands_types];
var $root owned = [$help_commands_types];
var $help_node nolist = 0;


new object $help_commands_matching: $help_commands;

var $root manager = $help_commands_matching;
var $root created_on = 810075678;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Matching Conventions", "Matching Conventions"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Two types of general matching systems are used in Cold. The base matching system is pattern matching. The asterisk character ('*') in a pattern match is used to represent a wildcard. It can be placed anywhere in the pattern. It tells the interpreter that when matching the pattern with a string, anything can match the wildcard. This becomes useful for matching different strings. Some examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["Pattern:           \"match *\"\nString:            \"match anything after this\"\nWildcard Match:    \"anything after this\"\n\nPattern:           \"match *t not this\"\nString:            \"match only this but not this\"\nWildcard Match:    \"only this bu\""], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Template matching expands upon the basic idea of pattern matching. Template matching is a little smarter about matching. It recognizes words as anything bounded by spaces or the beginning and end of the string. In a template the wildcard must be its own word--it must have spaces around it. Templates also add two more special characters; the question mark ('?') for optional matching and the pipe character ('|') for multiple matches. ", <$format, ["np", [], [], 'do_np]>, "If a question mark is placed within a word, it means that the word must match up to the point of the question mark, but everything after that point is optional. For instance, all of the following would be valid against the specified template:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["Template:          \"th?is\"\nString:            \"th\"\nString:            \"thi\"\nString:            \"this\""], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The pipe character (", <$format, ["tt", [], ["|"], 'do_tt]>, ") is used to specify several different words that can match the place of one. For instance, the template \"this|that|there\" would match \"this\" ", <$format, ["i", [], ["OR"], 'do_i]>, " \"that\" ", <$format, ["i", [], ["OR"], 'do_i]>, " \"there\". It is easiest to logically think of the pipe character as ", <$format, ["i", [], ["OR"], 'do_i]>, ". With these elements drawn together you get a simple yet dynamic matching system. Some full template examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["\"l?ook at *\"\n\"give|put * to|in *\"\n\"@who *\"\n\"@lock * to|with *\""], 'do_quote]>], 'do_dfn]>], #[['this, $help_commands_matching]]]>;
var $root managed = [$help_commands_matching];
var $root owned = [$help_commands_matching];
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_commands_enhanced: $help_commands;

var $root manager = $help_commands_enhanced;
var $root created_on = 810075680;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Enhanced Command Templates", "Enhanced Command Templates"];
var $help_node links = #[["Programming Commands", $help_prog_commands]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The Cold Dark further expands upon the above matching systems, specifying certain types of arguments which can be accepted for a command, where the wildcard ('*') is located. These are specified within less-than and greater-than signs (", <$format, ["tt", [], ["<"], 'do_tt]>, " and ", <$format, ["tt", [], [">"], 'do_tt]>, "). These tags simply tell the parser what type of arguments to accept in that location on the command line. An example would be:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["push <user>"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Where <user> must be a valid user of the system, some more examples follow.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["\"l?ook at <thing>\"\n\"get|take <any> from <thing>\"\n\"@who <user>\"\n\"@show <object>\""], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "More information on Enhanced Command Templates can be found in the section ", <$format, ["link", [["node", "$help_prog_commands"]], ["Programming Commands"], 'do_link]>, "."], #[['this, $help_commands_enhanced]]]>;
var $root managed = [$help_commands_enhanced];
var $root owned = [$help_commands_enhanced];
var $help_node nolist = 0;


new object $help_interaction: $help_general;

var $root manager = $help_interaction;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Interaction", "Interaction"];
var $help_node links = #[["say", $help_cmd_say], ["emote", $help_cmd_emote], ["to", $help_cmd_tosay], ["whisper", $help_cmd_whisper], ["think", $help_cmd_think], ["spoof", $help_cmd_spoof], ["@page", $help_cmd_page], ["@paste", $help_cmd_paste], ["shortcuts", $help_cmd_shortcuts]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The following common interaction commands exist:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_say"]], ["say"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Speak and talk to others"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_emote"]], ["emote"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Do free-form actions"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_tosay"]], ["to"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Direct messages to people in the room"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_whisper"]], ["whisper"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Privately talk to somebody"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_think"]], ["think"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Thinks something out loud"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_spoof"]], ["spoof"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Similar to eval, but formatted differently"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_page"]], ["@page"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Talk to somebody not in the room"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_paste"]], ["@paste"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Paste a block of text to people"], 'do_dd]>, <$format, ["br", [], [], 'do_br]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cmd_shortcuts"]], ["shortcuts"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Additional unnamed interaction shortcuts"], 'do_dd]>], 'do_dl]>], #[['this, $help_interaction]]]>;
var $root managed = [$help_interaction];
var $root owned = [$help_interaction];
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_interface: $help_general;

var $root manager = $help_interface;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847647924;
var $has_name name = ['prop, "Interface", "Interface"];
var $help_node links = #[["Client", $help_interface_client], ["Format", $help_interface_format], ["Settings", $help_interface_settings]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "You can alter your interface in many ways. ", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_interface_client"]], ["Client"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Using a Client"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_interface_format"]], ["Format"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Your output format"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_interface_settings"]], ["Settings"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Configurable Settings"], 'do_dd]>], 'do_dl]>], #[['this, $help_interface]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_interface];
var $root owned = [$help_interface];
var $help_node nolist = 0;


new object $help_interface_client: $help_interface;

var $root manager = $help_interface_client;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847664123;
var $has_name name = ['prop, "Clients", "Clients"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "When you connect to a Virtual Environment System you use a ", <$format, ["i", [], ["client"], 'do_i]>, ". A client is simply a program you run from your machine. This program connects you with the server somewhere on the network. If you used ", <$format, ["tt", [], ["telnet"], 'do_tt]>, " to get here, your client is ", <$format, ["tt", [], ["telnet"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "This system is not designed for use with ", <$format, ["tt", [], ["telnet"], 'do_tt]>, ". It has many customized aspects which telnet simply does not support. Because of this it is suggested for your own benefit and enjoyment that you get a supported client. ", <$format, ["np", [], [], 'do_np]>, "Currently supported clients are: ", <$format, ["dfn", [["ind", "4"], ["nobound", 1]], [<$format, ["table", [["cols", "25%,75%"]], [<$format, ["tr", [], [<$format, ["td", [], ["Tinyfugue"], 'do_td]>, <$format, ["td", [], ["ftp://tf.tcp.com/pub/tinyfugue"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["TkMOO-lite"], 'do_td]>, <$format, ["td", [], ["http://www.cm.cf.ac.uk/User/Andrew.Wilson/tkMOO-light/"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['this, $help_interface_client]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_interface_client];
var $root owned = [$help_interface_client];
var $help_node nolist = 0;


new object $help_interface_format: $help_interface;

var $root manager = $help_interface_format;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847664131;
var $has_name name = ['prop, "Format", "Format"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "By default your output format is plaintext (text/plain). You can change this to other formats by setting your Content-Type. Currently supported alternate types are:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], ["Plain Text (text/plain)"], 'do_li]>, <$format, ["li", [], ["HTML Text (text/html)"], 'do_li]>], 'do_ul]>, <$format, ["np", [], [], 'do_np]>, "These formats can easilly be extended to include others. To change your output format use the command:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set content-type=type"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Where ", <$format, ["i", [], ["type"], 'do_i]>, " is one of the MIME encodings of the above types (either ", <$format, ["tt", [], ["text/plain"], 'do_tt]>, " or ", <$format, ["tt", [], ["text/html"], 'do_tt]>, ")."], #[['this, $help_interface_format]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_interface_format];
var $root owned = [$help_interface_format];
var $help_node nolist = 0;


new object $help_interface_settings: $help_interface;

var $root manager = $help_interface_settings;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847664220;
var $has_name name = ['prop, "Settings", "Settings"];
var $help_node links = #[["@set", $help_cmd_set]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "There are many configurable settings available for you to use in customizing your environment. The command ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_set"]], ["@set"], 'do_link]>], 'do_tt]>, " is used to make these changes. If you type ", <$format, ["tt", [], ["@set"], 'do_tt]>, " with no arguments it will list all of your current settings. To change a setting you simply type ", <$format, ["tt", [], ["@set"], 'do_tt]>, " followed by the setting name, an equals sign and the new value. If the value does not conform to the setting requirements you will be notified appropriately. For example, the following will turn on the capability to receive variable termination on messages (i.e. you can recieve text prompts that are not terminated with newlines):", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set non-terminated-tell=on"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "There may also exist ", <$format, ["i", [], ["user-info"], 'do_i]>, " settings. These define Real-Life aspects of you. They work slightly different. By default all user-info settings are private, and may not be seen by anybody else unless you include ", <$format, ["tt", [], ["+public"], 'do_tt]>, " at the beginning of the setting, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set real-name=+public Brandon Gilespie"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Read about the ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_cmd_set"]], ["@set"], 'do_link]>], 'do_tt]>, " command for more information."], #[['this, $help_interface_settings]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_interface_settings];
var $root owned = [$help_interface_settings];
var $help_node nolist = 0;


new object $help_building: $help_coldcore;

var $root manager = $help_building;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847060847;
var $has_name name = ['prop, "Building", "Building"];
var $help_node links = #[["Theme", $help_theme], ["Dynamic Text", $help_cml], ["Places", $help_build_places]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Building in ColdCore is considered anything from describing yourself or an object you carry, to designing and creating full areas.", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_theme"]], ["Theme"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["The VR Theme"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_cml"]], ["Dynamic Text"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["The Cold text Markup Language"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_build_places"]], ["Places"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["How Places work"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["Commands"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Overview of Building Commands"], 'do_dd]>], 'do_dl]>], #[['this, $help_building]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root child_index = 8;
var $root managed = [$help_building];
var $root owned = [$help_building];
var $help_node nolist = 0;


new object $help_theme: $help_building;

var $root manager = $help_theme;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847060976;
var $has_name name = ['prop, "Theme", "Theme"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The Cold Dark has two primary realms, each with their own theme. ", <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["subj", [["level", "2"]], ["Taobh Thiar"], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Taobh Thiar [tave theer] is Gaelic for 'Beyond'. This realm is pretty much free-form, assuming you can get permission from a local area's managers to link into it."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "2"]], ["En Requiem"], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["En Requiem is a realm of Fantasy and Technology. More information on it can be found on the World Wide Web at: ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["http://www.cold.org/EnRequiem/"], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Contact Brandon for information on building in En Requiem."], 'do_dd]>], 'do_dl]>], #[['this, $help_theme]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_theme];
var $root owned = [$help_theme];
var $help_node nolist = 0;

root method .core_help_theme() {
    new.set_body(["This node needs to be written, use @help-list and @help-write"]);
    
    // $#Edited: 03 Nov 96 16:03 $brandon
};


new object $help_cml: $help_building;

var $root fertile = 1;
var $root manager = $help_cml;
var $root owned = [$help_cml];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'variables, 'core];
var $root managed = [$help_cml];
var $has_name name = ['prop, "CML|Cold Markup Language", "CML|Cold Markup Language"];
var $help_node links = #[["Formatters", $help_cml_formatters], ["Generators", $help_cml_generators], ["Customizing", $help_cml_customizing]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "CML is used to markup text for dynamic generation and formatting. CML text is compiled to an internal abstraction called Ctext which can be easilly decompiled to plain text, HTML or any other format that may be desired. Ctext is also dynamically interpreted for each interface receiving the text. This gives extreme power in the final result, and is much faster than older MUD systems which use %x replacements in strings to achieve the same result. ", <$format, ["np", [], [], 'do_np]>, "The CML syntax is made of tags embedded within the text. Tags can be formatted one of two ways depending upon if they are for dynamic text generation (Generator) or as a formatting or other directive (Formatter): ", <$format, ["dfn", [["nobound", 1]], [<$format, ["table", [["cols", "30%,50%"]], [<$format, ["tr", [], [<$format, ["td", [], ["Generator Format:"], 'do_td]>, <$format, ["td", [], ["[<name> <options>:<arguments>]"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["Directive Format:"], 'do_td]>, <$format, ["td", [], ["{<name> <options>:<arguments>}"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Specific tag names may vary depending upon the system. For more information on the specific tags for this system see help on ", <$format, ["link", [["node", "$help_cml_formatters"]], ["Formatters"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_cml_generators"]], ["Generators"], 'do_link]>, ".", <$format, ["p", [], [], 'do_p]>, "The exact behaviour of a tag may be controlled using options (sometimes called flags). Options can be in any order, and are specified in one of two ways: ", <$format, ["dfn", [["nobound", 1]], [<$format, ["table", [["cols", "20%,50%"]], [<$format, ["tr", [], [<$format, ["td", [], ["key=value"], 'do_td]>, <$format, ["td", [], ["sets the option named key to value"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["key"], 'do_td]>, <$format, ["td", [], ["sets the option named key to true (if unspecified it will be false)."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Arguments (anything following the colon) are optional, and depend upon the tag. How arguments are handled depends on whether the tag is a Generator or a Formatter. A Generator will treat it's arguments as a space seperated list. A formatter will treat it's argument as a single string, starting at the first non-space character following the colon. Arguments may contain other tags. ", <$format, ["np", [], [], 'do_np]>, "All tags with the exception of ", <$format, ["tt", [], ["quote"], 'do_tt]>, " follow this syntax. ", <$format, ["tt", [], ["quote"], 'do_tt]>, " can be used to include literal unparsed text in a document. It is similar to HTML's <pre> in that it includes any literal formatting of white space. However, it does ", <$format, ["i", [], ["NOT"], 'do_i]>, " parse any formatters or generators within it's body. ", <$format, ["tt", [], ["quote"], 'do_tt]>, " is formatted as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["{quote <text>}"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Where <text> is anything, including curly braces. Note: there is no colon following ", <$format, ["tt", [], ["quote"], 'do_tt]>, ", and there are no options for ", <$format, ["tt", [], ["quote"], 'do_tt]>, ". Further information on CML and Ctext can be found at:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["link", [["node", "$help_cml_formatters"]], ["Formatters"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["About CML Formatters"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cml_generators"]], ["Generators"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["About CML Generators"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_cml_customizing"]], ["Customizing"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Customizing Ctext"], 'do_dd]>], 'do_dl]>], #[['this, $help_cml]]]>;
var $root child_index = 1;
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_cml_formatters: $help_cml;

var $root manager = $help_cml_formatters;
var $root created_on = 809737729;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Formatters", "Formatters"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The standard formatter tags are loosely based on HTML 3.0: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "11%,89%"]], [<$format, ["tr", [], [<$format, ["td", [], ["action"], 'do_td]>, <$format, ["td", [], ["One flag of ", <$format, ["tt", [], ["cmd"], 'do_tt]>, ", which is run if the action is triggered (either by clicking on it, or using the action-trigger command ", <$format, ["tt", [], ["'>'"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["b"], 'do_td]>, <$format, ["td", [], ["Bold or strong"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["br"], 'do_td]>, <$format, ["td", [], ["Line Break. Differs from {p} in that it can be stacked multiple times, for multiple breaks. Use of {p} is preferred."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["dd"], 'do_td]>, <$format, ["td", [], ["Dictionary Definition, must be an argument to a Dictionary List (", <$format, ["tt", [], ["dl"], 'do_tt]>, ")"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["detail"], 'do_td]>, <$format, ["td", [], ["Generate a description detail. One required option of ", <$format, ["tt", [], ["name"], 'do_tt]>, " which is unique to this detail througout the entire description. Details may be nested"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["dfn"], 'do_td]>, <$format, ["td", [], ["Definition. Used to indent a block of text. Arguments can be ", <$format, ["tt", [], ["ind"], 'do_tt]>, ", which is an integer representing the spaces to indent (in plaintext this defaults to eight); and ", <$format, ["tt", [], ["nobound"], 'do_tt]>, ", which effects the line breaks after the definition."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["dl"], 'do_td]>, <$format, ["td", [], ["Dictionary list. Arguments can contain tags dt (dictionary title) and dd (dictionary definition)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["dt"], 'do_td]>, <$format, ["td", [], ["Dictionary Title, must be an argument to a Dictionary List (", <$format, ["tt", [], ["dl"], 'do_tt]>, ")"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["i"], 'do_td]>, <$format, ["td", [], ["Italics or Emphasis"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["img"], 'do_td]>, <$format, ["td", [], ["Place image in description. Image is only fisible in HTML format"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["lh"], 'do_td]>, <$format, ["td", [], ["List Header, must be an argument for ", <$format, ["tt", [], ["ol"], 'do_tt]>, " or ", <$format, ["tt", [], ["ul"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["li"], 'do_td]>, <$format, ["td", [], ["List Element, must be an argument for ", <$format, ["tt", [], ["ol"], 'do_tt]>, " or ", <$format, ["tt", [], ["ul"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["link"], 'do_td]>, <$format, ["td", [], ["Creates a hypertext link to the help node (as an objname) specified with the option ", <$format, ["tt", [], ["node"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["np"], 'do_td]>, <$format, ["td", [], ["New Paragraph, similar to {p}, but in plaintext it breaks with two lines rather than one."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["ol"], 'do_td]>, <$format, ["td", [], ["Ordered list. Within arguments use tags lh (list header) and li (list element)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["p"], 'do_td]>, <$format, ["td", [], ["Paragraph Break, similar to {np}, but in plaintext it only breaks with one line.."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["subj"], 'do_td]>, <$format, ["td", [], ["Rougly equivalent to HTML's header <h?> tags. Argument ", <$format, ["tt", [], ["level"], 'do_tt]>, " specifies which level of subject to use (1-4)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["table"], 'do_td]>, <$format, ["td", [], ["Similar to tables in HTML. Options are ", <$format, ["tt", [], ["ind"], 'do_tt]>, " (how many spaces to indent the table before formatting) and ", <$format, ["tt", [], ["cols"], 'do_tt]>, " (column definition). ", <$format, ["tt", [], ["cols"], 'do_tt]>, " must be defined. It is a comma seperated list of column specs, which can either be in specific character units or percentages (the whole list must be either one or the other). Arguments consist of ", <$format, ["tt", [], ["tr"], 'do_tt]>, " (table row) tags."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["td"], 'do_td]>, <$format, ["td", [], ["Table Cell, options include ", <$format, ["tt", [], ["colspan"], 'do_tt]>, " and ", <$format, ["tt", [], ["rowspan"], 'do_tt]>, " which can be used to span columns and rows with the Table Cell"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["tr"], 'do_td]>, <$format, ["td", [], ["Table Row, arguments consist of ", <$format, ["tt", [], ["td"], 'do_tt]>, " tags for each table cell in the row."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["tt"], 'do_td]>, <$format, ["td", [], ["Fixed-width font (typewriter), also used for literal text"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["ul"], 'do_td]>, <$format, ["td", [], ["Unordered list. Within arguments use tags lh (list header) and li (list element)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["web"], 'do_td]>, <$format, ["td", [], ["Creates a www hypertext link. Requires ", <$format, ["tt", [], ["src"], 'do_tt]>, " option with a valid URL as the value"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['this, $help_cml_formatters]]]>;
var $root managed = [$help_cml_formatters];
var $root owned = [$help_cml_formatters];
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_cml_generators: $help_cml;

var $root manager = $help_cml_generators;
var $root created_on = 809736951;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Generators", "Generators"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [["ind", "4"], ["nobound", 1]], [<$format, ["table", [["cols", "16%,84%"]], [<$format, ["tr", [], [<$format, ["td", [], ["columnize"], 'do_td]>, <$format, ["td", [], ["Generates a list of columnized strings taken from the argument list. Option ", <$format, ["tt", [], ["cols"], 'do_tt]>, " defines column information."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["def"], 'do_td]>, <$format, ["td", [], ["Requires option ", <$format, ["tt", [], ["var"], 'do_tt]>, " which is the name of a variable. Creates a new variable generator with that name, which has the value of the first argument. Will ", <$format, ["i", [], ["not"], 'do_i]>, " evaluate arguments, instead stores the unparsed first argument. Similar to ", <$format, ["tt", [], ["set"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["english"], 'do_td]>, <$format, ["td", [], ["Generates an english-formatted list from the arguments. Options can include ", <$format, ["tt", [], ["sep"], 'do_tt]>, " (element seperator, defaulting to \",\"), ", <$format, ["tt", [], ["empty"], 'do_tt]>, " (what to print if the argument list is empty, defaulting to \"nothing\"), ", <$format, ["tt", [], ["and"], 'do_tt]>, " (what to print as a seperator before the last element, defaulting to \"and\")"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["foreach"], 'do_td]>, <$format, ["td", [], ["Requires option ", <$format, ["tt", [], ["list"], 'do_tt]>, ". Will iterate over body for each element in list. Additional option ", <$format, ["tt", [], ["var"], 'do_tt]>, " may be defined for iteration variable, defaults to ", <$format, ["tt", [], ["iterator"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["join"], 'do_td]>, <$format, ["td", [], ["Joins arguments. Options can include ", <$format, ["tt", [], ["seperator"], 'do_tt]>, " which is either ", <$format, ["tt", [], ["none"], 'do_tt]>, ", ", <$format, ["tt", [], ["english"], 'do_tt]>, " or a string literal. If ", <$format, ["tt", [], ["none"], 'do_tt]>, " the list is forwarded to the caller, rather than joined to a string"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["name"], 'do_td]>, <$format, ["td", [], ["Generates the names of the objects in the arguments list. Options can include ", <$format, ["tt", [], ["seperator"], 'do_tt]>, " which is either ", <$format, ["tt", [], ["none"], 'do_tt]>, ", ", <$format, ["tt", [], ["english"], 'do_tt]>, " or a string literal. If ", <$format, ["tt", [], ["none"], 'do_tt]>, " is given a list is generated, otherwise a string is generated"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["pro"], 'do_td]>, <$format, ["td", [], ["Generates a pronoun. Required option is ", <$format, ["tt", [], ["obj"], 'do_tt]>, " which defines the object for the pronoun generation. First argument is taken as the type of pronoun to use, as defined on $gender"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["servname"], 'do_td]>, <$format, ["td", [], ["The name of the server, as is set on ", <$format, ["tt", [], ["@set $motd:server-name"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["set"], 'do_td]>, <$format, ["td", [], ["Requires option ", <$format, ["tt", [], ["var"], 'do_tt]>, " which is the name of a variable. Creates a new variable generator with that name, which has the value of the first argument. Will evaluate arguments and store results. Similar to ", <$format, ["tt", [], ["def"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["switch"], 'do_td]>, <$format, ["td", [], ["Requires option ", <$format, ["tt", [], ["value"], 'do_tt]>, " which is evaluated. The resulting value is then used to select a result. Currently switch uses every other item in the argument list as a case/value pair (use the ", <$format, ["tt", [], ["join"], 'do_tt]>, " generator for arguments with spaces). If there is a remaining odd element is is considered the default result"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["time"], 'do_td]>, <$format, ["td", [], ["Arguments are sent to the native method $time.format()"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["vars"], 'do_td]>, <$format, ["td", [], ["Returns the names of variables available. Option ", <$format, ["tt", [], ["separator"], 'do_tt]>, " is the same as in ", <$format, ["tt", [], ["name"], 'do_tt]>, " generator"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, " ", <$format, ["subj", [["level", "4"]], ["Other tags"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Each cml processor can also create extra generators. Also, caller to the cml can create extra variables that are available for generators."], #[['this, $help_cml_generators]]]>;
var $root managed = [$help_cml_generators];
var $root owned = [$help_cml_generators];
var $help_node index = $help_index_core;
var $help_node nolist = 0;


new object $help_cml_customizing: $help_cml;

var $root manager = $help_cml_customizing;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837752811;
var $has_name name = ['prop, "Customizing Ctext", "Customizing Ctext"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["subj", [["level", "3"]], ["Interface"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "ctext frobs are created by calling compile_cml method off the cml compiler object. On a frob, you can do .uncompile (returns the original text), eval_ctext (evaluates the generators, but will not touch the formatters. This is used to speed up message dispatching) and format (final formatting of the ctext). You can add/modify variables on a frob by set_var(variable, value) call, or with set_vars(dict) (same, with multiple variables getting modified). ", <$format, ["subj", [["level", "3"]], ["Adding new evaluators"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "Evaluator is an object which contains methods for generation or formatting. Evaluation object descended from vanilla evaluator will try to store the evaluation results in a list, and is therefore most suitable for adding new generators. On the other hand, evaluators descended from a formatter object create string, and try to evaluate and concatenate lists until a string is obtained. Hence, you want to use them for formatting. To add a new generator or formatter, simply add a do_format or gen_generator method on the object, and make sure that the object is in the evaluation path (by explicitely adding 'evaluator, 'formatter or evan 'uncompiler field to the ctext frob.)"], #[['this, $help_cml_customizing]]]>;
var $root inited = 1;
var $root managed = [$help_cml_customizing];
var $root owned = [$help_cml_customizing];
var $help_node nolist = 0;


new object $help_build_places: $help_building;

var $root manager = $help_build_places;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855981673;
var $root managed = [$help_build_places];
var $has_name name = ['prop, "Places", "Places"];
var $help_node links = #[["appearance", $help_appearance], ["Realms", $help_places_realms], ["Exits and Entrances", $help_places_exen], ["Environment Conditions", $help_places_env]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A location is simply anywhere in the Virtual Environment that another object can reside. Locations can also be located themselves, such as a box which can hold something and also be located in a location. A place is a type of location. Places are generally not located themselves, such as a room in a building, or a sidewalk outside of the building. This type of location is derived from the $place object. Places have several different attributes aside from their contents and ", <$format, ["link", [["node", "$help_build_app"]], ["appearance"], 'do_link]>, ", namely their realm, entrances and exits and the environment conditions. Further topics on places:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_places_realms"]], ["Realms"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_places_exen"]], ["Exits and Entrances"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_places_env"]], ["Environment Conditions"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_build_places]]]>;
var $root inited = 1;
var $root child_index = 3;
var $help_node nolist = 0;


new object $help_places_realms: $help_build_places;

var $root manager = $help_places_realms;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856037606;
var $root managed = [$help_places_realms];
var $has_name name = ['prop, "Realms", "Realms"];
var $help_node links = #[["@new", $help_cmd_new]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Realms are used to group places, and can exist in a heirarchy structure. For instance, all rooms within a building would exist within one realm for that building, and that realm would exist within a realm for that sector of the city, which exists within a realm for the entire city. Realms are useful not only for grouping, but also for events and searching. When an event occurs it can be broadcast to the entire realm, rather than just to the local room. ", <$format, ["np", [], [], 'do_np]>, "New realms are created with the command ", <$format, ["link", [["node", "$help_cmd_new"]], ["@new"], 'do_link]>, ", such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@new $realm named the Clocktower"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When creating a realm make sure to create it from the right parent, so as to keep the heirarchy intact. For instance, the above realm might be better spawned from a realm for the city."], #[['this, $help_places_realms]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_places_exen: $help_build_places;

var $root manager = $help_places_exen;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856037607;
var $root managed = [$help_places_exen];
var $has_name name = ['prop, "Exits and Entrances", "Exits and Entrances"];
var $help_node links = #[["@build", $help_cmd_build], ["@dig", $help_cmd_dig]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Entrances and Exits to a place are either created with the command ", <$format, ["link", [["node", "$help_cmd_build"]], ["@build"], 'do_link]>, " when rooms are built, or they can be linked later with the command ", <$format, ["link", [["node", "$help_cmd_dig"]], ["@dig"], 'do_link]>, ". Before you can link exits from a room you have to either manage the room you are building from, be trusted by it, or it has to be publicly extendable. You can create a disconnected room to start building from with the command:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@dig My New Room"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Which will create a new place with the name ", <$format, ["i", [], ["My New Room"], 'do_i]>, ". Otherwise, you may need to contact the manager of a room you wish to build from. ", <$format, ["np", [], [], 'do_np]>, "For generic building the command ", <$format, ["link", [["node", "$help_cmd_build"]], ["@build"], 'do_link]>, " is a good starting point. It will give explanations at each step as it prompts you for what is needed (to begin building just type ", <$format, ["tt", [], ["@build"], 'do_tt]>, ")."], #[['this, $help_places_exen]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_places_env: $help_build_places;

var $root manager = $help_places_env;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856037607;
var $root managed = [$help_places_env];
var $has_name name = ['prop, "Environment Conditions", "Environment Conditions"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Environment Conditions in a room include how light or dark it is (which can effect how visible things are) and if the place is outside this also includes the weather and other atmospheric conditions."], #[['this, $help_places_env]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_build_cmds: $help_building;

var $root manager = $help_build_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855981676;
var $root managed = [$help_build_cmds];
var $has_name name = ['prop, "Commands", "Commands"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[['this, $help_build_cmds]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_prog: $help_coldcore;

var $root manager = $help_prog;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 846999513;
var $has_name name = ['prop, "Programming", "Programming"];
var $help_node links = #[["OOP", $help_coldc_oop], ["ColdC", $help_coldc], ["Commands", $help_prog_commands]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Be warned: anything from this section down is not complete.", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["link", [["node", "$help_coldc_oop"]], ["OOP"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Object Oriented Programming"], 'do_dd]>, <$format, ["dt", [], ["Programming a Method"], 'do_dt]>, <$format, ["dd", [], ["Overview on creating a method"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_coldc"]], ["ColdC"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["ColdC Reference Manual"], 'do_dd]>, <$format, ["dt", [], ["Functions"], 'do_dt]>, <$format, ["dd", [], ["Function Reference"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_prog_commands"]], ["Commands"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Overview of Programming Commands"], 'do_dd]>], 'do_dl]>], #[['this, $help_prog]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_prog];
var $root owned = [$help_prog];
var $root child_index = 2;
var $help_node nolist = 0;


new object $help_prog_commands: $help_prog;

var $root manager = $help_prog_commands;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 846999554;
var $has_name name = ['prop, "Programming Commands", "Programming Commands"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[['this, $help_prog_commands]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_prog_commands];
var $root owned = [$help_prog_commands];
var $help_node nolist = 0;


new object $help_coldc: $help_prog;

var $root manager = $help_coldc;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853692931;
var $has_name name = ['prop, "ColdC Reference Manual", "ColdC Reference Manual"];
var $help_node links = #[["Object Oriented Programming", $help_coldc_oop], ["Conventions used in this Document", $help_conventions], ["ColdC Objects", $help_coldc_objs], ["Referencing Objects", $help_coldc_objs_ref], ["Methods", $help_coldc_methods], ["Variables", $help_coldc_objs_vars], ["Special Objects", $help_coldc_objs_special], ["Tokens", $help_coldc_tokens], ["Data Types", $help_coldc_types], ["Expressions", $help_coldc_expr], ["Statements", $help_coldc_stmts], ["Frames and Tasks", $help_coldc_tasks], ["Errors", $help_coldc_errors], ["Security", $help_coldc_security], ["Networking", $help_coldc_net], ["Regular Expressions", $help_coldc_regexp], ["Files", $help_coldc_files], ["Textdump Structure", $help_coldc_textdump], ["Function Reference", $help_coldc_func], ["Native Method Reference", $help_coldc_native]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdC was initially created by Greg Hudson with ColdMUD, and was later developed and evolved by many enterprising individuals. ColdC is a low-profile object oriented database language. It is intended for network servers which require run-time morphism (such as Virtual/Interactive Environment Servers). ", <$format, ["np", [], [], 'do_np]>, "This reference manual is written by Brandon Gillespie, with portions being taken from the ColdMUD Reference manual written by Greg Hudson and additions by various Cold contributors.", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_oop"]], ["Object Oriented Programming"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_conventions"]], ["Conventions used in this Document"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs"]], ["ColdC Objects"], 'do_link]>], 'do_li]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs_ref"]], ["Referencing Objects"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs_methods"]], ["Methods"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs_vars"]], ["Variables"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs_special"]], ["Special Objects"], 'do_link]>], 'do_li]>], 'do_ul]>, <$format, ["li", [], ["Language Structure"], 'do_li]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_tokens"]], ["Tokens"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_types"]], ["Data Types"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_expr"]], ["Expressions"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_stmts"]], ["Statements"], 'do_link]>], 'do_li]>], 'do_ul]>, <$format, ["li", [], ["Implementation Reference"], 'do_li]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_methods"]], ["Methods"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_tasks"]], ["Frames and Tasks"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_errors"]], ["Errors"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_security"]], ["Security"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_net"]], ["Networking"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_regexp"]], ["Regular Expressions"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_files"]], ["Files"], 'do_link]>], 'do_li]>], 'do_ul]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_textdump"]], ["Textdump Structure"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_func"]], ["Function Reference"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_native"]], ["Native Method Reference"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc]]]>;
var $root inited = 1;
var $root child_index = 14;
var $root managed = [$help_coldc];
var $help_node nolist = 0;


new object $help_coldc_oop: $help_coldc;

var $root manager = $help_coldc_oop;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853694227;
var $has_name name = ['prop, "Object Oriented Programming|OOP", "Object Oriented Programming|OOP"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Object Oriented Programming (OOP) is a style of programming which not only groups procedures and data by functionality but which also applies a few common rules to how this grouping occurs. In OOP designers group procedures and data into ", <$format, ["i", [], ["modules"], 'do_i]>, ". By doing this it helps to define the purpose of the program, and also gives the added benefit of portability (porting a modular segment of code to another program is much easier than porting an integrated segment of code). ", <$format, ["np", [], [], 'do_np]>, "These modules (or ", <$format, ["i", [], ["objects"], 'do_i]>, ") will generally follow a few guidelines:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["Abstraction and Encapsulation of Data"], 'do_li]>, <$format, ["li", [], ["Inheritance"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "Because data and procedures are grouped together, all procedures which handle the specific data should be included within the module. ", <$format, ["i", [], ["Abstraction and Encapsulation"], 'do_i]>, " occurs when the module abstracts and controls access to the data it manipulates. The internal representation of data used by a module is most likely irrelevant to external sources (with the interface being the primary concern). ", <$format, ["np", [], [], 'do_np]>, "An example of ", <$format, ["i", [], ["Abstraction and Encapsulation"], 'do_i]>, " would be a table of people and their pets. The 'People and Pets' module has several procedures:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["i", [], ["Add Person"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Add a Person to the table. This procedure is passed the person, and their pet."], 'do_dd]>, <$format, ["dt", [], [<$format, ["i", [], ["Remove Person"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Remove a Person from the table. This procedure is passed the person to be removed."], 'do_dd]>, <$format, ["dt", [], [<$format, ["i", [], ["Get Pet"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["This procedure finds the pet for a given person. It is passed the person and returns the Pet associated with that person."], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "In the People and Pets module the table can be internalized in any form. The form is irrelevant to external programs which may use it. ", <$format, ["np", [], [], 'do_np]>, <$format, ["i", [], ["Inheritance"], 'do_i]>, " is the ability of another module to take on the functionality an existing module and further expand upon it. For instance, a 'People, Pets and their Names' module could be created which takes on the functionality of 'People and Pets', but expands it to include the names of the pets. ", <$format, ["np", [], [], 'do_np]>, "Inheritance is extremely useful because code becomes reusable and extendable without having to re-create each portion or module for different functionality. ", <$format, ["np", [], [], 'do_np]>, "In inheritance a module taking on the functionality of another object is called ", <$format, ["i", [], ["deriving"], 'do_i]>, " from that object. For instance, 'People, Pets and their Names' is derived from 'People and Pets'. The module 'People, Pets and their Names' is a ", <$format, ["i", [], ["child"], 'do_i]>, " of 'People and Pets', with 'People and Pets' being the ", <$format, ["i", [], ["parent"], 'do_i]>, " of 'People, Pets and their Names'."], #[['this, $help_coldc_oop]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_oop];
var $help_node nolist = 0;


new object $help_coldc_objs: $help_coldc;

var $root manager = $help_coldc_objs;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853696071;
var $has_name name = ['prop, "Objects", "Objects"];
var $help_node links = #[["parents", $help_coldc_oop], ["children", $help_coldc_oop], ["methods", $help_coldc_objs_methods], ["variables", $help_coldc_objs_vars], ["Referencing Objects", $help_coldc_objs_ref], ["Special Objects", $help_coldc_objs_special]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "An object in ColdC is both a data type and a database record. Objects are structured with ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_oop"]], ["parents"], 'do_link]>], 'do_i]>, " and ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_oop"]], ["children"], 'do_link]>], 'do_i]>, " in a tree (geneology-style) heirarchy known as the ", <$format, ["i", [], ["object heirarchy"], 'do_i]>, ". An object has both ColdC procedures (", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_objs_methods"]], ["methods"], 'do_link]>], 'do_i]>, ") and ColdC Data (", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_objs_vars"]], ["variables"], 'do_link]>], 'do_i]>, ") bound to it. The object variables are accessed and modified by the methods defined on the object. ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs_ref"]], ["Referencing Objects"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs_methods"]], ["Methods"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs_vars"]], ["Variables"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_objs_special"]], ["Special Objects"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_objs]]]>;
var $root inited = 1;
var $root child_index = 4;
var $root managed = [$help_coldc_objs];
var $help_node nolist = 0;


new object $help_coldc_objs_ref: $help_coldc_objs;

var $root manager = $help_coldc_objs_ref;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853696071;
var $has_name name = ['prop, "Referencing Objects", "Referencing Objects"];
var $help_node links = #[["identifier", $help_coldc_tokens]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Objects exist within the database, and are referenced with a unique number or ", <$format, ["i", [], ["Object Number"], 'do_i]>, " (", <$format, ["i", [], ["objnum"], 'do_i]>, "), which is assigned to the object upon its creation in the database. ", <$format, ["i", [], ["Object numbers"], 'do_i]>, " cannot be changed after an object is created. When an object is destroyed, it's ", <$format, ["i", [], ["objnum"], 'do_i]>, " is not re-used by the driver unless the database is decompiled to text and recompiled.", <$format, ["p", [], [], 'do_p]>, "An object can also have an ", <$format, ["i", [], ["Object Name"], 'do_i]>, " assigned to it, which can be changed througout the life of the object. Object Name's are only unique to that object, while the object has the name. Once the name is changed the old name can be taken by another object. Object Names exist for practical functionality, as it is easier to remember references which consist of alphabetic and numeric characters, compared to references which are simply numeric.", <$format, ["p", [], [], 'do_p]>, "In ColdC an object number is designated with a hash mark ('#') followed by the object's number. For instance ", <$format, ["tt", [], ["#23"], 'do_tt]>, " refers to ", <$format, ["i", [], ["object number"], 'do_i]>, " ", <$format, ["tt", [], ["23"], 'do_tt]>, ". An object name is designated as an ", <$format, ["link", [["node", "$help_coldc_tokens"]], ["identifier"], 'do_link]>, " beginning with a dollar sign (", <$format, ["tt", [], ["$"], 'do_tt]>, "). For instance, if the object ", <$format, ["tt", [], ["#23"], 'do_tt]>, " has the name ", <$format, ["i", [], ["object_23"], 'do_i]>, " assigned to it, it would be formatted in ColdC as: ", <$format, ["tt", [], ["$object_23"], 'do_tt]>, ".", <$format, ["p", [], [], 'do_p]>, "Both the object number and object name are generically called ", <$format, ["i", [], ["database references"], 'do_i]>, " (", <$format, ["i", [], ["dbrefs"], 'do_i]>, "). When the driver formats a database reference the Object Name will take precedence over an Object Number, because the name is generally easier to remember and comprehend.", <$format, ["p", [], [], 'do_p]>, "When the interpreter encounters an object name, it looks up the number associated with that name in a table. If no object has been assigned to that name, a ", <$format, ["tt", [], ["~namenf"], 'do_tt]>, " error is thrown; otherwise the object name is equivalent to the object number when executing."], #[['this, $help_coldc_objs_ref]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_objs_ref];
var $help_node nolist = 0;


new object $help_coldc_objs_methods: $help_coldc_objs;

var $root manager = $help_coldc_objs_methods;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853696071;
var $has_name name = ['prop, "Methods", "Methods"];
var $help_node links = #[["Defining Methods", $help_coldc_methods], ["descendants", $help_coldc_oop]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A method is a series of ColdC statements which are grouped together as a procedure, to perform a task. Method's are given a name and bound to a specific object. Methods determine the object's behavior.", <$format, ["p", [], [], 'do_p]>, "Methods have a specific structure to them. The number of arguments they will accept is defined at the beginning of the method, followed by the definition all of the variables used within the method. Subsequent lines compose the actual method (See ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Defining Methods"], 'do_link]>, " for more information on method structure).", <$format, ["p", [], [], 'do_p]>, "When ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_oop"]], ["descendants"], 'do_link]>], 'do_i]>, " of an object wish to change their behavior, they may define their own methods, or ", <$format, ["i", [], ["override"], 'do_i]>, " a method defined on an ", <$format, ["i", [], ["ancestor"], 'do_i]>, ". A method is overriden by simply naming it the same as an existing method on an ancestor of the object. When a method is called, the interpreter looks for it first on the object, then on the object's ancestors. If this occurs, it is possible for a method overriding another to stop executing and pass back to the method on its ancestor, and then resume executing when the overriden method completes executing.", <$format, ["p", [], [], 'do_p]>, "It is possible for a method to disallow descendants to override a method, see ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Defining Methods"], 'do_link]>, "."], #[['this, $help_coldc_objs_methods]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_objs_methods];
var $help_node nolist = 0;


new object $help_coldc_objs_vars: $help_coldc_objs;

var $root manager = $help_coldc_objs_vars;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853696071;
var $has_name name = ['prop, "Variables", "Variables"];
var $help_node links = #[["encapsulation", $help_coldc_oop]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "In ColdC there are two types of variables, ", <$format, ["i", [], ["local variables"], 'do_i]>, " and ", <$format, ["i", [], ["object variables"], 'do_i]>, ". An object variable is defined on the object, and can be accessed by any method defined on the same object. Object variables exist outside of the scope of methods. Local variables are defined within a method, with their scope being limited to that method. Object variables will always exist until they are explicitly removed. Local variables only exist while the method defining them is executing. ", <$format, ["p", [], [], 'do_p]>, "If a variable is used within the body of a method, but it is not defined as an argument or a local variable (at the top of the method), it is assumed to be an object variable. When the method is executed the interpreter looks on the object for the variable. If the interpreter cannot find the variable on the object, the error ", <$format, ["tt", [], ["~varnf"], 'do_tt]>, " is thrown. ", <$format, ["p", [], [], 'do_p]>, "It is important to remember that object variables may only be accessed by methods ", <$format, ["i", [], ["defined by same object defining the variable"], 'do_i]>, ". No other method may reference that variable. For instance, assume two objects exist as ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, " and ", <$format, ["tt", [], ["$obj_b"], 'do_tt]>, ", where ", <$format, ["tt", [], ["$obj_b"], 'do_tt]>, " is a child of ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, ". ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, " defines the variable ", <$format, ["tt", [], ["text"], 'do_tt]>, " and the methods ", <$format, ["tt", [], ["set_text"], 'do_tt]>, " and ", <$format, ["tt", [], ["get_text"], 'do_tt]>, ": ", <$format, ["dfn", [], [<$format, ["quote", [], ["\nobject $obj_a: $root;\nvar $obj_a text;\n\npublic method $obj_a.get_text {\n    return text;\n};\n\npublic method $obj_a.set_text {\n    arg new_text;\n\n    text = new_text;\n};"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Calling ", <$format, ["tt", [], ["$obj_a.set_text(\"text\")"], 'do_tt]>, " will set $obj_a's instance of the object variable ", <$format, ["tt", [], ["text"], 'do_tt]>, " to \"text\". ", <$format, ["tt", [], ["$obj_b"], 'do_tt]>, " does inherit the ability to use and write to it's own instance of ", <$format, ["tt", [], ["text"], 'do_tt]>, " (using methods defined on ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, "), but it does not inherit values assigned to the same object variable on it's ancestors. For instance, calling ", <$format, ["tt", [], ["$obj_b.get_text()"], 'do_tt]>, " will currently return ", <$format, ["tt", [], ["0"], 'do_tt]>, " (the default unset value), as it's instance of ", <$format, ["tt", [], ["text"], 'do_tt]>, " has not yet been defined, even though ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, "'s instance of ", <$format, ["tt", [], ["text"], 'do_tt]>, " has been defined. This is called ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_oop"]], ["encapsulation"], 'do_link]>], 'do_i]>, ". ", <$format, ["p", [], [], 'do_p]>, "Calling ", <$format, ["tt", [], ["$obj_b.set_text(\"more\")"], 'do_tt]>, " would set ", <$format, ["tt", [], ["$obj_b"], 'do_tt]>, "'s instance of ", <$format, ["tt", [], ["text"], 'do_tt]>, " to \"more\". If, following this, ", <$format, ["tt", [], ["$obj_b"], 'do_tt]>, " were to override the method ", <$format, ["tt", [], ["get_text"], 'do_tt]>, " defined on ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, " as: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\npublic method $obj_b.get_text {\n    return \"more text: \" + text;\n};"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Calling ", <$format, ["tt", [], ["$obj_b.get_text()"], 'do_tt]>, " would cause the error ", <$format, ["tt", [], ["~varnf"], 'do_tt]>, " to be thrown, rather than having \"more text: more\" returned. This is because the object variable ", <$format, ["tt", [], ["text"], 'do_tt]>, " is not defined by $obj_b (where the new ", <$format, ["tt", [], ["get_text"], 'do_tt]>, " is defined), even though it has it's own instance from $obj_a. ", <$format, ["p", [], [], 'do_p]>, "Another way to look at this is from a ", <$format, ["i", [], ["C++"], 'do_i]>, " perspective. All object variables in ColdC are equivalent to being private object variables in C++."], #[['this, $help_coldc_objs_vars]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_objs_vars];
var $help_node nolist = 0;


new object $help_coldc_objs_special: $help_coldc_objs;

var $root manager = $help_coldc_objs_special;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853696071;
var $has_name name = ['prop, "Special Object Status", "Special Object Status"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "There are always two objects which exists within a ColdC database. The first object is ", <$format, ["tt", [], ["$root"], 'do_tt]>, " (", <$format, ["tt", [], ["#1"], 'do_tt]>, "). The root object has no parents, and is the base for all other objects. This is a requirement in order to allow for a secure database to be created. ", <$format, ["p", [], [], 'do_p]>, "The second object is ", <$format, ["tt", [], ["$sys"], 'do_tt]>, " (", <$format, ["tt", [], ["#0"], 'do_tt]>, "). The system object is the only object the driver directly calls methods on, with without previously setting up with the driver (i.e. connections). These methods include ", <$format, ["tt", [], ["$sys.startup()"], 'do_tt]>, ", ", <$format, ["tt", [], ["$sys.heartbeat()"], 'do_tt]>, " and ", <$format, ["tt", [], ["$sys.signal()"], 'do_tt]>, ". ", <$format, ["p", [], [], 'do_p]>, "The root and system objects are automatically created by the database compiler."], #[['this, $help_coldc_objs_special]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_objs_special];
var $help_node nolist = 0;


new object $help_coldc_lang: $help_coldc;

var $root manager = $help_coldc_lang;
var $help_node holder = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853707985;
var $has_name name = ['prop, "Language Structure", "Language Structure"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[['this, $help_coldc_lang]]]>;
var $root inited = 1;
var $root child_index = 2;
var $root managed = [$help_coldc_lang];
var $help_node nolist = 0;


new object $help_coldc_tokens: $help_coldc_lang;

var $root manager = $help_coldc_tokens;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698065;
var $has_name name = ['prop, "Tokens", "Tokens"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Tokens are the base elements of ColdC. Tokens are simply abstract groupings of text imbued with a specific meaning. There are many different types of tokens ranging from single characters to long words. The following characters and pairs of characters are tokens in ColdC: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\n{   }   [   ]   #[  ]   `[  ]   (   )   (|  |)  (>  <)\n,   ;   =   +=  -=  *=  /=  !   -   +   *   /   %   ..\n==  !=  >   >=  <   <=  .   ||  &&  ?   |   @   --  ++"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "The above tokens are used as operators and punctuation in ColdC expressions and statements. ", <$format, ["subj", [["level", "3"]], ["Identifier"], 'do_subj]>, " ", <$format, ["p", [], [], 'do_p]>, "An ", <$format, ["i", [], ["identifier"], 'do_i]>, " is another type of ColdC token which is a sequence of alphabetic and numeric characters or underlines not beginning with a number. Identifiers in ColdC are case-sensitive, so the identifiers ", <$format, ["tt", [], ["Car"], 'do_tt]>, " and ", <$format, ["tt", [], ["car"], 'do_tt]>, " are not equivalent. The following are all valid identifiers: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\nwe_3_kings\nobj\na"], 'do_quote]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Without additional tokens, identifiers usually represent variables. However, certain identifiers have special meanings to the parser. These reserved words are used in writing certain kinds of statements and expressions. They are: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\nvar, if, else, while, for, switch, case, default,\nbreak, continue, return, catch, any, with handler,\npass, to, in"], 'do_quote]>], 'do_dfn]>], #[['this, $help_coldc_tokens]]]>;
var $root inited = 1;
var $root child_index = 1;
var $root managed = [$help_coldc_tokens];
var $help_node nolist = 0;


new object $help_coldc_types: $help_coldc_lang;

var $root manager = $help_coldc_types;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Data Types", "Data Types"];
var $help_node links = #[["expression", $help_coldc_expr], ["Integer", $help_coldc_types_ints], ["Float", $help_coldc_types_floats], ["String", $help_coldc_types_strings], ["Buffer", $help_coldc_types_buffers], ["Symbol", $help_coldc_types_symbols], ["List", $help_coldc_types_lists], ["Object Number", $help_coldc_types_dbref], ["Object Name", $help_coldc_types_dbref], ["Dictionary", $help_coldc_types_dicts], ["Error Code", $help_coldc_types_errors], ["Frob", $help_coldc_types_frobs], ["type()", $help_func_type]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "All ColdC data has a type and a logical truth value it will return when evaluated as an ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_expr"]], ["expression"], 'do_link]>], 'do_i]>, ". The following is a list of ColdC data types along with their names and literal representation in ColdC: ", <$format, ["dfn", [], [<$format, ["table", [["cols", "25%,25%,40%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["Type"], 'do_b]>], 'do_td]>, <$format, ["td", [], [<$format, ["b", [], ["Name"], 'do_b]>], 'do_td]>, <$format, ["td", [], [<$format, ["b", [], ["Representation"], 'do_b]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_ints"]], ["Integer"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'integer"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["42"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_floats"]], ["Float"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'float"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["1.0"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_strings"]], ["String"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'string"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["\"This String\""], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_buffers"]], ["Buffer"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'buffer"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["`[]"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_symbols"]], ["Symbol"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'symbol"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["'identifier"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_lists"]], ["List"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'list"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["[1, 2, 3, 4]"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_dbref"]], ["Object Number"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'objnum"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["#1234"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_dbref"]], ["Object Name"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'objname"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["$identifier"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_dicts"]], ["Dictionary"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'dictionary"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["#[[\"key\", $value]]"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_errors"]], ["Error Code"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'error"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["~identifier"], 'do_tt]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_coldc_types_frobs"]], ["Frob"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["'frob"], 'do_td]>, <$format, ["td", [], [<$format, ["tt", [], ["<object, value>"], 'do_tt]>], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The type of data being manipulated can be determined using the ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_type"]], ["type()"], 'do_link]>], 'do_tt]>, " function."], #[['this, $help_coldc_types]]]>;
var $root inited = 1;
var $root child_index = 11;
var $help_node nolist = 1;
var $root managed = [$help_coldc_types];


new object $help_coldc_types_ints: $help_coldc_types;

var $root manager = $help_coldc_types_ints;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Integer|Number", "Integer|Number"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "An ", <$format, ["i", [], ["integer"], 'do_i]>, " is a rational number (in mathematical terms). Integers can reliably be from 2147483647 to -2147483648 (unless the driver has been compiled with BIG_NUMBERS, in which case they are larger). An integer is logically true if it is not zero (negative numbers are logically true). Integers are denoted in ColdC with a series of digits, optionally preceded with a plus (", <$format, ["tt", [], ["+"], 'do_tt]>, ") or minus (", <$format, ["tt", [], ["-"], 'do_tt]>, ") sign."], #[['this, $help_coldc_types_ints]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_ints];
var $help_node nolist = 0;


new object $help_coldc_types_floats: $help_coldc_types;

var $root manager = $help_coldc_types_floats;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Float", "Float"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A ", <$format, ["i", [], ["float"], 'do_i]>, " is a real number (in mathematical terms). A float is logically true if it is not zero. Floats are denoted in ColdC with two numbers seperated by a period and optionally preceded with a plus (", <$format, ["tt", [], ["+"], 'do_tt]>, ") or minus (", <$format, ["tt", [], ["-"], 'do_tt]>, ") sign. If the float has small enough precision it may be formatted in scientific notation. Both forms are acceptable. For instance, the two floats are equivalent: ", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["0.000000001", <$format, ["br", [], [], 'do_br]>, "1e-09"], 'do_dfn]>], #[['this, $help_coldc_types_floats]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_floats];
var $help_node nolist = 0;


new object $help_coldc_types_strings: $help_coldc_types;

var $root manager = $help_coldc_types_strings;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "String", "String"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A ", <$format, ["i", [], ["string"], 'do_i]>, " is a sequence of printable characters. A string is logically true if it is not empty. A string is denoted in ColdC by enclosing the printable characters within double quote characters (", <$format, ["tt", [], ["\""], 'do_tt]>, "). To include a double quote inside a string precede it with a backslash. Any other occurance of a backslash in a string has no special meaning. The following are some examples of strings: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\n\"foo\"\n\"\\\"foo\\\" is a metasyntactic variable.\"\n\"The backslash (`\') is a much-abused character in many languages.\""], 'do_quote]>], 'do_dfn]>], #[['this, $help_coldc_types_strings]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_strings];
var $help_node nolist = 0;


new object $help_coldc_types_symbols: $help_coldc_types;

var $root manager = $help_coldc_types_symbols;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Symbol", "Symbol"];
var $help_node links = #[["ColdC identifier", $help_coldc_tokens]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A ", <$format, ["i", [], ["symbol"], 'do_i]>, " is similar to a string, but it has been abstracted into a ", <$format, ["link", [["node", "$help_coldc_tokens"]], ["ColdC identifier"], 'do_link]>, ". This makes comparisons between symbols much faster than with strings, as when comparing a string each character in the string must be compared, but when comparing a symbol only one comparison occurs. ", <$format, ["p", [], [], 'do_p]>, "Symbols are denoted in ColdC by preceding the identifier with an apostrophe (", <$format, ["tt", [], ["'"], 'do_tt]>, "). Symbols are not terminated with an apostrophe. Symbols are always logically true."], #[['this, $help_coldc_types_symbols]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_symbols];
var $help_node nolist = 0;


new object $help_coldc_types_lists: $help_coldc_types;

var $root manager = $help_coldc_types_lists;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "List", "List"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A ", <$format, ["i", [], ["list"], 'do_i]>, " is an ordered grouping of data. The data contained within a list can be of any type, and does not have to be the same type througout the list. Lists are useful for grouping different data elements together. A list is logically true if it contains one or more elements, and is logically false if it is empty. A list is constructed by enclosing a comma-separated series of data elements within square brackets. For example both of the following are both valid lists: ", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["[1, 2, 3] ", <$format, ["br", [], [], 'do_br]>, "[1, [\"foo\", 'bar], $sys]"], 'do_dfn]>], #[['this, $help_coldc_types_lists]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_lists];
var $help_node nolist = 0;


new object $help_coldc_types_dbref: $help_coldc_types;

var $root manager = $help_coldc_types_dbref;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Object Number|objnum|Object Name|objname|dbref", "Object Number|objnum|Object Name|objname|dbref"];
var $help_node links = #[["Referencing Objects", $help_coldc_objs_ref]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["i", [], ["Object numbers"], 'do_i]>, " and ", <$format, ["i", [], ["object names"], 'do_i]>, " are explained in detail in the section ", <$format, ["link", [["node", "$help_coldc_objs_ref"]], ["Referencing Objects"], 'do_link]>, ". Object numbers and names are always logically true."], #[['this, $help_coldc_types_dbref]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_dbref];
var $help_node nolist = 0;


new object $help_coldc_types_dicts: $help_coldc_types;

var $root manager = $help_coldc_types_dicts;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Dictionary", "Dictionary"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A ", <$format, ["i", [], ["dictionary"], 'do_i]>, " is a collection of data associations, each of which has a key and a value. Dictionaries are similar to lists, however, lookup in a dictionary is with the key (returning the value), rather than with the location in the list. Dictionaries generally take up more storage space in memory than lists, and are slightly slower to add to and remove from than lists, but searching for items in dictionaries is much faster than searching for items in a list. ", <$format, ["p", [], [], 'do_p]>, "Dictionaries are denoted by a list of two-element lists, preceded with a hash mark (", <$format, ["tt", [], ["#"], 'do_tt]>, "). Each of the two-element lists is an association, where the first element is the key and the second element is the value. Dictionaries are logically true unless empty. The following are all valid dictionaries: ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["#[[\"foo\", 3], ['bar, 'baz]] ", <$format, ["br", [], [], 'do_br]>, "#[[\"something\", 'blue], [\"one\", 1], [\"two\", 2]]"], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "When evaluating the key for the value in the dictionary is indexed, rather than the position as in a list, such as: ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["dict=#[[\"foo\", 3], ['bar, 'baz]]; ", <$format, ["br", [], [], 'do_br]>, "dict['bar]; ", <$format, ["br", [], [], 'do_br]>, "=> 'baz"], 'do_dfn]>], #[['this, $help_coldc_types_dicts]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_dicts];
var $help_node nolist = 0;


new object $help_coldc_types_errors: $help_coldc_types;

var $root manager = $help_coldc_types_errors;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Error Codes|errors", "Error Codes|errors"];
var $help_node links = #[["Errors", $help_coldc_errors]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "An ", <$format, ["i", [], ["error code"], 'do_i]>, " identifies an error. Both the ColdC interpreter and ColdC methods use error codes to identify types of errors when they occur. See section ", <$format, ["link", [["node", "$help_coldc_errors"]], ["Errors"], 'do_link]>, " for information about how errors in ColdC are handled. Errors are denoted in ColdC by preceding an identifier with a tilde (", <$format, ["tt", [], ["~"], 'do_tt]>, "). Error codes are always logically false."], #[['this, $help_coldc_types_errors]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_errors];
var $help_node nolist = 0;


new object $help_coldc_types_frobs: $help_coldc_types;

var $root manager = $help_coldc_types_frobs;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Frob", "Frob"];
var $help_node links = #[["method-call", $help_coldc_mcall], ["Defining Methods", $help_coldc_methods]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["i", [], ["Frobs"], 'do_i]>, " are an advanced data type in ColdC. They consist of a ", <$format, ["i", [], ["class"], 'do_i]>, " (the controlling object) and a ", <$format, ["i", [], ["representation"], 'do_i]>, " (a list or dictionary). Frobs are useful for grouping, abstracting and encapsulating a set of similar data by associating it with a handler object. Frobs are constructed by enclosing the class and representation within a less-than sign (", <$format, ["tt", [], ["<"], 'do_tt]>, ") and a greater-than sign (", <$format, ["tt", [], [">"], 'do_tt]>, "), seperated by a comma. All of the following are valid frobs:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["<$thing_frob, #[['desc, \"worthless\"], ['name, \"coin\"]]> ", <$format, ["br", [], [], 'do_br]>, "<$coins, [923]> ", <$format, ["br", [], [], 'do_br]>, "<#73, [1, 2]>"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The usefullness of a frob becomes apparent when used as the recipient in a ", <$format, ["link", [["node", "$help_coldc_mcall"]], ["method-call"], 'do_link]>, " expression. In this instance the ", <$format, ["i", [], ["frob class"], 'do_i]>, " becomes the recipient and the ", <$format, ["i", [], ["frob value"], 'do_i]>, " becomes the first argument sent to the method. For instance, the following two method calls are equivalent:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["$list.reverse([1, 2, 3], 'do_this) ", <$format, ["br", [], [], 'do_br]>, "(<$list, [1, 2, 3]>).reverse('do_this)"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Because of the difference in how a frob method is called, it is possible to define a method as a frob-only method. If a method is defined as a frob-only method it is ", <$format, ["i", [], ["only"], 'do_i]>, " called when called by a frob. Calling it in the standard syntax would not retrieve the frob-only method, but would instead look for the same method further up the ancestor heirarchy. For more information see ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Defining Methods"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "Frobs are always logically true."], #[['this, $help_coldc_types_frobs]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_frobs];
var $help_node nolist = 0;


new object $help_coldc_types_buffers: $help_coldc_types;

var $root manager = $help_coldc_types_buffers;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853698066;
var $has_name name = ['prop, "Buffer", "Buffer"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A ", <$format, ["i", [], ["buffer"], 'do_i]>, " is an array of integers which are interpreted to unsigned eight-bit values. Keep this in mind, as the range of an integer in a buffer is only 0 through 255, any other number will be randomly cast to an eight bit unsigned value. ", <$format, ["p", [], [], 'do_p]>, "Buffers are intended for handling character values outside of the normal printable range used by ColdC strings. A buffer is constructed by prefixing a list of integers with an accent mark (", <$format, ["tt", [], ["`"], 'do_tt]>, "), where each integer is the decimal value of the respective character. Buffers are logically true if not empty. The following buffer and string are equivalent: ", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["`[98, 117, 102, 102, 101, 114]", <$format, ["br", [], [], 'do_br]>, "\"buffer\""], 'do_dfn]>], #[['this, $help_coldc_types_buffers]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_types_buffers];
var $help_node nolist = 0;


new object $help_coldc_expr: $help_coldc_lang;

var $root manager = $help_coldc_expr;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853826333;
var $has_name name = ['prop, "Expressions", "Expressions"];
var $help_node links = #[["tokens", $help_coldc_tokens], ["operators", $help_coldc_ops], ["Data", $help_coldc_data], ["Variable", $help_coldc_vars], ["Function Call", $help_coldc_fcall], ["Method Call", $help_coldc_mcall], ["Error Handling", $help_coldc_err_expr], ["Looping", $help_coldc_loop_expr]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Expressions are ColdC ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_tokens"]], ["tokens"], 'do_link]>], 'do_i]>, " and ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_expr_ops"]], ["operators"], 'do_link]>], 'do_i]>, " which--when evaluated--perform their defined behavior and take on a value after completion (also known as the ", <$format, ["i", [], ["return value"], 'do_i]>, "). If they evaluated without error, the return value is a standard ColdC data type. If an error occured, the return value is an error data type, and execution of the method is halted. ", <$format, ["np", [], [], 'do_np]>, "There are many different types of expressions:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_data"]], ["Data"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_ops"]], ["Operators"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_vars"]], ["Variable"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_fcall"]], ["Function Call"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_mcall"]], ["Method Call"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_err_expr"]], ["Error Handling"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_loop_expr"]], ["Looping"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_expr]]]>;
var $root inited = 1;
var $root child_index = 8;
var $root managed = [$help_coldc_expr];
var $help_node nolist = 0;


new object $help_coldc_data: $help_coldc_expr;

var $root manager = $help_coldc_data;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853827083;
var $has_name name = ['prop, "Data", "Data"];
var $help_node links = #[["expression", $help_coldc_expr], ["Data Types", $help_coldc_types]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "All ColdC data has a type and a logical truth value it will take on when evaluated as an ", <$format, ["link", [["node", "$help_coldc_expr"]], ["expression"], 'do_link]>, ". Each data type is explained in the section ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_types"]], ["Data Types"], 'do_link]>], 'do_i]>, "."], #[['this, $help_coldc_data]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_data];
var $help_node nolist = 0;


new object $help_coldc_ops: $help_coldc_expr;

var $root manager = $help_coldc_ops;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853827084;
var $has_name name = ['prop, "Operators", "Operators"];
var $help_node links = #[["Operator Precedence", $help_coldc_prec], ["Index Operators", $help_coldc_index], ["Arithmetic Operators", $help_coldc_arith], ["Assignment Operators", $help_coldc_assign], ["Logical Operators", $help_coldc_logical], ["Conditional Operators", $help_coldc_cond], ["List Splice Operator", $help_coldc_splice]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Operators are tokens used to perform simple operations on expression values, such as adding two values together. ", <$format, ["tt", [], ["ColdC"], 'do_tt]>, " provides a variety of operators to perform arithmetic and logical operations on data. Most of these operators fall into two categories: ", <$format, ["i", [], ["unary operators"], 'do_i]>, " and ", <$format, ["i", [], ["binary operators"], 'do_i]>, ". ", <$format, ["np", [], [], 'do_np]>, <$format, ["i", [], ["Unary operators"], 'do_i]>, " act on a single expression value. In ", <$format, ["tt", [], ["ColdC"], 'do_tt]>, ", all unary operators are single characters which precede expressions. For example, ", <$format, ["tt", [], ["!str"], 'do_tt]>, " is the logical negation of the variable ", <$format, ["tt", [], ["str"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, <$format, ["i", [], ["Binary operators"], 'do_i]>, " act on two expression values. For example, ", <$format, ["tt", [], ["a + b"], 'do_tt]>, " is the sum of the variables ", <$format, ["tt", [], ["a"], 'do_tt]>, " and ", <$format, ["tt", [], ["b"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "Some operators are neither unary nor binary. More information on these operators can be found in each sub section:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_prec"]], ["Operator Precedence"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_index"]], ["Index Operators"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_arith"]], ["Arithmetic Operators"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_assign"]], ["Assignment Operators"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_logical"]], ["Logical Operators"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_cond"]], ["Conditional Operators"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_splice"]], ["List Splice Operator"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_ops]]]>;
var $root inited = 1;
var $root child_index = 7;
var $root managed = [$help_coldc_ops];
var $help_node nolist = 0;


new object $help_coldc_prec: $help_coldc_ops;

var $root manager = $help_coldc_prec;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853827084;
var $has_name name = ['prop, "Operator Precedence", "Operator Precedence"];
var $help_node links = #[["Logical Operators", $help_coldc_logical]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "When the interpreter executes an expression it evaluates each operator it in a certain order. It is easy to write an expression which has an unclear order of evaluation. For instance, the expression ", <$format, ["tt", [], ["A - B + C"], 'do_tt]>, " could be parsed as ", <$format, ["tt", [], ["A - B"], 'do_tt]>, " followed by the result plus ", <$format, ["tt", [], ["C"], 'do_tt]>, " or as ", <$format, ["tt", [], ["A"], 'do_tt]>, " minus ", <$format, ["tt", [], ["B + C"], 'do_tt]>, ". To resolve these ambiguities, each operator has two properties when interpreted: ", <$format, ["i", [], ["precedence"], 'do_i]>, " and ", <$format, ["i", [], ["association"], 'do_i]>, ". ", <$format, ["np", [], [], 'do_np]>, <$format, ["i", [], ["Precedence"], 'do_i]>, " determines whether an operator is more important than another operator; for instance, ", <$format, ["tt", [], ["A + B * C"], 'do_tt]>, " is equivalent to ", <$format, ["tt", [], ["A + (B * C)"], 'do_tt]>, " because multiplication has higher precedence (is more important) than addition. ", <$format, ["np", [], [], 'do_np]>, <$format, ["i", [], ["Association"], 'do_i]>, " determines whether operators at the same precedence level associate left to right or right to left; ", <$format, ["tt", [], ["A - B - C"], 'do_tt]>, " is equivalent to ", <$format, ["tt", [], ["(A - B) - C"], 'do_tt]>, " because subtraction associates left to right. ", <$format, ["np", [], [], 'do_np]>, "Here is a list of operators grouped by precedence, in order from highest to lowest: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\n[]\n.\n-- ++\n! - (unary)\n* / %\n+ - (binary)\n== != > >= < <=\nin\n&&\n||\n?:\n= += -= /= *= ?="], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "All operators associate from left to right except the ", <$format, ["link", [["node", "$help_coldc_logical"]], ["Logical Operators"], 'do_link]>, " (", <$format, ["tt", [], ["&&"], 'do_tt]>, ", ", <$format, ["tt", [], ["||"], 'do_tt]>, ", and ", <$format, ["tt", [], ["?|"], 'do_tt]>, "), which associate from right to left. Parentheses may be used to group expressions and clarify evaluation."], #[['this, $help_coldc_prec]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_prec];
var $help_node nolist = 0;


new object $help_coldc_index: $help_coldc_ops;

var $root manager = $help_coldc_index;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854138336;
var $has_name name = ['prop, "Index Operators", "Index Operators"];
var $help_node links = #[["find", $help_coldc_find]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Indexing involves lookup in either a string, list, buffer and in some instances a dictionary. Depending upon the specific operator used indexing can return either the position of a desired element, or it can return the element at the specified position. There are two indexing operators, each performing one of these roles:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["[]", <$format, ["br", [], [], 'do_br]>, "in"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The binary operator index-lookup (", <$format, ["tt", [], ["in"], 'do_tt]>, ") is used to find the position of an element. It may only be used with strings, lists and buffers. When used this operator will return an integer representing the position within the right side data where the left side specified element exists. If the specified element does not exist, a zero (", <$format, ["tt", [], ["0"], 'do_tt]>, ") is returned. Indexing is case-insensitive, when using strings. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["\"C\" in \"abcdefg\"", <$format, ["br", [], [], 'do_br]>, "=> 3"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The expression ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_coldc_find"]], ["find"], 'do_link]>], 'do_tt]>, " and the functions ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_stridx"]], ["stridx()"], 'do_link]>], 'do_tt]>, ", ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_listidx"]], ["listidx()"], 'do_link]>], 'do_tt]>, " and ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_bufidx"]], ["bufidx()"], 'do_link]>], 'do_tt]>, " may also be used in finding the positional index of an element. ", <$format, ["np", [], [], 'do_np]>, "The index-retrieve operator ([]) is used to retrieve an element found within the data. It may be used with strings, lists, buffers and dictionaries. It is a binary operator, although its syntax is not as standard as others:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["i", [], ["data expression"], 'do_i]>, "[", <$format, ["i", [], ["data expression"], 'do_i]>, "]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The right data expression is used as the key to lookup within the left data expression. In all but the dictionary the right data expression must result in an integer, which represents the position in the right data expression to retrieve from. With a dictionary the right data expression may be any data type (see ", <$format, ["link", [["node", "$help_coldc_types_dicts"]], ["Dictionaries"], 'do_link]>, ")."], #[['this, $help_coldc_index]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_index];
var $help_node nolist = 0;


new object $help_coldc_arith: $help_coldc_ops;

var $root manager = $help_coldc_arith;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853827084;
var $has_name name = ['prop, "Arithmetic Operators", "Arithmetic Operators"];
var $help_node links = #[["Increment / Decrement Operators", $help_coldc_incdec], ["Non-Numeric Use", $help_coldc_non_arith]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdC provides several operators for performing arithmetic operations. These operators apply primarily to integers and floats, but some of them may be used with non-integer data for easier formatting and manipulation. If any arithmetic operator is used with inappropriate data the error ", <$format, ["tt", [], ["~type"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "If both sides of a binary arithmetic expression are integers, the result will always be an integer, even if the result would have floating precision. If one side of the expression is a float, the result will always be a float. For instance, ", <$format, ["tt", [], ["3 / 2"], 'do_tt]>, " (both integers) would result in ", <$format, ["tt", [], ["1"], 'do_tt]>, ", whereas ", <$format, ["tt", [], ["3 / 2.0"], 'do_tt]>, " would result in ", <$format, ["tt", [], ["1.500000"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "The arithmetic operators are: ", <$format, ["dfn", [], [<$format, ["table", [["cols", "10%,20%,15%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["ignored"], 'do_td]>, <$format, ["td", [], ["(unary)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["-"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["negate"], 'do_td]>, <$format, ["td", [], ["(unary)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["addition"], 'do_td]>, <$format, ["td", [], ["(binary)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["-"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["subtraction"], 'do_td]>, <$format, ["td", [], ["(binary)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["*"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["multiply"], 'do_td]>, <$format, ["td", [], ["(binary)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["/"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["divide"], 'do_td]>, <$format, ["td", [], ["(binary)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["%"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["modulo"], 'do_td]>, <$format, ["td", [], ["(binary)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["++"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["increment"], 'do_td]>, <$format, ["td", [], ["(unary)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["--"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["decrement"], 'do_td]>, <$format, ["td", [], ["(unary)"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The unary ", <$format, ["tt", [], ["-"], 'do_tt]>, " operator negates the numeric value (reverses its positive/negative value). The unary ", <$format, ["tt", [], ["+"], 'do_tt]>, " operator has no effect on its argument, and is provided simply for completeness. The binary operators ", <$format, ["tt", [], ["+"], 'do_tt]>, " and ", <$format, ["tt", [], ["-"], 'do_tt]>, " add and subtract their arguments. ", <$format, ["np", [], [], 'do_np]>, "The binary multiplication operator ", <$format, ["tt", [], ["*"], 'do_tt]>, " multiplies the left argument by the right argument. The binary division operator ", <$format, ["tt", [], ["/"], 'do_tt]>, " divides the left argument by the right argument, returning the whole result. The binary modulus operator ", <$format, ["tt", [], ["%"], 'do_tt]>, " divides the left argument by the right argument and returns the remainder result. ", <$format, ["np", [], [], 'do_np]>, "The unary Increment and Decrement operators serve a dual function, and are explained further in their own section.", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_incdec"]], ["Increment / Decrement Operators"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_non_arith"]], ["Non-Numeric Use"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_arith]]]>;
var $root inited = 1;
var $root child_index = 2;
var $root managed = [$help_coldc_arith];
var $help_node nolist = 0;


new object $help_coldc_incdec: $help_coldc_arith;

var $root manager = $help_coldc_incdec;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854136779;
var $has_name name = ['prop, "Increment|Decrement", "Increment|Decrement"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The unary Increment (", <$format, ["tt", [], ["++"], 'do_tt]>, ") and Decrement (", <$format, ["tt", [], ["--"], 'do_tt]>, ") operators perform a dual purpose. They either add or subtract one from a numeric variable (respectively), assigning the result back to the variable. They must be used directly on a variable. All of the following are equivalent:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["i = i + 1", <$format, ["br", [], [], 'do_br]>, "i++", <$format, ["br", [], [], 'do_br]>, "i = i - 1", <$format, ["br", [], [], 'do_br]>, "i--"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The result returned from an increment or decrement expression will will depend upon what side of the variable it is placed. If the operator is on the left side of the variable, the value of the variable is modified before it is returned. If the operator is on the right side of the variable, the value of the variable is returned first and then the variable is incremented or decremented. ", <$format, ["np", [], [], 'do_np]>, "In the examples below assume ", <$format, ["tt", [], ["i"], 'do_tt]>, " is 10. Assuming this, in the first example ", <$format, ["tt", [], ["x"], 'do_tt]>, " is assigned the value ", <$format, ["tt", [], ["10"], 'do_tt]>, " where in the second example it is assigned the value ", <$format, ["tt", [], ["11"], 'do_tt]>, ".", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["x = i++", <$format, ["br", [], [], 'do_br]>, "x=++i"], 'do_tt]>], 'do_dfn]>], #[['this, $help_coldc_incdec]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_incdec];
var $help_node nolist = 0;


new object $help_coldc_non_arith: $help_coldc_arith;

var $root manager = $help_coldc_non_arith;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854136779;
var $has_name name = ['prop, "Non-Numeric Use", "Non-Numeric Use"];
var $help_node links = #[["Dual Role Assignment", $help_coldc_dual_assign]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The binary ", <$format, ["tt", [], ["+"], 'do_tt]>, " operator can also be applied to strings, lists and buffers. Using it in this way will cause it to concatenate the two values. For instance, the expression ", <$format, ["tt", [], ["(\"foo\" + \"bar\")"], 'do_tt]>, " would evaluate to ", <$format, ["tt", [], ["\"foobar\""], 'do_tt]>, ", and the expression ", <$format, ["tt", [], ["([\"foo\", \"bar\"] + [\"baz\"])"], 'do_tt]>, " would result in the list ", <$format, ["tt", [], ["[\"foo\", \"bar\", \"baz\"]"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "As long as both sides of the operator are the same data type (which is restricted to strings, lists and buffers) no error will be raised. If one side of the operator is a string (either side), and the other side is not a string, it will be converted to its literal representation and joined with the string. For example, the expression ", <$format, ["tt", [], ["(\"list: \" + [1, 2, 3])"], 'do_tt]>, " would evaluate to ", <$format, ["tt", [], ["\"list: [1, 2, 3]\""], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "The binary ", <$format, ["tt", [], ["*"], 'do_tt]>, " may be applied with a string on the left side and an integer on the right side. In this situation the left side string is duplicated by the number of times specified by the right side integer. Example: ", <$format, ["tt", [], ["(\"-\" * 5)"], 'do_tt]>, " would result in ", <$format, ["tt", [], ["\"-----\""], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, <$format, ["link", [["node", "$help_coldc_dual_assign"]], ["Dual Role Assignment"], 'do_link]>, " operators also behave in the same way, as is applicable. For instance, the dual role arithmetic operator ", <$format, ["tt", [], ["+="], 'do_tt]>, " would behave the same as the standard arithmetic operator ", <$format, ["tt", [], ["+"], 'do_tt]>, " when evaluating the addition expression."], #[['this, $help_coldc_non_arith]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_non_arith];
var $help_node nolist = 0;


new object $help_coldc_assign: $help_coldc_ops;

var $root manager = $help_coldc_assign;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853827084;
var $has_name name = ['prop, "Assignments", "Assignments"];
var $help_node links = #[["variable", $help_coldc_vars], ["Simple Assignments", $help_coldc_simple_assign], ["Scatter Assignments", $help_coldc_scatter_assign], ["Dual Role Assignments", $help_coldc_dual_assign], ["Default Assignments", $help_coldc_default_assign]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Data is stored in a ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_vars"]], ["variable"], 'do_link]>], 'do_i]>, " through an assignment. Assignments can either be ", <$format, ["i", [], ["Simple"], 'do_i]>, ", ", <$format, ["i", [], ["Scattered"], 'do_i]>, ", ", <$format, ["i", [], ["Dual Role"], 'do_i]>, " or ", <$format, ["i", [], ["Default"], 'do_i]>, ". Simple Assignments store the result of an expression to a single variable. A Scatter Assignment stores each element in the result of a list expression across multiple variables. Dual Role Assignments join another operator and the simple assignment operator into one for the purpose of simplicity and optimizing, such as ", <$format, ["tt", [], ["+="], 'do_tt]>, " which is both the the addition operator and the assignment operator. Default assignments only assign the value if the current value of the variable is false. More information can be found in each section:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_simple_assign"]], ["Simple Assignments"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_scatter_assign"]], ["Scatter Assignments"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_dual_assign"]], ["Dual Role Assignments"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_default_assign"]], ["Default Assignments"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_assign]]]>;
var $root inited = 1;
var $root child_index = 4;
var $root managed = [$help_coldc_assign];
var $help_node nolist = 0;


new object $help_coldc_simple_assign: $help_coldc_assign;

var $root manager = $help_coldc_simple_assign;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854128989;
var $has_name name = ['prop, "Simple", "Simple"];
var $help_node links = #[["set_var()", $help_func_set_var], ["Variables", $help_coldc_vars]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Both simple and scatter assignments use the the same equals sign ", <$format, ["tt", [], ["="], 'do_tt]>, " operator. A simple assignment stores the result of the expression on the right into the variable on the left, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["variable"], 'do_i]>, " = ", <$format, ["i", [], ["expression"], 'do_i]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_set_var"]], ["set_var()"], 'do_link]>], 'do_tt]>, " may also be used for the same purpose, but only on an object variable (see ", <$format, ["link", [["node", "$help_coldc_vars"]], ["Variables"], 'do_link]>, ")."], #[['this, $help_coldc_simple_assign]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_simple_assign];
var $help_node nolist = 0;


new object $help_coldc_scatter_assign: $help_coldc_assign;

var $root manager = $help_coldc_scatter_assign;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854129007;
var $has_name name = ['prop, "Scatter", "Scatter"];
var $help_node links = #[["List Splice", $help_coldc_splice]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "In a scatter assignment multiple variables are specified within a square brackets on the left, and each element from the list expression on the right is assigned to the respective variable on the left, with any remaining elements in the list being discarded. For example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["[var1, var2, var3] = [\"this\", [\"for\"], 1, 'that]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In this example ", <$format, ["tt", [], ["var1"], 'do_tt]>, " is assigned the string ", <$format, ["tt", [], ["\"this\""], 'do_tt]>, ", ", <$format, ["tt", [], ["var2"], 'do_tt]>, " is assigned the list ", <$format, ["tt", [], ["[\"for\"]"], 'do_tt]>, ", ", <$format, ["tt", [], ["var3"], 'do_tt]>, " is assigned the integer ", <$format, ["tt", [], ["1"], 'do_tt]>, " and the remaining symbol ", <$format, ["tt", [], ["'that"], 'do_tt]>, " is discarded. ", <$format, ["np", [], [], 'do_np]>, "The remaining elements may all be grouped in a new list which is stored in the last variable by using the ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_splice"]], ["List Splice"], 'do_link]>], 'do_i]>, " operator on the last variable in the scatter list, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["[var1, var2, @var3] = [\"this\", [\"for\"], 1, 'that]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In this example ", <$format, ["tt", [], ["var3"], 'do_tt]>, " would have the value ", <$format, ["tt", [], ["[1, 'that]"], 'do_tt]>, ". The List Splice operator may only be used this way on the last variable in the scatter list. ", <$format, ["np", [], [], 'do_np]>, "Scatter Assignments may also be nested, assuming the list expression is a nested list in the same order as the scatter list. For example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["[var1, [var2, @var3], var4] = [\"this\", [\"for\", 1, 2, 3], 'that]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In this example ", <$format, ["tt", [], ["var1"], 'do_tt]>, " is assigned ", <$format, ["tt", [], ["\"this\""], 'do_tt]>, ", ", <$format, ["tt", [], ["var2"], 'do_tt]>, " is assigned ", <$format, ["tt", [], ["\"for\""], 'do_tt]>, ", ", <$format, ["tt", [], ["var3"], 'do_tt]>, " is assigned the new list ", <$format, ["tt", [], ["[1, 2, 3]"], 'do_tt]>, " and ", <$format, ["tt", [], ["var4"], 'do_tt]>, " is assigned the remaining symbol ", <$format, ["tt", [], ["'that"], 'do_tt]>, "."], #[['this, $help_coldc_scatter_assign]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_scatter_assign];
var $help_node nolist = 0;


new object $help_coldc_dual_assign: $help_coldc_assign;

var $root manager = $help_coldc_dual_assign;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854129007;
var $has_name name = ['prop, "Dual", "Dual"];
var $help_node links = #[["Arithmetic Operator", $help_coldc_arith], ["Non-Arithmetic Behaviour", $help_coldc_non_arith]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Dual Role Assignment operators join an arithmetic operator and the simple assignment operator into one for the purpose of simplicity and optimization. The Dual Role Assignment operators are:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["+=", <$format, ["br", [], [], 'do_br]>, "-=", <$format, ["br", [], [], 'do_br]>, "*=", <$format, ["br", [], [], 'do_br]>, "/="], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "These operators must have a variable as the left argument. When used, the arithmetic expression is evaluated as normal, and the result is assigned back into the variable on the left. The following examples are equivalent:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["x = x + 5", <$format, ["br", [], [], 'do_br]>, "x += 5"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When evaluating the arithmetic expression the operator behaves the same as the equivalent ", <$format, ["link", [["node", "$help_coldc_arith"]], ["Arithmetic Operator"], 'do_link]>, ", including any ", <$format, ["link", [["node", "$help_coldc_non_arith"]], ["Non-Arithmetic Behaviour"], 'do_link]>, "."], #[['this, $help_coldc_dual_assign]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_dual_assign];
var $help_node nolist = 0;


new object $help_coldc_default_assign: $help_coldc_assign;

var $root manager = $help_coldc_default_assign;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 857847069;
var $root managed = [$help_coldc_default_assign];
var $has_name name = ['prop, "Default", "Default"];
var $help_node links = #[["Simple Assignment", $help_coldc_simple_assign], ["if-else Conditional Expression", $help_coldc_cond]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The default assignment is used to assign a value to a variable if the current value of the variable is logically false. The default assignment operator is:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["?="], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "And the syntax is:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["i", [], ["variable"], 'do_i]>, " ?= ", <$format, ["i", [], ["value expression"], 'do_i]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When executed the driver tests the logical value of ", <$format, ["i", [], ["variable"], 'do_i]>, ". If it is false, it assigns the result of ", <$format, ["i", [], ["value expression"], 'do_i]>, ", otherwise it is untouched. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["len ?= 79;"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Will assign ", <$format, ["i", [], ["79"], 'do_i]>, " to ", <$format, ["i", [], ["len"], 'do_i]>, " if it is false (for instance, if it is zero). This operator is equivalent to a combination of the ", <$format, ["link", [["node", "$help_coldc_simple_assign"]], ["Simple Assignment"], 'do_link]>, " and the ", <$format, ["link", [["node", "$help_coldc_cond"]], ["if-else Conditional Expression"], 'do_link]>, ":", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["len = len ? len : 79;"], 'do_dfn]>], #[['this, $help_coldc_default_assign]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_coldc_logical: $help_coldc_ops;

var $root manager = $help_coldc_logical;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853827084;
var $has_name name = ['prop, "Logical Operators", "Logical Operators"];
var $help_node links = #[["strcmp()", $help_func_strcmp]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["tt", [], ["ColdC"], 'do_tt]>, " provides a number of relational and logical operators. These operators are primarily useful for expressing conditions, since they return either true or false, represented by the integers ", <$format, ["tt", [], ["1"], 'do_tt]>, " and ", <$format, ["tt", [], ["0"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "The binary operators ", <$format, ["tt", [], ["=="], 'do_tt]>, " and ", <$format, ["tt", [], ["!="], 'do_tt]>, " test the left and right arguments for equality and inequality, respectively. The arguments are equal if each side has the same data type and contains the same value. Equality of strings is not case-sensitive, but equality of symbols is, so ", <$format, ["tt", [], ["(\"foo\" == \"fOo\")"], 'do_tt]>, " is true, but ", <$format, ["tt", [], ["('car == 'CAr)"], 'do_tt]>, " is false. Lists are equal if all of the elements in each list are equal and are in the same order. ", <$format, ["np", [], [], 'do_np]>, "The ", <$format, ["tt", [], ["<"], 'do_tt]>, ", ", <$format, ["tt", [], ["<="], 'do_tt]>, ", ", <$format, ["tt", [], [">="], 'do_tt]>, ", and ", <$format, ["tt", [], [">"], 'do_tt]>, " operators test whether their left-hand arguments are less than, less than or equal to, greater than or equal to, or greater than their right-hand arguments, respectively. Arguments to these operators must both be of the same type, and must be either numeric or a string. String comparison is not case-sensitive, so ", <$format, ["tt", [], ["(\"fooa\" < \"fooB\")"], 'do_tt]>, " is true, even though the ASCII value of ", <$format, ["tt", [], ["`a'"], 'do_tt]>, " is greater than that of ", <$format, ["tt", [], ["`B'"], 'do_tt]>, " (the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_strcmp"]], ["strcmp()"], 'do_link]>], 'do_tt]>, " may be used for a true lexical case-sensitive comparison of strings). ", <$format, ["np", [], [], 'do_np]>, "The unary ", <$format, ["tt", [], ["!"], 'do_tt]>, " operator tests whether its argument is false, thus acting as a logical ", <$format, ["i", [], ["NOT"], 'do_i]>, " operation."], #[['this, $help_coldc_logical]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_logical];
var $help_node nolist = 0;


new object $help_coldc_cond: $help_coldc_ops;

var $root manager = $help_coldc_cond;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 853827084;
var $has_name name = ['prop, "Conditional", "Conditional"];
var $help_node links = #[["critical expression", $help_coldc_err_expr], ["Conditional if-else Statement", $help_coldc_cond_ifelse]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["tt", [], ["||"], 'do_tt]>, " and ", <$format, ["tt", [], ["&&"], 'do_tt]>, " operators act as logical ", <$format, ["i", [], ["OR"], 'do_i]>, " and ", <$format, ["i", [], ["AND"], 'do_i]>, " operators, respectively. The expression ", <$format, ["tt", [], ["(this || that)"], 'do_tt]>, " is equivalent to ", <$format, ["i", [], ["this OR that"], 'do_i]>, ", where the return value of the expression is ", <$format, ["i", [], ["this"], 'do_i]>, " if ", <$format, ["i", [], ["this"], 'do_i]>, " is logically true. If ", <$format, ["i", [], ["this"], 'do_i]>, " is not logically true then the return value of the expression is ", <$format, ["i", [], ["that"], 'do_i]>, ". ", <$format, ["np", [], [], 'do_np]>, "The expression ", <$format, ["tt", [], ["(this && that)"], 'do_tt]>, " is equivalent to ", <$format, ["i", [], ["this AND that"], 'do_i]>, ", where the return value of the expression is logically true when both ", <$format, ["i", [], ["this"], 'do_i]>, " and ", <$format, ["i", [], ["that"], 'do_i]>, " are also logically true. If either ", <$format, ["i", [], ["this"], 'do_i]>, " or ", <$format, ["i", [], ["that"], 'do_i]>, " are not logically true then the return value is false. ", <$format, ["np", [], [], 'do_np]>, <$format, ["tt", [], ["ColdC"], 'do_tt]>, "'s conditional operators are ", <$format, ["i", [], ["short-circuit operators"], 'do_i]>, ", meaning that the right-hand argument is never evaluated if the left-hand argument is sufficient to determine the value of the expression. This is important if the right-hand argument has side-effects or could cause an error. For instance, because of this it is possible to have the following expression:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["(| dict[key] |) || throw(~nope, \"Nope, doesn't exist\");"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "With this expression if ", <$format, ["i", [], ["key"], 'do_i]>, " is in the dictionary ", <$format, ["i", [], ["dict"], 'do_i]>, " then the return value is the related value to ", <$format, ["i", [], ["key"], 'do_i]>, ". If it is not, the error ", <$format, ["tt", [], ["~keynf"], 'do_tt]>, " is thrown by the index operator (", <$format, ["tt", [], ["[]"], 'do_tt]>, "). However, the expression is a ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_err_expr"]], ["critical expression"], 'do_link]>], 'do_i]>, ". Because of this the left value becomes ", <$format, ["i", [], ["~keynf"], 'do_i]>, ", which is logically false, and the interpreter moves onto the throw function. ", <$format, ["np", [], [], 'do_np]>, "The ", <$format, ["tt", [], ["? :"], 'do_tt]>, " operator is a trinary operator, with the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["condition"], 'do_i]>, " ? ", <$format, ["i", [], ["true-expr"], 'do_i]>, " : ", <$format, ["i", [], ["false-expr"], 'do_i]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The result of this expression is the result of ", <$format, ["i", [], ["true-expr"], 'do_i]>, " if ", <$format, ["i", [], ["condition"], 'do_i]>, " is true, or the result of ", <$format, ["i", [], ["false-expr"], 'do_i]>, " if ", <$format, ["i", [], ["condition"], 'do_i]>, " is false. This is similar to the ", <$format, ["link", [["node", "$help_coldc_cond_ifelse"]], ["Conditional if-else Statement"], 'do_link]>, "."], #[['this, $help_coldc_cond]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_cond];
var $help_node nolist = 0;


new object $help_coldc_splice: $help_coldc_ops;

var $root manager = $help_coldc_splice;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058343;
var $has_name name = ['prop, "List Splice Operator", "List Splice Operator"];
var $help_node links = #[["listgraft()", $help_func_listgraft], ["Precedence", $help_coldc_prec]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Splicing is used to either expand a list or in scatter assignments and method calls to group remaining arguments into a list. The splice operator is an at sign (", <$format, ["tt", [], ["@"], 'do_tt]>, "). ", <$format, ["np", [], [], 'do_np]>, "Splice can be used to expand a list in three situations: within a method call, within a function call or within another list When expanding, elements within the list to be spliced are placed starting at the appropriate position within the spliced list. For example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["[1, @['a, 'b, 'c], 2, 3]", <$format, ["br", [], [], 'do_br]>, "[1, 'a, 'b, 'c, 2, 3]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Note: the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_listgraft"]], ["listgraft()"], 'do_link]>], 'do_tt]>, " behaves in the same manner. When using splice to expand a list as arguments to a function it looks similar:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["others = [1, \"this\"];", <$format, ["br", [], [], 'do_br]>, "$string.do_something(this, that, @others);"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When the method ", <$format, ["tt", [], ["do_something"], 'do_tt]>, " is called it would be called with four arguments, and the last two arguments would have a value of ", <$format, ["tt", [], ["1"], 'do_tt]>, " and ", <$format, ["tt", [], ["\"this\""], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "The splicing operator is always evaluated last, and is not listed in the operator precedence list (see section ", <$format, ["link", [["node", "$help_coldc_prec"]], ["Precedence"], 'do_link]>, "). Because of its restricted nature the splicing operator never causes ambiguity."], #[['this, $help_coldc_splice]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_splice];
var $help_node nolist = 0;


new object $help_coldc_vars: $help_coldc_expr;

var $root manager = $help_coldc_vars;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854057942;
var $has_name name = ['prop, "Variable Expression", "Variable Expression"];
var $help_node links = #[["Defining Methods", $help_coldc_methods], ["Objects and Variables", $help_coldc_objs_vars], ["assignment expression", $help_coldc_assign]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdC provides two kinds of variables, ", <$format, ["i", [], ["local variables"], 'do_i]>, " and ", <$format, ["i", [], ["object variables"], 'do_i]>, ". ", <$format, ["i", [], ["Local variables"], 'do_i]>, " are used within methods to temporarily store data. In order for a local variable to be used it must first be declared at the top of the method in a ", <$format, ["tt", [], ["var"], 'do_tt]>, " declaration (see section ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Defining Methods"], 'do_link]>, "). ", <$format, ["i", [], ["Object variables"], 'do_i]>, " are defined on an object, and can be used to store data for an indefinite period of time (at least until the object is destroyed). More information on Variables can be found in the section ", <$format, ["link", [["node", "$help_coldc_objs_vars"]], ["Objects and Variables"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "When a variable is evaluated as an expression, its value is that of its contents (the data stored in the variable name). Initially variables will contain the integer data value of zero (", <$format, ["tt", [], ["0"], 'do_tt]>, "). To set the contents of a variable, use the ", <$format, ["link", [["node", "$help_coldc_assign"]], ["assignment expression"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "The value of a local variable is specific to the currently executing method frame. When the method is invoked at another time all of the local variables begin again with the value of zero (", <$format, ["tt", [], ["0"], 'do_tt]>, "). ", <$format, ["np", [], [], 'do_np]>, "If the variable is a local variable, it must be declared as a local variable at the top of the method (see ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Defining Methods"], 'do_link]>, "). If it is not declared at the top of the method, the interpreter will assume it is an object variable. In the case that both a local variable and an object variable have the same name, the local variable will take precedence. ", <$format, ["np", [], [], 'do_np]>, "It is possible to indirectly access and set data on an object variable using the functions ", <$format, ["link", [["node", "$help_func_get_var"]], ["get_var()"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_func_set_var"]], ["set_var()"], 'do_link]>, ". Normally, an object variable is accessed and set just as if it were a local variable. These functions are useful for indirectly setting or accessing the variable, or for when there is a possible conflict with a local variable. If the variable is not declared in the method, the interpreter will always assume it is an object variable."], #[['this, $help_coldc_vars]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_vars];
var $help_node nolist = 0;


new object $help_coldc_fcall: $help_coldc_expr;

var $root manager = $help_coldc_fcall;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854057965;
var $has_name name = ['prop, "Function Call Expression", "Function Call Expression"];
var $help_node links = #[["Function Reference", $help_coldc_func]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Functions are driver-defined procedures which perform a certain action which ColdC is incapable of (such as opening a network connection), or which the driver can handle more efficiently. A function is called using the ", <$format, ["i", [], ["function call expression"], 'do_i]>, ", which has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["function"], 'do_i]>, "(", <$format, ["i", [], ["arg1"], 'do_i]>, ", ", <$format, ["i", [], ["arg2"], 'do_i]>, ", ", <$format, ["i", [], ["..."], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In this example ", <$format, ["i", [], ["function"], 'do_i]>, " is an identifier naming the function, and ", <$format, ["i", [], ["arg1"], 'do_i]>, ", ", <$format, ["i", [], ["arg2"], 'do_i]>, " are expressions. There are no limits to the amount of arguments a function can accept. However, even if there are no arguments the parentheses must be present. Arguments are evaluated from left to right. ", <$format, ["np", [], [], 'do_np]>, "As an example, the ", <$format, ["tt", [], ["pad()"], 'do_tt]>, " function pads a string argument with spaces to a certain length. When evaluated with the string \"foo\" and a length of six characters:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["pad(\"foo\", 6)", <$format, ["br", [], [], 'do_br]>, "=> \"foo \""], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "There are driver functions available for a variety of tasks. A comprehensive explanation of the available functions is available in the section ", <$format, ["link", [["node", "$help_coldc_func"]], ["Function Reference"], 'do_link]>, "."], #[['this, $help_coldc_fcall]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_fcall];
var $help_node nolist = 0;


new object $help_coldc_mcall: $help_coldc_expr;

var $root manager = $help_coldc_mcall;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854057972;
var $has_name name = ['prop, "Method Call Expression", "Method Call Expression"];
var $help_node links = #[["Defining Methods", $help_coldc_methods], ["Calling Overridden Methods", $help_coldc_mcall_over]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Methods defined on an object can be executed with the ", <$format, ["i", [], ["method-call expression"], 'do_i]>, ", which has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["receiver"], 'do_i]>, ".", <$format, ["i", [], ["method"], 'do_i]>, "(", <$format, ["i", [], ["arg1"], 'do_i]>, ", ", <$format, ["i", [], ["arg2"], 'do_i]>, ", ", <$format, ["i", [], ["..."], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In this example ", <$format, ["i", [], ["receiver"], 'do_i]>, " is the object where ", <$format, ["i", [], ["method"], 'do_i]>, " may be called, and ", <$format, ["i", [], ["arg1"], 'do_i]>, ", ", <$format, ["i", [], ["arg2"], 'do_i]>, " are expressions. There are is no limit to the number of arguments sent, although even if there are no arguments the parenthesis must exist. Arguments are evaluated from left to right. ", <$format, ["np", [], [], 'do_np]>, "The ", <$format, ["i", [], ["receiver"], 'do_i]>, " may be omitted, in which case it is assumed to be the current object. If ", <$format, ["i", [], ["receiver"], 'do_i]>, " does not exist in the database, the error ", <$format, ["tt", [], ["~objnf"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "Any ColdC Data (with the exception of Frobs) may be used in place of the object as the ", <$format, ["i", [], ["receiver"], 'do_i]>, ". If a method is called in this manner, the interpreter will lookup an object with an object name that is the same as the type of data being used (such as an object named ", <$format, ["tt", [], ["$string"], 'do_tt]>, " if the data is a ", <$format, ["tt", [], ["'string"], 'do_tt]>, "). If an object is found in the database with this name, the method is called on that object and the data is sent as the first argument (subsequent arguments will still be sent). If not, the error ", <$format, ["tt", [], ["~objnf"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "If a Frob is used in place of ", <$format, ["i", [], ["receiver"], 'do_i]>, ", the class object for the frob becomes the ", <$format, ["i", [], ["receiver"], 'do_i]>, " and the representation of the frob is sent as the first argument. Because of this difference it is possible to have a special method that only a frob may call. For more information on frobbed methods see ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Defining Methods"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, <$format, ["i", [], ["method"], 'do_i]>, " must be either the name of the method, or an expression which results in a symbol for the name of the method. If ", <$format, ["i", [], ["method"], 'do_i]>, " cannot be found on ", <$format, ["i", [], ["receiver"], 'do_i]>, " or any of ", <$format, ["i", [], ["receiver"], 'do_i]>, "'s ancestors, then the error ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "The result from a method-call expression is the value returned by the method. If the method does not return a value, the result is ", <$format, ["i", [], ["receiver"], 'do_i]>, ". If ", <$format, ["i", [], ["receiver"], 'do_i]>, " is a frob, then the method is called on the frob's class object, with the frob's representation inserted as the first argument (other arguments are placed after the representation). ", <$format, ["np", [], [], 'do_np]>, "Here are some examples of method-call expressions:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [".tell(\"I don't see that here.\");", <$format, ["br", [], [], 'do_br]>, "=> $brandon"], 'do_dfn]>, " ", <$format, ["dfn", [], ["$sys.admins();", <$format, ["br", [], [], 'do_br]>, "=> [$lynx, $dancer, $jenner]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["([1, 2, 3]).reverse()", <$format, ["br", [], [], 'do_br]>, "=> [3, 2, 1]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["$parser.(tosym(what + \"_mesg\"))(messages)", <$format, ["br", [], [], 'do_br]>, "=> $parser"], 'do_dfn]>, " ", <$format, ["dfn", [], ["(<$thing_frob, #[['myname, \"coins\"], ['amount, 300]]>).name()", <$format, ["br", [], [], 'do_br]>, "=> \"300 coins\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In order to prevent incidents of infinite recursion, there is a maximum calling depth for methods. If calling a method would exceed the maximum calling depth, the error ", <$format, ["tt", [], ["~maxdepth"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "If a method is overridden it is still possible for it to be called. For more information see the section ", <$format, ["link", [["node", "$help_coldc_mcall_over"]], ["Calling Overridden Methods"], 'do_link]>, "."], #[['this, $help_coldc_mcall]]]>;
var $root inited = 1;
var $root child_index = 2;
var $root managed = [$help_coldc_mcall];
var $help_node nolist = 0;


new object $help_coldc_mcall_over: $help_coldc_mcall;

var $root manager = $help_coldc_mcall_over;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058039;
var $has_name name = ['prop, "Overridden Methods|override", "Overridden Methods|override"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "If a method overrides another method defined on an ancestor, the overriding method can call the overridden method using the function ", <$format, ["tt", [], ["pass()"], 'do_tt]>, ". Arguments to ", <$format, ["tt", [], ["pass()"], 'do_tt]>, " are sent to the overridden method as if the method were called normally. The return value of ", <$format, ["tt", [], ["pass()"], 'do_tt]>, " is the normal return value of the overridden method. ", <$format, ["np", [], [], 'do_np]>, "For instance, passing to an overridden method with:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["pass(\"this arg\", 2);"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Would be rougly equivalent to calling the same method, if it was not overridden, with:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["obj.method(\"this arg\", 2);"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When executed in this manner, the overridden method sees the same object, sender, and caller as the current method. ", <$format, ["np", [], [], 'do_np]>, "In the situation where a descendant overrides a method defined on two of its ancestors, you can determine which method is passed to using the function ", <$format, ["i", [], [<$format, ["link", [["node", "$help_func_find_next_method"]], ["find_next_method()"], 'do_link]>], 'do_i]>, ". The following method (assuming a ColdCore database) can also be of use:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["arg obj, method;\nvar trace, current;\n\ncurrent = (> obj.find_method(method) <);\ntrace = [];\nwhile (current) {\n    trace += [current];\n    current = (| obj.find_next_method(method, current) |);\n}\nreturn trace;"], 'do_quote]>], 'do_dfn]>], #[['this, $help_coldc_mcall_over]]]>;
var $root inited = 1;
var $help_node group = 1;
var $root managed = [$help_coldc_mcall_over];
var $help_node nolist = 0;


new object $help_coldc_err_expr: $help_coldc_expr;

var $root manager = $help_coldc_err_expr;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854057983;
var $has_name name = ['prop, "Error Handling Expression", "Error Handling Expression"];
var $help_node links = #[["Errors", $help_coldc_errors]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Two mechanisms exist for handling errors in expressions. These are the ", <$format, ["i", [], ["critical expression"], 'do_i]>, " and the ", <$format, ["i", [], ["propagation expression"], 'do_i]>, ". The ", <$format, ["i", [], ["critical expression"], 'do_i]>, " is used to ignore any errors thrown from inside the expression. It has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["(| expression |)"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If an error occurs in ", <$format, ["i", [], ["expression"], 'do_i]>, " the interpreter will stop evaluating ", <$format, ["i", [], ["expression"], 'do_i]>, " and continue to execute the current method as if it had succeeded evaluating ", <$format, ["i", [], ["expression"], 'do_i]>, ". The value of ", <$format, ["i", [], ["expression"], 'do_i]>, " will be the error code for the error which occurred. ", <$format, ["np", [], [], 'do_np]>, "The ", <$format, ["i", [], ["propagation expression"], 'do_i]>, " causes any error thrown by a method call within the expression to be thrown as if the current method threw it. It has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["(> expression <)"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, "If an error occurs in ", <$format, ["i", [], ["expression"], 'do_i]>, " it will propagate to the calling method as if the error had originated in the calling method and not in the current method. Otherwise, the calling method will receive the error as ", <$format, ["tt", [], ["~methoderr"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "Critical expressions override the behavior of catch statements so that errors which occur within critical expressions do not trigger catch error handlers. Propagation expressions do not override critical expressions or catch statements, however. They do not prevent errors from being caught; they only determine how errors propagate if they are not caught. ", <$format, ["np", [], [], 'do_np]>, "For more information on handling errors, see section ", <$format, ["link", [["node", "$help_coldc_errors"]], ["Errors"], 'do_link]>, "."], #[['this, $help_coldc_err_expr]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_err_expr];
var $help_node nolist = 0;


new object $help_coldc_loop_expr: $help_coldc_expr;

var $root manager = $help_coldc_loop_expr;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854057996;
var $has_name name = ['prop, "Looping Expressions", "Looping Expressions"];
var $help_node links = #[["map", $help_coldc_map], ["hash", $help_coldc_hash], ["find", $help_coldc_find], ["filter", $help_coldc_filter]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Cold offers several expressions that enable looping through lists, dictionaries or integer ranges. Their main advantages over looping statements are brevity and preallocating of lists/dictionaries they return (for greater speed). The loop expressions are:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_map"]], ["map"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_hash"]], ["hash"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_find"]], ["find"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_filter"]], ["filter"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_loop_expr]]]>;
var $root inited = 1;
var $root child_index = 4;
var $root managed = [$help_coldc_loop_expr];
var $help_node nolist = 0;


new object $help_coldc_map: $help_coldc_loop_expr;

var $root manager = $help_coldc_map;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854330811;
var $has_name name = ['prop, "map", "map"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["tt", [], ["map"], 'do_tt]>, " expression loops a variable through a list, dictionary or integer range, evaluating an expression for each iteration. Results from each iteration are collected into a list and returned when the loop is completed. The syntax for map can be either of the following:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["map ", <$format, ["i", [], ["var"], 'do_i]>, " in (", <$format, ["i", [], ["what expr"], 'do_i]>, ") to (", <$format, ["i", [], ["iteration expr"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, "map ", <$format, ["i", [], ["var"], 'do_i]>, " in [", <$format, ["i", [], ["lower expr"], 'do_i]>, " .. ", <$format, ["i", [], ["upper expr"], 'do_i]>, "] to (", <$format, ["i", [], ["iteration expr"], 'do_i]>, ")"], 'do_tt]>, " "], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["map x in ([1, 2, 3]) to (tostr(x))", <$format, ["br", [], [], 'do_br]>, "=> [\"1\", \"2\", \"3\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["map x in [5 .. 15] to (x)", <$format, ["br", [], [], 'do_br]>, "=> [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]"], 'do_dfn]>], #[['this, $help_coldc_map]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_map];
var $help_node nolist = 0;


new object $help_coldc_hash: $help_coldc_loop_expr;

var $root manager = $help_coldc_hash;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854330811;
var $has_name name = ['prop, "hash", "hash"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["tt", [], ["hash"], 'do_tt]>, " expression loops a variable through a list, dictionary or integer range, evaluating an expression for each iteration. Results from each iteration must be contained within a two element list. The list is inserted as the key/value pair into a dictionary. After the loop completes the final dictionary is returned. The syntax for hash can be either of the following:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["hash x in ([1, 2, 3]) to ([toobjnum(x).name(), x])", <$format, ["br", [], [], 'do_br]>, "=> #[[\"$root\", 1], [\"Brandon\", 2], [\"Dancer\", 3]]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["hash x in [1 .. 3] to (.random_pair())", <$format, ["br", [], [], 'do_br]>, "=> #[[\"Dancer\", 1], [\"Miro\", 7], [\"$root\", 1]]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "In the above example the method ", <$format, ["tt", [], [".random_pair()"], 'do_tt]>, " returns a random two element key/value pair."], #[['this, $help_coldc_hash]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_hash];
var $help_node nolist = 0;


new object $help_coldc_find: $help_coldc_loop_expr;

var $root manager = $help_coldc_find;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854330811;
var $has_name name = ['prop, "find", "find"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The find expression is used to find the position of something in a list or dictionary. It does this by looping through the given list or dictionary and testing the iteration expression. When the iteration expression evaluates true it stops and returns the given position. The syntax of find is:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["find var in (what expr) where (iteration expr)", <$format, ["br", [], [], 'do_br]>, "find var in [lower expr .. upper expr] where (iteration expr)"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If iteration expression never evaluated true, find returns a zero. The following examples assume the variable ", <$format, ["i", [], ["list"], 'do_i]>, " is set as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["[\"First line\",\"second line\",\"3rd line\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["list[find x in (list) where (x.match_regexp(\"co\"))]", <$format, ["br", [], [], 'do_br]>, "=> \"second line\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["find x in [1 .. listlen(list)] where (list[x].match_regexp(\"co\"))", <$format, ["br", [], [], 'do_br]>, "=> 2"], 'do_dfn]>], #[['this, $help_coldc_find]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_find];
var $help_node nolist = 0;


new object $help_coldc_filter: $help_coldc_loop_expr;

var $root manager = $help_coldc_filter;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854330811;
var $has_name name = ['prop, "filter", "filter"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["tt", [], ["filter"], 'do_tt]>, " expression is used to selectively pull elements from a list or dictionary. It loops through the given list or dictionary and adds each element to a new list if the iteration expression tests true. The final list is returned after filter finishes looping. The syntax of filter is:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["filter var in (what expr) where (iteration expr)", <$format, ["br", [], [], 'do_br]>, "filter var in [lower expr .. upper expr] where (iteration expr)"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The following examples assume the variable ", <$format, ["i", [], ["list"], 'do_i]>, " is set as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["[\"First line\", \"second line\", \"3rd line\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["filter x in (list) where (x.match_regexp(\"co\"))", <$format, ["br", [], [], 'do_br]>, "=> [\"second line\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["filter x in [1 .. list.length()] where (list[x].match_regexp(\"co\"));", <$format, ["br", [], [], 'do_br]>, "=> [2]"], 'do_dfn]>], #[['this, $help_coldc_filter]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_filter];
var $help_node nolist = 0;


new object $help_coldc_stmts: $help_coldc_lang;

var $root manager = $help_coldc_stmts;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058207;
var $has_name name = ['prop, "Statements", "Statements"];
var $help_node links = #[["expressions", $help_coldc_expr], ["Simple", $help_coldc_simple_stmts], ["Conditional", $help_coldc_cond_stmts], ["Error Handling", $help_coldc_err_stmts], ["Looping", $help_coldc_loop_stmts]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A ", <$format, ["i", [], ["statement"], 'do_i]>, " is a complete instruction to the interpreter. Statements are composed of ", <$format, ["link", [["node", "$help_coldc_expr"]], ["expressions"], 'do_link]>, " or constructs. Statements can be simple (such as comments), or they can be complex (such as loops and conditionals). Most statement types in ColdC have simple structures. Because statements can include other statements (using a compound statement) they can be used to build complex directives for the interpreter. Statements are grouped into four categories:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_simple_stmts"]], ["Simple"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_cond_stmts"]], ["Conditional"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_err_stmts"]], ["Error Handling"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_loop_stmts"]], ["Looping"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_stmts]]]>;
var $root inited = 1;
var $root child_index = 4;
var $root managed = [$help_coldc_stmts];
var $help_node nolist = 0;


new object $help_coldc_simple_stmts: $help_coldc_stmts;

var $root manager = $help_coldc_simple_stmts;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058235;
var $has_name name = ['prop, "Simple", "Simple"];
var $help_node links = #[["Comment", $help_coldc_comment_stmt], ["Expression", $help_coldc_expr_stmt], ["Compound", $help_coldc_compound_stmt], ["Return", $help_coldc_return_stmt]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Simple statements evaluate one instruction, once. There are four different simple statements in ColdC:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_comment_stmt"]], ["Comment"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_expr_stmt"]], ["Expression"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_compound_stmt"]], ["Compound"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_return_stmt"]], ["Return"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_simple_stmts]]]>;
var $root inited = 1;
var $root child_index = 4;
var $root managed = [$help_coldc_simple_stmts];
var $help_node nolist = 0;


new object $help_coldc_comment_stmt: $help_coldc_simple_stmts;

var $root manager = $help_coldc_comment_stmt;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854343841;
var $has_name name = ['prop, "Comment", "Comment"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["comment statement"], 'do_i]>, " does nothing. A comment statement is used for including notes within ColdC code. It is formatted as two forward slashes followed by any characters up to the end of the line, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["// This is a comment."], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The interpreter ignores comment statements completely; they are for the benefit of human readers. Note that comments in ColdC are actual statements, unlike comments in other languages, which are usually discarded by the preprocessor."], #[['this, $help_coldc_comment_stmt]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_comment_stmt];
var $help_node nolist = 0;


new object $help_coldc_expr_stmt: $help_coldc_simple_stmts;

var $root manager = $help_coldc_expr_stmt;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854390331;
var $has_name name = ['prop, "Expression", "Expression"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["expression statement"], 'do_i]>, " evaluates a complete expression, discarding the result. The syntax of an expression statement is an expression followed by a semi colon, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["expression"], 'do_i]>, ";"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["\"this\";", <$format, ["br", [], [], 'do_br]>, "y = x + 50;"], 'do_tt]>], 'do_dfn]>], #[['this, $help_coldc_expr_stmt]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_expr_stmt];
var $help_node nolist = 0;


new object $help_coldc_compound_stmt: $help_coldc_simple_stmts;

var $root manager = $help_coldc_compound_stmt;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854390331;
var $has_name name = ['prop, "Compound", "Compound"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The compound statement is used to group one or more statements as a single statement. The compound statement is formatted as any number of statements contained within left and right curly braces, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["{", <$format, ["dfn", [], [<$format, ["i", [], ["statement1", <$format, ["br", [], [], 'do_br]>, "statement2", <$format, ["br", [], [], 'do_br]>, "..", <$format, ["br", [], [], 'do_br]>, "..", <$format, ["br", [], [], 'do_br]>, ".."], 'do_i]>], 'do_dfn]>, "}"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The interpreter evaluates each statement in the compound block in turn."], #[['this, $help_coldc_compound_stmt]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_compound_stmt];
var $help_node nolist = 0;


new object $help_coldc_return_stmt: $help_coldc_simple_stmts;

var $root manager = $help_coldc_return_stmt;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854390331;
var $has_name name = ['prop, "Return", "Return"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["return statement"], 'do_i]>, " stops executing the current method and (optionally) returns a specific value. The return statement can have either of the following two forms:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["return ", <$format, ["i", [], ["expression"], 'do_i]>, ";", <$format, ["br", [], [], 'do_br]>, "return;"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If ", <$format, ["i", [], ["expression"], 'do_i]>, " exists the interpreter evaluates and returns its result from the method. Otherwise, if no expression is given the current object is returned."], #[['this, $help_coldc_return_stmt]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_return_stmt];
var $help_node nolist = 0;


new object $help_coldc_cond_stmts: $help_coldc_stmts;

var $root manager = $help_coldc_cond_stmts;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058244;
var $has_name name = ['prop, "Conditional", "Conditional"];
var $help_node links = #[["if", $help_coldc_cond_if], ["if-else", $help_coldc_cond_ifelse], ["switch", $help_coldc_cond_switch]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Conditional statements execute other statements if a test condition evaluates true. There are three types of conditional statements in ColdC:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_cond_if"]], ["if"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_cond_ifelse"]], ["if-else"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_cond_switch"]], ["switch"], 'do_link]>], 'do_li]>], 'do_ul]>, <$format, ["np", [], [], 'do_np]>, "Because the if statement and the if-else statement are similar, they can sometimes be ambiguous. The following code will produce unexpected results:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["if (a)\n    if (b) c;\nelse\n    d;"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The indentation suggests that the ", <$format, ["tt", [], ["else"], 'do_tt]>, " clause should apply to the first ", <$format, ["tt", [], ["if"], 'do_tt]>, " clause, but in fact it applies to the more recent one. Ambiguities like this can be avoided by using braces to create compound statements out of conditional and looping statements, even if there is only one statement. A less ambiguous way to write the above is:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["if (a) {\n    if (b)\n        c;\n} else {  \n    d;\n}"], 'do_quote]>], 'do_dfn]>], #[['this, $help_coldc_cond_stmts]]]>;
var $root inited = 1;
var $root child_index = 3;
var $root managed = [$help_coldc_cond_stmts];
var $help_node nolist = 0;


new object $help_coldc_cond_if: $help_coldc_cond_stmts;

var $root manager = $help_coldc_cond_if;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854395476;
var $has_name name = ['prop, "if", "if"];
var $help_node links = #[["compound statement", $help_coldc_compound_stmt]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["if statement"], 'do_i]>, " is used to selectively execute code. It will only execute the code if the ", <$format, ["i", [], ["condition expression"], 'do_i]>, " evaluates true. It has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["if (", <$format, ["i", [], ["condition expression"], 'do_i]>, ") ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["i", [], ["statement"], 'do_i]>], 'do_dfn]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When the interpreter encounters the ", <$format, ["i", [], ["if statement"], 'do_i]>, " it will first evaluate the ", <$format, ["i", [], ["condition expression"], 'do_i]>, ". If the value of the ", <$format, ["i", [], ["condition expression"], 'do_i]>, " is true then it will evaluate the ", <$format, ["i", [], ["statement"], 'do_i]>, ". If it is not true it will skip the ", <$format, ["i", [], ["statement"], 'do_i]>, ". The ", <$format, ["link", [["node", "$help_coldc_compound_stmt"]], ["compound statement"], 'do_link]>, " can be used to group multiple statements."], #[['this, $help_coldc_cond_if]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_cond_if];
var $help_node nolist = 0;


new object $help_coldc_cond_ifelse: $help_coldc_cond_stmts;

var $root manager = $help_coldc_cond_ifelse;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854395484;
var $has_name name = ['prop, "if-else|else", "if-else|else"];
var $help_node links = #[["if statement", $help_coldc_cond_if], ["compound statement", $help_coldc_compound_stmt]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["if-else statement"], 'do_i]>, " is similar to the ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_cond_if"]], ["if statement"], 'do_link]>], 'do_i]>, ". It further extends the ", <$format, ["i", [], ["if statement"], 'do_i]>, "'s syntax to include a second statement for when the ", <$format, ["i", [], ["condition expression"], 'do_i]>, " evaluates false. It has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["if (", <$format, ["i", [], ["condition expression"], 'do_i]>, ") ", <$format, ["dfn", [["ind", "4"]], [<$format, ["i", [], ["true statement"], 'do_i]>], 'do_dfn]>, "else ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["i", [], ["false statement"], 'do_i]>], 'do_dfn]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When the interpreter encounters the ", <$format, ["i", [], ["if-else statement"], 'do_i]>, " it will first evaluate the ", <$format, ["i", [], ["condition expression"], 'do_i]>, ". If the value of the ", <$format, ["i", [], ["condition expression"], 'do_i]>, " is true, it will execute the ", <$format, ["i", [], ["true expression"], 'do_i]>, ", otherwise it will execute the ", <$format, ["i", [], ["false expression"], 'do_i]>, ". The ", <$format, ["link", [["node", "$help_coldc_compound_stmt"]], ["compound statement"], 'do_link]>, " can be used to group multiple statements."], #[['this, $help_coldc_cond_ifelse]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_cond_ifelse];
var $help_node nolist = 0;


new object $help_coldc_cond_switch: $help_coldc_cond_stmts;

var $root manager = $help_coldc_cond_switch;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854395484;
var $has_name name = ['prop, "switch", "switch"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["switch statement"], 'do_i]>, " is used to compare one value against a series of other values. The switch statement is the most complicated statement in ColdC, and does vary from it's counterpart in C, so rather than using abstract explanations we will start with an example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["switch (val) {\n    case 0:\n        echo(\"The value is zero.\");\n    case 1 .. 10:\n        echo(\"The value is between one and ten inclusive.\");\n    case 11 .. a:\n        echo(\"The value is between eleven and a inclusive.\");\n    case \"foo\", \"bar\"..\"baz\":\n        echo(\"The value is \\\"foo\\\" or between \\\"bar\\\" and \\\"baz\\\"\");\n    case a .. b, c .. d, 42:\n        count = count + 1;\n        echo(\"The value is in the counted area.\");\n    case ~perm:\n        echo(\"Permission denied while getting the value.\");\n    default:\n        echo(\"Did not recognize value.\");\n}"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This example illustrates all of the capabilities of the switch statement. The expression given by ", <$format, ["tt", [], ["val"], 'do_tt]>, " in the example is the ", <$format, ["i", [], ["controlling expression"], 'do_i]>, ", and is compared against each of the cases inside the switch body until a match is found. Each ", <$format, ["tt", [], ["case"], 'do_tt]>, " has a value or list of values to compare against. The values can be of any type, and need not be constant expressions. Ranges are specified using two dots (", <$format, ["tt", [], [".."], 'do_tt]>, ") to separate the lower and upper bounds. The keyword ", <$format, ["tt", [], ["default"], 'do_tt]>, " specifies an action to perform if no cases were matched by the controlling expression. ", <$format, ["np", [], [], 'do_np]>, "Here is a more formal description of the syntax of the switch statement:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["switch (", <$format, ["i", [], ["controlling-expression"], 'do_i]>, ") { ", <$format, ["dfn", [["ind", "4"]], ["case ", <$format, ["i", [], ["expr-or-range"], 'do_i]>, ", ", <$format, ["i", [], ["expr-or-range"], 'do_i]>, ", ", <$format, ["i", [], [".."], 'do_i]>, ": ", <$format, ["dfn", [["ind", "4"]], ["statement"], 'do_dfn]>, "case ", <$format, ["i", [], ["expr-or-range"], 'do_i]>, ", ", <$format, ["i", [], ["expr-or-range"], 'do_i]>, ", ", <$format, ["i", [], [".."], 'do_i]>, ": ", <$format, ["dfn", [["ind", "4"]], ["statement"], 'do_dfn]>, <$format, ["i", [], [".."], 'do_i]>, <$format, ["br", [], [], 'do_br]>, "default: ", <$format, ["dfn", [["ind", "4"], ["nobound", 1]], [<$format, ["i", [], ["default-statement"], 'do_i]>], 'do_dfn]>], 'do_dfn]>, "}"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When executing a switch statement, the interpreter scans through the list of cases and compares the ", <$format, ["i", [], ["controlling-expression"], 'do_i]>, " against each of the cases, evaluating the case from left to right until there is a match. When using a range, the lower and upper bounds must be of the same type and must be either integers or strings. If they are not the error ", <$format, ["tt", [], ["~type"], 'do_tt]>, " is thrown. When the interpreter finds a match, it will execute the statement for that case. The interpreter will not continue checking cases after a match. ", <$format, ["np", [], [], 'do_np]>, "If the interpreter does not find a match, it will execute instead execute the ", <$format, ["i", [], ["default-statement"], 'do_i]>, ". A default statement does not need to be defined. If a default is not defined nothing in the switch is executed. ", <$format, ["np", [], [], 'do_np]>, <$format, ["tt", [], ["C"], 'do_tt]>, " programmers should note that switch statements in ColdC differ from switch statements in ", <$format, ["tt", [], ["C"], 'do_tt]>, " in several respects. Because case values do not have to be constants, they may conflict, in which case the first match will take precedence. Also, there is no fall-through in ColdC switch statements; only the statements corresponding to the matching case will be executed. Because there is no fall-through, the ", <$format, ["tt", [], ["break"], 'do_tt]>, " statement does not apply to switch statements. Finally, the default case must be placed last in the list of cases if it is given."], #[['this, $help_coldc_cond_switch]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_cond_switch];
var $help_node nolist = 0;


new object $help_coldc_err_stmts: $help_coldc_stmts;

var $root manager = $help_coldc_err_stmts;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058264;
var $has_name name = ['prop, "Error-Handling|catch", "Error-Handling|catch"];
var $help_node links = #[["error()", $help_func_error], ["traceback()", $help_func_traceback], ["rethrow()", $help_func_rethrow], ["throw()", $help_func_throw], ["critical expressions", $help_coldc_err_expr]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["catch statement"], 'do_i]>, " is used to catch and recuperate from errors. The catch statement has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["catch ", <$format, ["i", [], ["error code"], 'do_i]>, ", ", <$format, ["i", [], ["error code"], 'do_i]>, ", ", <$format, ["i", [], [".."], 'do_i]>, " ", <$format, ["dfn", [["ind", "4"]], [<$format, ["i", [], ["body-statement"], 'do_i]>], 'do_dfn]>, "with ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["i", [], ["handler-statement"], 'do_i]>], 'do_dfn]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The keyword ", <$format, ["tt", [], ["any"], 'do_tt]>, " can be substituded for the list of errors to to catch all errors. The handler statement is optional, and does not need to be defined. ", <$format, ["np", [], [], 'do_np]>, "If an error listed in the error list is thrown inside the ", <$format, ["i", [], ["body-statement"], 'do_i]>, ", the interpreter will catch the error and start executing ", <$format, ["i", [], ["handler-statement"], 'do_i]>, " rather than aborting the method. After the handler is done, the interpreter continues executing after the end of the catch statement, as if ", <$format, ["i", [], ["body-statement"], 'do_i]>, " had completed with no errors. ", <$format, ["np", [], [], 'do_np]>, "Inside the handler statement, the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_error"]], ["error()"], 'do_link]>], 'do_tt]>, " can be used to retrieve the error code which triggered the handler and the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_traceback"]], ["traceback()"], 'do_link]>], 'do_tt]>, " can be used to retrieve the propagated error stack. The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_rethrow"]], ["rethrow()"], 'do_link]>], 'do_tt]>, " is used to continue propagating an error. The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_throw"]], ["throw()"], 'do_link]>], 'do_tt]>, " can be used at any time to throw an error. ", <$format, ["np", [], [], 'do_np]>, "Here is an example of how a catch statement could intelligently handle a ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " error thrown from the ", <$format, ["tt", [], ["list_method()"], 'do_tt]>, " function:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["catch ~methodnf\n    code = list_method(method_name);\nwith\n    .tell(\"There is no method named \" + tostr(method_name) + \".\");"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Note that ", <$format, ["link", [["node", "$help_coldc_err_expr"]], ["critical expressions"], 'do_link]>, " inside ", <$format, ["i", [], ["body-statement"], 'do_i]>, " will override the behavior of the catch statement."], #[['this, $help_coldc_err_stmts]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_err_stmts];
var $help_node nolist = 0;


new object $help_coldc_loop_stmts: $help_coldc_stmts;

var $root manager = $help_coldc_loop_stmts;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058280;
var $has_name name = ['prop, "Looping Statements", "Looping Statements"];
var $help_node links = #[["for-list", $help_coldc_forlist], ["for-range", $help_coldc_forrange], ["while", $help_coldc_while], ["break", $help_coldc_break], ["continue", $help_coldc_continue]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdC provides three kinds of looping statements. These statements are used to traverse a list or a range of numbers, or to execute a statement as long as a certain condition is true. ColdC also provides two kinds of jump statements which are used to prematurely exit from a loop or continue onto the next iteration of a loop.", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_forlist"]], ["for-list"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_forrange"]], ["for-range"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_while"]], ["while"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_break"]], ["break"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_continue"]], ["continue"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_loop_stmts]]]>;
var $root inited = 1;
var $root child_index = 10;
var $root managed = [$help_coldc_loop_stmts];
var $help_node nolist = 0;


new object $help_coldc_forlist: $help_coldc_loop_stmts;

var $root manager = $help_coldc_forlist;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854403194;
var $has_name name = ['prop, "for-list", "for-list"];
var $help_node links = #[["Dictionaries", $help_coldc_types]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["for-list statement"], 'do_i]>, " is used to traverse a list. It has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["for ", <$format, ["i", [], ["iteration variable"], 'do_i]>, " in (", <$format, ["i", [], ["what expr"], 'do_i]>, ") ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["i", [], ["statement"], 'do_i]>], 'do_dfn]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, <$format, ["i", [], ["iteration variable"], 'do_i]>, " must be a local variable (it cannot be an object variable), and ", <$format, ["i", [], ["what expr"], 'do_i]>, " must be an expression resulting in a list or dictionary type. The interpreter executes ", <$format, ["i", [], ["statement"], 'do_i]>, " once for each element in ", <$format, ["i", [], ["what"], 'do_i]>, ", assigning the current element to the ", <$format, ["i", [], ["iteration variable"], 'do_i]>, " for the iteration. Here is an example of using a for-list statement on a list:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["for s in ([\"foo\", \"bar\", \"baz\"])\n    .tell(s);"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When executed, the method ", <$format, ["i", [], ["tell"], 'do_i]>, " is called three times, the first time with an argument of ", <$format, ["tt", [], ["\"foo\""], 'do_tt]>, " (the first element in the list), the second time with ", <$format, ["tt", [], ["\"bar\""], 'do_tt]>, " (the second element in the list), and the third time with ", <$format, ["tt", [], ["\"baz\""], 'do_tt]>, " (the last element in the list). ", <$format, ["np", [], [], 'do_np]>, "When using a dictionary as ", <$format, ["i", [], ["what expr"], 'do_i]>, ", the interpreter assigns each association in the dictionary to the ", <$format, ["i", [], ["iteration variable"], 'do_i]>, " (see ", <$format, ["link", [["node", "$help_coldc_types"]], ["Dictionaries"], 'do_link]>, "). For example, if the dictionary ", <$format, ["tt", [], ["#[['count, 21], ['name, \"foo\"]]"], 'do_tt]>, " were to be used as the ", <$format, ["i", [], ["what expr"], 'do_i]>, ", the first iteration would set ", <$format, ["i", [], ["iteration variable"], 'do_i]>, " to ", <$format, ["tt", [], ["['count, 21]"], 'do_tt]>, ", and the second iteration would set it to ", <$format, ["tt", [], ["['name, \"foo\"]"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "Assigning to the ", <$format, ["i", [], ["iteration variable"], 'do_i]>, " within a for-list statement will not change the status of the loop; the interpreter remembers where it is at in ", <$format, ["i", [], ["what"], 'do_i]>, " and will continue as normal."], #[['this, $help_coldc_forlist]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_forlist];
var $help_node nolist = 0;


new object $help_coldc_forrange: $help_coldc_loop_stmts;

var $root manager = $help_coldc_forrange;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854403194;
var $has_name name = ['prop, "for-range", "for-range"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["for-range statement"], 'do_i]>, " is used to traverse a range of integers. The range is specified by seperating the lower and upper bounds of the range with the range operator (", <$format, ["tt", [], [".."], 'do_tt]>, "), contained within the left and right square brackets (", <$format, ["tt", [], ["["], 'do_tt]>, " and ", <$format, ["tt", [], ["]"], 'do_tt]>, "). A for-list statement of this nature would look like:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["for ", <$format, ["i", [], ["variable"], 'do_i]>, " in [", <$format, ["i", [], ["lower"], 'do_i]>, " .. ", <$format, ["i", [], ["upper"], 'do_i]>, "] ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["i", [], ["statement"], 'do_i]>], 'do_dfn]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, <$format, ["i", [], ["lower"], 'do_i]>, " and ", <$format, ["i", [], ["upper"], 'do_i]>, " must be expressions resulting in an integer type (unlike a range in a switch). The interpreter executes ", <$format, ["i", [], ["statement"], 'do_i]>, " once for each number from ", <$format, ["i", [], ["lower"], 'do_i]>, " to ", <$format, ["i", [], ["upper"], 'do_i]>, ", with ", <$format, ["i", [], ["variable"], 'do_i]>, " being assigned the current number in the range. An example of using a range in a list is: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\nfor i in [1 .. 10]\n    .tell(\"iteration \" + i);"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Assigning to ", <$format, ["i", [], ["variable"], 'do_i]>, " within a for-list statement will not change the status of the loop; the interpreter remembers where it is at in ", <$format, ["i", [], ["what"], 'do_i]>, " and will continue as normal."], #[['this, $help_coldc_forrange]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_forrange];
var $help_node nolist = 0;


new object $help_coldc_while: $help_coldc_loop_stmts;

var $root manager = $help_coldc_while;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854403194;
var $has_name name = ['prop, "while", "while"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["while statement"], 'do_i]>, " is used to execute code as long as the condition expression is true. The while statement has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["while (", <$format, ["i", [], ["condition expression"], 'do_i]>, ") ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["i", [], ["statement"], 'do_i]>], 'do_dfn]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The interpreter continually evaluates ", <$format, ["i", [], ["expression"], 'do_i]>, " and executes ", <$format, ["i", [], ["statement"], 'do_i]>, " until the return value of ", <$format, ["i", [], ["expression"], 'do_i]>, " is false. Here is an example using a while statement: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\na = 1;\nwhile (a < 35)\n    a *= 2;   \n.tell(\"total: \" + a);"], 'do_quote]>], 'do_dfn]>], #[['this, $help_coldc_while]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_while];
var $help_node nolist = 0;


new object $help_coldc_break: $help_coldc_loop_stmts;

var $root manager = $help_coldc_break;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854403194;
var $has_name name = ['prop, "break", "break"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["break statement"], 'do_i]>, " is used to exit a looping statement prematurely. The break statement has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["break;"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The interpreter jumps to the end of the ", <$format, ["i", [], ["innermost"], 'do_i]>, " for-list, for-range, or while statement and continues executing. It is important to note this, as when executing multiple nested looping statements the the ", <$format, ["i", [], ["break statement"], 'do_i]>, " will only break out of the innermost loop."], #[['this, $help_coldc_break]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_break];
var $help_node nolist = 0;


new object $help_coldc_continue: $help_coldc_loop_stmts;

var $root manager = $help_coldc_continue;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854403194;
var $has_name name = ['prop, "continue", "continue"];
var $help_node links = #[["break statement", $help_coldc_break]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ", <$format, ["i", [], ["continue statement"], 'do_i]>, " is used to jump to the next iteration of a loop. The continue statement has the following syntax:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["continue;"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The interpreter skips the remainder of the loop body and begins another iteration of the innermost looping statement. As with the ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_break"]], ["break statement"], 'do_link]>], 'do_i]>, " the ", <$format, ["i", [], ["continue statement"], 'do_i]>, " only is relevant to the innermost looping statement."], #[['this, $help_coldc_continue]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_continue];
var $help_node nolist = 0;


new object $help_coldc_imp: $help_coldc;

var $root manager = $help_coldc_imp;
var $help_node holder = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854662991;
var $has_name name = ['prop, "Implementation", "Implementation"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[['this, $help_coldc_imp]]]>;
var $root inited = 1;
var $root child_index = 1;
var $root managed = [$help_coldc_imp];
var $help_node nolist = 0;


new object $help_coldc_methods: $help_coldc_imp;

var $root manager = $help_coldc_methods;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058074;
var $has_name name = ['prop, "Methods", "Methods"];
var $help_node links = #[["Method Code", $help_coldc_methods_code], ["Method Flags", $help_coldc_methods_flags], ["Method Access", $help_coldc_methods_access]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "A method consists of five different aspects: Arguments, Variables, ColdC Code, Access and Flags. Arguments, Variables and ColdC Code are all defined within the Method Code. Access and Flags are set and changed outside the method definition. Arguments define how the method can be called. Variables define any local variables used in the method. Code consists of the rest of the method instructions. Access defines how the method may be called and Flags define any other functionality and behaviour of the method.", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_methods_code"]], ["Method Code"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_methods_flags"]], ["Method Flags"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_methods_access"]], ["Method Access"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_methods]]]>;
var $root inited = 1;
var $root child_index = 4;
var $root managed = [$help_coldc_methods];
var $help_node nolist = 0;


new object $help_coldc_methods_code: $help_coldc_methods;

var $root manager = $help_coldc_methods_code;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854665860;
var $has_name name = ['prop, "Code", "Code"];
var $help_node links = #[["splice operator", $help_coldc_splice], ["add_method()", $help_func_add_method], ["Textdump", $help_coldc_textdump]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Arguments, Local Variables and the ColdC Code for a method are defined all at once, within one block of text formatted as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["arg ", <$format, ["i", [], ["arg1"], 'do_i]>, ", ", <$format, ["i", [], ["arg2"], 'do_i]>, ", ", <$format, ["i", [], [".."], 'do_i]>, ", @", <$format, ["i", [], ["rest"], 'do_i]>, ";", <$format, ["br", [], [], 'do_br]>, "var ", <$format, ["i", [], ["var1"], 'do_i]>, ", ", <$format, ["i", [], ["var2"], 'do_i]>, ", ", <$format, ["i", [], [".."], 'do_i]>, ";", <$format, ["br", [], [], 'do_br]>, <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["statement1"], 'do_i]>, <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["statement2"], 'do_i]>, <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], [".."], 'do_i]>, <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], [".."], 'do_i]>], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The first line is the Argument Declaration. The second line is the Local Variable Declaration. Any remaining lines are standard ColdC statements, also known generically as ColdC Code. ", <$format, ["np", [], [], 'do_np]>, "The ", <$format, ["tt", [], ["arg"], 'do_tt]>, " declaration gives a list of argument variables, whose values will correspond to the arguments passed with the message. The ", <$format, ["tt", [], ["arg"], 'do_tt]>, " declaration may be omitted if the method does not take any arguments. If the final argument variable is preceeded with the ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_splice"]], ["splice operator"], 'do_link]>], 'do_i]>, " (an at-sign `", <$format, ["tt", [], ["@"], 'do_tt]>, "`), then the method can accept any number of argments; the variable ", <$format, ["i", [], ["rest"], 'do_i]>, " will contain a list of the remaining arguments. If the final argument is not defined in this way, the method can only accept the defined number of arguments, and sending any more will cause a ", <$format, ["tt", [], ["~numargs"], 'do_tt]>, " error to be thrown. ", <$format, ["np", [], [], 'do_np]>, "The ", <$format, ["tt", [], ["var"], 'do_tt]>, " declaration is used to define local variables. Any variable given in the list will exist during the execution of the method. In the case of conflicts with object variables, the local variable is used first. The ", <$format, ["tt", [], ["var"], 'do_tt]>, " declaration may be omitted if no local variables are declared. ", <$format, ["np", [], [], 'do_np]>, "Once the method begins normal execution, both arguments and local variables are treated the same (as local variables). The statements ", <$format, ["i", [], ["statement1"], 'do_i]>, ", ", <$format, ["i", [], ["statement2"], 'do_i]>, ", ", <$format, ["i", [], [".."], 'do_i]>, " compose the ColdC Code body. ", <$format, ["np", [], [], 'do_np]>, "A Method is defined using the ColdC function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_add_method"]], ["add_method()"], 'do_link]>], 'do_tt]>, ", or within a ", <$format, ["link", [["node", "$help_coldc_textdump"]], ["Textdump"], 'do_link]>, "."], #[['this, $help_coldc_methods_code]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_methods_code];
var $help_node nolist = 0;


new object $help_coldc_methods_flags: $help_coldc_methods;

var $root manager = $help_coldc_methods_flags;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854665861;
var $has_name name = ['prop, "Flags", "Flags"];
var $help_node links = #[["method_flags()", $help_func_method_flags], ["set_method_flags()", $help_func_set_method_flags]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Method flags define certain behaviour features of the method. Currently the following method flags exist: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "20%,80%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["nooverride"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Methods which specify ", <$format, ["tt", [], ["nooverride"], 'do_tt]>, " cannot be overridden by any of the defining object's descendants."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["lock"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["This locks all aspects of a method. Locked methods cannot have their access or flags changed, nor can they be recompiled during run-time. Locked methods can be changed outside of the regular running environment (such as in a textdb, or with coldcc)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["forked"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["This is used to specify that the method forks from the current task. The return value of a forked method is the task id of the new task."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["native"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["This specifies a native method. Native methods are not really methods, but are actually functions acting as a method. Because of this native methods cannot be listed or manipulated in most of the usual ways."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "All method flags, with the exception of ", <$format, ["tt", [], ["native"], 'do_tt]>, ", can be manipulated using the functions ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_method_flags"]], ["method_flags()"], 'do_link]>], 'do_tt]>, " and ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_set_method_flags"]], ["set_method_flags()"], 'do_link]>], 'do_tt]>, "."], #[['this, $help_coldc_methods_flags]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_methods_flags];
var $help_node nolist = 0;


new object $help_coldc_methods_access: $help_coldc_methods;

var $root manager = $help_coldc_methods_access;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854665867;
var $has_name name = ['prop, "Access", "Access"];
var $help_node links = #[["Frobbed Method Calls", $help_coldc_methods_frob]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "It is possible to restrict what calls a method by setting the method's access. By default all methods are ", <$format, ["i", [], ["public"], 'do_i]>, " methods. The available settings for method access are: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "15%,85%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["public"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["This access state is the default. A public method can be called by any object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["protected"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Protected methods can only be called by the defining object, or descendants of the defining object (sender() must be this())."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["private"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Private methods can only be called by the object they were defined on (caller() must be this())."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["root"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Root methods can only be called by the ", <$format, ["tt", [], ["$root"], 'do_tt]>, " object (caller() must be ", <$format, ["tt", [], ["$root"], 'do_tt]>, ")."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["driver"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Driver methods can only be called by the driver."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], [<$format, ["b", [], ["frob"], 'do_b]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["This access state only allows ", <$format, ["link", [["node", "$help_coldc_methods_frob"]], ["Frobbed Method Calls"], 'do_link]>, "."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Method access can be manipulated using the functions ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_coldc_func_method_access"]], ["method_access()"], 'do_link]>], 'do_tt]>, " and ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_coldc_func_set_method_access"]], ["set_method_access()"], 'do_link]>], 'do_tt]>, "."], #[['this, $help_coldc_methods_access]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_methods_access];
var $help_node nolist = 0;


new object $help_coldc_methods_frob: $help_coldc_methods_access;

var $root manager = $help_coldc_methods_frob;
var $help_node group = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854925896;
var $has_name name = ['prop, "Frobbed", "Frobbed"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Frobbed Method calls behave slightly different than any other access restriction. First, a frobbed method may only be called from a frob. That is, it must be called where the frob is the receiver, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["(<$object, #[]>).method()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If it is called in the normal way, it will be as if the frobbed method does not exist. For example, assume ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, " is a parent of ", <$format, ["tt", [], ["$obj_b"], 'do_tt]>, ". ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, " defines the method ", <$format, ["tt", [], [".name()"], 'do_tt]>, " as a standard method, but ", <$format, ["tt", [], ["$obj_b"], 'do_tt]>, " overrides it and defines it as a frobbed method. Calling ", <$format, ["tt", [], ["$obj_b.name()"], 'do_tt]>, " will actually skip the frobbed method and execute the method defined on ", <$format, ["tt", [], ["$obj_a"], 'do_tt]>, " where calling ", <$format, ["tt", [], ["(<$obj_b, #[]>).name()"], 'do_tt]>, " will execute the frobbed method defined on ", <$format, ["tt", [], ["$obj_b"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "When a Frobbed Method passes back to an overridden method it will look first for another Frobbed method, and then for a standard method. ", <$format, ["np", [], [], 'do_np]>, "If a method is defined as non-overridable, it may still be overridden by a Frobbed Method. This allows for Frob Class objects to emulate real object systems in the database, with frobs."], #[['this, $help_coldc_methods_frob]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_methods_frob];
var $help_node nolist = 0;


new object $help_coldc_tasks: $help_coldc_imp;

var $root manager = $help_coldc_tasks;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058088;
var $has_name name = ['prop, "Tasks and Frames", "Tasks and Frames"];
var $help_node links = #[["Execution Frame", $help_coldc_tasks_frames], ["Task", $help_coldc_tasks_tasks], ["Preempting", $help_coldc_tasks_preempt]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The state of a method as it is being evaluated is called the ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_tasks_frames"]], ["Execution Frame"], 'do_link]>], 'do_i]>, ". Each frame has a few unique values associated with it, which may or may not propagate to the next execution frame. ", <$format, ["np", [], [], 'do_np]>, "One or more frames executed in a series is called a ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_tasks_tasks"]], ["Task"], 'do_link]>], 'do_i]>, ". Tasks will originate from either a connection, a heartbeat, or by a fork in another task. There is no restriction on how many frames a task can execute. ", <$format, ["np", [], [], 'do_np]>, "It is possible to stop an executing frame, refresh the ticks it has and then continue executing. This is called ", <$format, ["i", [], [<$format, ["link", [["node", "$help_coldc_tasks_preempt"]], ["Preempting"], 'do_link]>], 'do_i]>, ". When a task is preempted it stops executing and is queued behind other current tasks. When these tasks are finished executing the preempted task continues, with a refreshed tick amount. Further information is given in the following sections:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_tasks_frames"]], ["Execution Frame"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_coldc_tasks_tasks"]], ["Task"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['this, $help_coldc_tasks]]]>;
var $root inited = 1;
var $root child_index = 3;
var $root managed = [$help_coldc_tasks];
var $help_node nolist = 0;


new object $help_coldc_tasks_frames: $help_coldc_tasks;

var $root manager = $help_coldc_tasks_frames;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854937535;
var $has_name name = ['prop, "Frames", "Frames"];
var $help_node links = #[["ticks_left()", $help_func_ticks_left], ["method()", $help_func_method], ["this()", $help_func_method], ["definer()", $help_func_method], ["sender()", $help_func_method], ["caller()", $help_func_method]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The state of a method as it is being evaluated is called the ", <$format, ["i", [], ["execution frame"], 'do_i]>, ". Each frame has a few unique values associated with it, including the maximum operations it can execute, the method itself, the current object and the object defining the method being executed. These values are only relevant to the current frame, and may or may not propagate to the next execution frame. ", <$format, ["np", [], [], 'do_np]>, "The maximum operations a frame can execute are also referred to as the ticks. If a frame runs out of ticks before it finishes executing, the ", <$format, ["tt", [], ["~ticks"], 'do_tt]>, " error is thrown by the interpreter. ", <$format, ["np", [], [], 'do_np]>, "These values can be determined by calling the following functions, as is appropriate: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "23%,77%"]], [<$format, ["tr", [], [<$format, ["th", [], ["FUNCTION"], 'do_th]>, <$format, ["th", [], ["RETURNS"], 'do_th]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_ticks_left"]], ["ticks_left()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["The ticks remaining in the frame"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_method"]], ["method()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["The current method"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_method"]], ["this()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["The current object"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_method"]], ["definer()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["The object defining the method"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_method"]], ["sender()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["The object which called this method (the last frame's current object)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_method"]], ["caller()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["The object defining the method which called this method (the last frame's definer)"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['this, $help_coldc_tasks_frames]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_tasks_frames];
var $help_node nolist = 0;


new object $help_coldc_tasks_tasks: $help_coldc_tasks;

var $root manager = $help_coldc_tasks_tasks;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854937905;
var $has_name name = ['prop, "Tasks", "Tasks"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "One or more frames executed in a series is called a ", <$format, ["i", [], ["task"], 'do_i]>, ". Tasks will originate from either a connection, a heartbeat, or by a fork in another task. There is no restriction on how many frames a task can execute. ", <$format, ["np", [], [], 'do_np]>, "Several different functions return information about a task, or are used on a task-wide scale: ", <$format, ["dfn", [["ind", "4"], ["nobound", 1]], [<$format, ["table", [["cols", "23%,77%"]], [<$format, ["tr", [], [<$format, ["th", [], ["FUNCTION"], 'do_th]>, <$format, ["th", [], ["BEHAVIOUR"], 'do_th]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_task_id"]], ["task_id()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns unique ID for the curre nt task"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_task_info"]], ["task_info()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns information on a task"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_tasks"]], ["tasks()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns a list of all paused or preempted tasks"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_stack"]], ["stack()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns full execution frame st ack"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_user"]], ["user()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Returns task user"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_user"]], ["set_user()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Sets task user"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_atomic"]], ["atomic()"], 'do_link]>], 'do_td]>, <$format, ["td", [], ["Used to turn on/off Atomic execution"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['this, $help_coldc_tasks_tasks]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_tasks_tasks];
var $help_node nolist = 0;


new object $help_coldc_tasks_preempt: $help_coldc_tasks;

var $root manager = $help_coldc_tasks_preempt;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854946002;
var $has_name name = ['prop, "Preempting", "Preempting"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "When a task is preempted it stops executing and is queued behind other current tasks. When these tasks are finished executing the preempted task continues, with a refreshed tick amount. Preempting can be caused by calling either ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_coldc_func_pause"]], ["pause()"], 'do_link]>], 'do_tt]>, " or ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_coldc_func_refresh"]], ["refresh()"], 'do_link]>], 'do_tt]>, ". ", <$format, ["tt", [], ["pause()"], 'do_tt]>, " will always preempt immediately. ", <$format, ["tt", [], ["refresh()"], 'do_tt]>, " will only preempt if the tick count is nearly exhausted. Furthermore, if executing atomically ", <$format, ["tt", [], ["refresh()"], 'do_tt]>, " will not preempt, but will immediately refresh the tick count and continue executing. ", <$format, ["np", [], [], 'do_np]>, "Tasks may also be suspended indefinitely by using the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_coldc_func_suspend"]], ["suspend()"], 'do_link]>], 'do_tt]>, ". The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_coldc_func_resume"]], ["resume()"], 'do_link]>], 'do_tt]>, " will resume a suspended task. The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_coldc_func_cancel"]], ["cancel()"], 'do_link]>], 'do_tt]>, " will cancel a suspended task. ", <$format, ["np", [], [], 'do_np]>, "For more information see ", <$format, ["link", [["node", "$help_coldc_tasks_preempt_examp"]], ["A Preempting Example"], 'do_link]>, "."], #[['this, $help_coldc_tasks_preempt]]]>;
var $root inited = 1;
var $root child_index = 1;
var $root managed = [$help_coldc_tasks_preempt];
var $help_node nolist = 0;


new object $help_coldc_tasks_preempt_examp: $help_coldc_tasks_preempt;

var $root manager = $help_coldc_tasks_preempt_examp;
var $help_node group = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854946269;
var $has_name name = ['prop, "Example", "Example"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["np", [], [], 'do_np]>, "An example of suspending a task is when reading an indefinite amount of input from a connection. Input arrives through the ", <$format, ["i", [], ["parse"], 'do_i]>, " method on an object (see ", <$format, ["link", [["node", "$help_coldc_networking"]], ["Networking"], 'do_link]>, "), which we define as follows, assuming the object variables ", <$format, ["i", [], ["reading"], 'do_i]>, ", ", <$format, ["i", [], ["read"], 'do_i]>, ", ", <$format, ["i", [], ["buffer"], 'do_i]>, " and ", <$format, ["i", [], ["lines"], 'do_i]>, ". ", <$format, ["i", [], ["reading"], 'do_i]>, " is used to store a boolean value of true or false, depending upon if we are reading input or not. ", <$format, ["i", [], ["read"], 'do_i]>, " is used to store what we have already read from the connection. ", <$format, ["i", [], ["buffer"], 'do_i]>, " is used to store incoming information which is not yet parsable by the function ", <$format, ["i", [], ["buf_to_strings()"], 'do_i]>, " (i.e. there is no carriage return yet). ", <$format, ["i", [], ["lines"], 'do_i]>, " is used to buffer lines converted by ", <$format, ["i", [], ["buf_to_strings()"], 'do_i]>, " from the connection which we have not parsed yet. It is important to use an object variable for both ", <$format, ["i", [], ["buffer"], 'do_i]>, " and ", <$format, ["i", [], ["lines"], 'do_i]>, ", because if the task suspends all information stored in either variable would be suspended along with that instance of the task.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["ind", "4"]], [<$format, ["quote", [], ["driver method .parse() {\n    arg incoming;\n    var line;\n\n    lines = buf_to_strings(buffer + incoming));\n    buffer = lines[listlen(lines)];\n    lines = delete(lines, listlen(lines));\n\n    // now parse the lines\n    for line in (buf_to_strings(incoming)) {\n        if (reading) {\n            if (line == \".\")\n                .done_reading();\n            else\n                read += [line];\n        } else {\n            .parse_line(line);\n        }\n    }\n}"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "We will not define the method ", <$format, ["i", [], ["parse_line"], 'do_i]>, ", just assume that it parses the line as a command. When an object wishes to start reading from the connection it calls the method ", <$format, ["i", [], [".read()"], 'do_i]>, " on the connection object:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["ind", "4"]], [<$format, ["quote", [], ["public method .read() {\n    // reading just has to be true, so lets save space and store the\n    // task id there as well, instead of storing it in another variable.\n    reading = task_id();\n\n    // make sure this is an empty list\n    read = [];\n\n    // suspend the task, have our return value be the return value\n    // of suspend (which is whatever resume() sends)\n    return suspend();\n}"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When a period is found as the line being read, the connection is done reading (the period is insignificant, and is only used in this example for convenience), and the method ", <$format, ["i", [], ["done_reading"], 'do_i]>, " is called:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [["ind", "4"]], [<$format, ["quote", [], ["protected method .done_reading() {\n    var info, task;\n\n    // get a local copy of what we read, and the task id\n    info = read;\n    task = reading;\n\n    // reset the object variables first\n    read = [];\n    reading = 0;\n\n    // resume the task, send what we read as the return\n    // value for suspend()\n    resume(task, info);\n}"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Now, all that has to happen to read input from a connection is to call the method ", <$format, ["i", [], [".read()"], 'do_i]>, " on the connection object, and the input read is returned from the method call. ", <$format, ["np", [], [], 'do_np]>, "It is possible to set a task as ", <$format, ["i", [], ["atomic"], 'do_i]>, ". Atomic tasks cannot be preempted or suspended. If an attempt is made to preempt or suspend an atomic task the error ", <$format, ["tt", [], ["~atomic"], 'do_tt]>, " is thrown instead. However, calling ", <$format, ["tt", [], ["refresh()"], 'do_tt]>, " while executing atomically will always refresh the current frame's ticks. A task's atomic state is toggled using the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_atomic"]], ["atomic()"], 'do_link]>], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, <$format, ["b", [], ["Note:"], 'do_b]>, " be very cautious when using atomic tasks. Atomic tasks can easilly disrupt the regular integrity of an online environment. See the section on ", <$format, ["link", [["node", "$help_coldc_security"]], ["Security"], 'do_link]>, "."], #[['this, $help_coldc_tasks_preempt_examp]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_tasks_preempt_examp];
var $help_node nolist = 0;


new object $help_coldc_errors: $help_coldc_imp;

var $root manager = $help_coldc_errors;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058064;
var $has_name name = ['prop, "Errors", "Errors"];
var $help_node links = #[["throw()", $help_func_throw], ["Error-Handling Expressions", $help_coldc_err_expr], ["traceback()", $help_func_traceback], ["catch statement", $help_coldc_err_stmts], ["Error-Handling Statements", $help_coldc_err_stmts], ["propagation expression", $help_coldc_err_expr]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "When something goes wrong in a ", <$format, ["tt", [], ["ColdC"], 'do_tt]>, " method an error is thrown. The interpreter will throw errors, and methods can throw custom errors (using the ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_throw"]], ["throw()"], 'do_link]>], 'do_tt]>, " function). An error consists of an error code (the ", <$format, ["i", [], ["type"], 'do_i]>, " of error), a string describing the error, and--optionally--data relative to the error. ", <$format, ["np", [], [], 'do_np]>, "When the interpreter throws an error, it checks to see how the current method handles that error type. If the error occured in a critical expression (see ", <$format, ["link", [["node", "$help_coldc_err_expr"]], ["Error-Handling Expressions"], 'do_link]>, "), then the interpreter will cease evaluating the critical expression. Processing of the method will continue as if the interpreter had completed evaluation of the critical expression. The return value of the critical expression will be the error code associated with the thrown error. In this case, the traceback is not accessible from ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_traceback"]], ["traceback()"], 'do_link]>], 'do_tt]>, "; in order to get a traceback, a ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_coldc_err_stmts"]], ["catch statement"], 'do_link]>], 'do_tt]>, " must be used. ", <$format, ["np", [], [], 'do_np]>, "If the error did not occur in a critical expression, but occurred in a catch statement which catches the error code (either because it is a ", <$format, ["tt", [], ["catch all"], 'do_tt]>, " statement or because it lists the error code (see ", <$format, ["link", [["node", "$help_coldc_err_stmts"]], ["Error-Handling Statements"], 'do_link]>, "). Then the processing of the method jumps to the error handler, if one was provided, or to the end of the catch statement if not. ", <$format, ["np", [], [], 'do_np]>, "If the error did not occur in a critical expression or in an appropriate catch statement, then the current method aborts, and the interpreter throws an error in the calling method. Normally, the error thrown in the calling routine will have the error code ", <$format, ["tt", [], ["~methoderr"], 'do_tt]>, " unless the original error occurred within a ", <$format, ["link", [["node", "$help_coldc_err_expr"]], ["propagation expression"], 'do_link]>, ". If the error occurred within a propagation expression then the error code will be the same as it was for the original error. A propagation expression has no effect on how an error is handled except to cause the error code to propagate differently to the calling routine. ", <$format, ["np", [], [], 'do_np]>, "Errors are thrown using the ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_throw"]], ["throw()"], 'do_link]>], 'do_tt]>, " function. This does not throw an error in the current method; instead, it exits the current method and throws an error in the calling method. Thus a method cannot ignore an error which it threw itself using ", <$format, ["tt", [], ["throw()"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "There is one case in which a method cannot catch an interpreter-generated error. Methods have a limited amount of time to run, measured in ", <$format, ["i", [], ["ticks"], 'do_i]>, ". A method will generally only run out of ticks if it gets stuck in an infinite loop. If a method runs out of ticks, then the interpreter will throw a ", <$format, ["tt", [], ["~ticks"], 'do_tt]>, " error, which the method cannot catch. This causes the method to abort, which in turn causes the interpreter to throw a ", <$format, ["tt", [], ["~methoderr"], 'do_tt]>, " error in the calling routine. ", <$format, ["np", [], [], 'do_np]>, "Critical expressions should be used when calling code which is possibly buggy or when the method may be undefined, and it is undesirable for the current method to stop executing as a result. For instance, a method which announces a string to every object in a container should probably ignore errors in the methods for each individual object which handle receiving the string. ", <$format, ["np", [], [], 'do_np]>, "Catch statements should be used to handle errors in any way other than ignoring them. The catch statement is much more powerful than the critical expression, and is ideal for situations in which fine-grain control over error handling is required. ", <$format, ["np", [], [], 'do_np]>, "Propagation expressions should be used when the current method is an intermediary between an outside object and an internal feature. For instance, a method which checks permissions and calls an object function such as ", <$format, ["tt", [], ["list_method()"], 'do_tt]>, " is acting as an intermediary. In this case, the method should throw the same errors as the ", <$format, ["tt", [], ["list_method()"], 'do_tt]>, " function, so the function call should be enclosed within a propagation expression."], #[['this, $help_coldc_errors]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_errors];
var $help_node nolist = 0;


new object $help_coldc_security: $help_coldc_imp;

var $root manager = $help_coldc_security;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058097;
var $has_name name = ['prop, "Security", "Security"];
var $help_node links = #[["bind_function()", $help_func_bind_function], ["atomic()", $help_func_atomic], ["cancel()", $help_func_cancel], ["create()", $help_func_create], ["backup()", $help_func_backup], ["shutdown()", $help_func_shutdown], ["set_heartbeat()", $help_func_set_heartbeat], ["bind_port()", $help_func_bind_port], ["unbind_port()", $help_func_unbind_port], ["open_connection()", $help_func_open_connection], ["fopen()", $help_func_fopen], ["fstat()", $help_func_fstat], ["fchmod()", $help_func_fchmod], ["fmkdir()", $help_func_fmkdir], ["frmdir()", $help_func_frmdir], ["files()", $help_func_files], ["fremove()", $help_func_fremove], ["frename()", $help_func_frename], ["fclose()", $help_func_fclose], ["fseek()", $help_func_fseek], ["feof()", $help_func_feof], ["fwrite()", $help_func_fwrite], ["fread()", $help_func_fread], ["execute()", $help_func_execute], ["fflush()", $help_func_fflush], ["unbind_function()", $help_func_unbind_function], ["Defining Methods", $help_coldc_methods]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "As the ColdC driver does not know what sort of environment the database defines, by default all functions are callable by any object in the database. In order to preserve integrity it is strongly suggested that the database builds a heirarchy of trusted objects. Bind administrative-level functions to these objects using the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_bind_function"]], ["bind_function()"], 'do_link]>], 'do_tt]>, " and restrict access to them. ", <$format, ["np", [], [], 'do_np]>, "It is suggested that the following functions always be bound and secured: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "30%,30%,30%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_atomic"]], ["atomic()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_cancel"]], ["cancel()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_create"]], ["create()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_backup"]], ["backup()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_shutdown"]], ["shutdown()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_heartbeat"]], ["set_heartbeat()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_bind_port"]], ["bind_port()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_unbind_port"]], ["unbind_port()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_open_connection"]], ["open_connection()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fopen"]], ["fopen()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fstat"]], ["fstat()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fchmod"]], ["fchmod()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fmkdir"]], ["fmkdir()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_frmdir"]], ["frmdir()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_files"]], ["files()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fremove"]], ["fremove()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_frename"]], ["frename()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fclose"]], ["fclose()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fseek"]], ["fseek()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_feof"]], ["feof()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fwrite"]], ["fwrite()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fread"]], ["fread()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_execute"]], ["execute()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fflush"]], ["fflush()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_bind_function"]], ["bind_function()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_unbind_function"]], ["unbind_function()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "It is also suggested that any additional function which modifies an object or which alters/retrieves data on an object be bound. ", <$format, ["np", [], [], 'do_np]>, "The database can further be secured by solidifying key methods in its internal security scheme (if one exists) and locking them (by setting the ", <$format, ["tt", [], ["'lock"], 'do_tt]>, " method flag, see section ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Defining Methods"], 'do_link]>, ")."], #[['this, $help_coldc_security]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_security];
var $help_node nolist = 0;


new object $help_coldc_net: $help_coldc_imp;

var $root manager = $help_coldc_net;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058107;
var $has_name name = ['prop, "Networking", "Networking"];
var $help_node links = #[["bind_port()", $help_func_bind_port], ["close_connection()", $help_func_close_connection], ["connection()", $help_func_connection], ["cwrite()", $help_func_cwrite], ["cwritef()", $help_func_cwritef], ["open_connection()", $help_func_open_connection], ["unbind_port()", $help_func_unbind_port], ["reassign_connection()", $help_func_reassign_connection], ["server connection", $help_coldc_net_server], ["client connection", $help_coldc_net_client]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdC gives the ability to handle network sockets with the following functions: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "30%,30%,30%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_bind_port"]], ["bind_port()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_close_connection"]], ["close_connection()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_connection"]], ["connection()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_cwrite"]], ["cwrite()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_cwritef"]], ["cwritef()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_open_connection"]], ["open_connection()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_unbind_port"]], ["unbind_port()"], 'do_link]>], 'do_td]>, <$format, ["td", [["colspan", "2"]], [<$format, ["link", [["node", "$help_func_reassign_connection"]], ["reassign_connection()"], 'do_link]>], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Connections are bound to a ", <$format, ["i", [], ["connection object"], 'do_i]>, ". The driver will use the following methods on a connection object:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], [".connect()", <$format, ["br", [], [], 'do_br]>, ".disconnect()", <$format, ["br", [], [], 'do_br]>, ".failed()", <$format, ["br", [], [], 'do_br]>, ".parse()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "There are two types of connections which can be created. The first is a ", <$format, ["link", [["node", "$help_coldc_net_server"]], ["server connection"], 'do_link]>, ", or a passive connection. To do this the driver listens on a network port and waits for incoming connections. The second type is an ", <$format, ["link", [["node", "$help_coldc_net_client"]], ["client connection"], 'do_link]>, ", or a active connection. This type of connection is established by the driver to another network host."], #[['this, $help_coldc_net]]]>;
var $root inited = 1;
var $root child_index = 2;
var $root managed = [$help_coldc_net];
var $help_node nolist = 0;


new object $help_coldc_net_server: $help_coldc_net;

var $root manager = $help_coldc_net_server;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854948047;
var $has_name name = ['prop, "Server Connection", "Server Connection"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "To establish a server connection first call the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_bind_port"]], ["bind_port()"], 'do_link]>], 'do_tt]>, ". The argument to this function is the network port to listen on. Note: most operating systems will restrict low numbered ports (usually anything below 1024 is restricted, and can only be opened with special privelages). If there are no errors, the current object is listening as a server on the specified port. ", <$format, ["np", [], [], 'do_np]>, "When an external client opens a connection the driver will call the method ", <$format, ["tt", [], [".connect()"], 'do_tt]>, " with two arguments. The first argument is a STRING, specifying the remote IP address of the client. The second argument is an INTEGER, specifying the socket where the connection was established. In general this number can be ignored. ", <$format, ["np", [], [], 'do_np]>, "Data received on the connection will be sent as a buffer to the method ", <$format, ["tt", [], [".parse()"], 'do_tt]>, ", after the method ", <$format, ["tt", [], [".connect()"], 'do_tt]>, " is called. Data is sent to the connection using the functions ", <$format, ["tt", [], ["cwrite()"], 'do_tt]>, " and ", <$format, ["tt", [], ["cwritef()"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "If the client terminates the connection, the method ", <$format, ["tt", [], [".disconnect()"], 'do_tt]>, " is called. Note: this method will not be called if the object terminates the connection through ", <$format, ["tt", [], ["close_connection()"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "If multiple connections will be received on the network port, it is suggested that when a connection is started the connection object either reassigns the connection to another connection object (using the function ", <$format, ["tt", [], ["reassign_connection()"], 'do_tt]>, "), or it notifies a new connection object to re-bind the port to itself. If this is not done, new connections will preempt and close the older connection (as only one connection can be on an object at a time)."], #[['this, $help_coldc_net_server]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_net_server];
var $help_node nolist = 0;


new object $help_coldc_net_client: $help_coldc_net;

var $root manager = $help_coldc_net_client;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854948047;
var $has_name name = ['prop, "Client Connection", "Client Connection"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "To establish a client connection call the function ", <$format, ["tt", [], ["open_connection()"], 'do_tt]>, " with the first argument as a STRING specifing the IP address of the host, and the second argument an INTEGER specifying the network port to connect on. This function is not a blocking function. Calling it will simply start the process of opening a connection. If there are no immediate errors the function will return normally. ", <$format, ["np", [], [], 'do_np]>, "When a connection is opened the driver will call the method ", <$format, ["tt", [], [".connect()"], 'do_tt]>, " on the current object, with the argument being an INTEGER task_id for the task which called ", <$format, ["tt", [], ["open_connection()"], 'do_tt]>, ". Connection code may wish to ", <$format, ["tt", [], ["suspend()"], 'do_tt]>, " after calling ", <$format, ["tt", [], ["open_connection()"], 'do_tt]>, ", then have the method ", <$format, ["tt", [], [".connect()"], 'do_tt]>, " resume the task when it is received. ", <$format, ["np", [], [], 'do_np]>, "If the connection could not be established, the method ", <$format, ["tt", [], [".failed()"], 'do_tt]>, " is called instead. The first argument is once again the task id, the second argument is an ERROR representing why the connection could not be established. ", <$format, ["np", [], [], 'do_np]>, "Once the connection is established, input and output is handled the same as on a server connection."], #[['this, $help_coldc_net_client]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_net_client];
var $help_node nolist = 0;


new object $help_coldc_regexp: $help_coldc_imp;

var $root manager = $help_coldc_regexp;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058118;
var $has_name name = ['prop, "Regexps|Regular Expressions", "Regexps|Regular Expressions"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdC Regular Expressions use Henry Spencer's Regular Expression package with further extensions similar to those Perl has implemented. ", <$format, ["np", [], [], 'do_np]>, "A Regular Expression is an abstract way of matching text. The simplest Regular Expression is a direct match. For instance, the string \"that\" exists within the string \"this and that are here.\", therefore \"that\" is a Regular Expression. ", <$format, ["np", [], [], 'do_np]>, "However, regular expressions can be much more complex than this case, as there are many possibilities which may be matched in strings. Wildcard matching is a common way of matching more than a simple instance of text. Wildcard matching generally matches any number of anything where a ", <$format, ["tt", [], ["`*'"], 'do_tt]>, " is found in the wildcard. Although useful it does have its restrictions. Wildcard matching is not used in Regular Expressions because of its lack of control. ", <$format, ["subj", [["level", "2"]], ["ColdC Regular Expressions Explained"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "The first concept of Regular Expressions are ", <$format, ["i", [], ["branches"], 'do_i]>, ". There can be zero or more ", <$format, ["i", [], ["branches"], 'do_i]>, " in a Regular Expression, seperated by the pipe character (\"|\"). A Regular Expression will match anything in one of the branches. An example of this is:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["this|that|there"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This Regular Expression will match \"this\" OR \"that\" OR \"there\". It is easiest to logically think of branches in this manner. ", <$format, ["np", [], [], 'do_np]>, "A branch is further defined as zero or more ", <$format, ["i", [], ["pieces"], 'do_i]>, " joined together. A ", <$format, ["i", [], ["piece"], 'do_i]>, " is an ", <$format, ["i", [], ["atom"], 'do_i]>, " possibly followed by an asterisk, a plus sign, or a question mark (\"*\", \"+\", or \"?\"). The asterisk, plus sign, or question mark defines how to match the atom. An atom followed by an asterisk matches zero or more occurances of the atom. An atom followed by a plus sign matches one or more occurances of the atom. An atom followed by a question mark matches zero or one occurance of the atom. ", <$format, ["np", [], [], 'do_np]>, "An ", <$format, ["i", [], ["atom"], 'do_i]>, " is either a Regular Expression in parentheses, a range (see below), or one of the following: a period (\".\"), a carat (\"^\"), a dollar sign (\"$\"), a back-slash (\"\") followed by a single character, or a single character with no other significance. A period matches any single character in the input text, a carat matches the beginning of the input text, a dollar-sign matches the end of the input text, and a back-slash followed by a single character either has special significance--such as matching all white space or all digits--or it removes special significance from the following character. For instance, \"$\" would match a dollar-sign in the input text, rather than matching the end of the line (which is what the dollar-sign usually does). The following characters have special meaning when matching (similar to PERL Regular Expressions): ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "10%,90%"]], [<$format, ["tr", [], [<$format, ["td", [], ["\"\w\""], 'do_td]>, <$format, ["td", [], ["Match a word word character (alphanumeric plus \"_\")"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["\"\W\""], 'do_td]>, <$format, ["td", [], ["Match a non-word character"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["\"\s\""], 'do_td]>, <$format, ["td", [], ["Match a whitespace character"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["\"\S\""], 'do_td]>, <$format, ["td", [], ["Match a non-whitespace character"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["\"\d\""], 'do_td]>, <$format, ["td", [], ["Match a digit character"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["\"\D\""], 'do_td]>, <$format, ["td", [], ["Match a non-digit character"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, <$format, ["i", [], ["Note: the above escape characters have not yet been integrated into the regular expression matcher."], 'do_i]>, " ", <$format, ["np", [], [], 'do_np]>, "A range is a sequence of characters enclosed in square brackets (", <$format, ["tt", [], ["\"[]\""], 'do_tt]>, "). It normally matches any single character contained within the range sequence. Characters which normally have special significance (such as a dollar-sign, period and a back-slash) loose that significance when enclosed in a range. However, a range has its own special characters. If the range begins with a carat (", <$format, ["tt", [], ["\"^\""], 'do_tt]>, "), it matches any single character which is ", <$format, ["i", [], ["not"], 'do_i]>, " in the sequence. If two characters in the sequence are separated by a dash (", <$format, ["tt", [], ["\"-\""], 'do_tt]>, "), the full range of ASCII characters between the two are matched, including the two. For instance, ", <$format, ["tt", [], ["\"[0-9]\""], 'do_tt]>, " matches any single decimal digit from zero to nine. To include a literal square bracket (", <$format, ["tt", [], ["\"]\""], 'do_tt]>, ") in the sequence do not use the back-slash to escape it (as the back-slash does not have special meaning when in a range), instead place it at the begining of the range (following a possible ", <$format, ["tt", [], ["\"^\""], 'do_tt]>, "). To include a literal dash (", <$format, ["tt", [], ["\"-\""], 'do_tt]>, ") place it the start or end of the range."], #[['this, $help_coldc_regexp]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_regexp];
var $help_node nolist = 0;


new object $help_coldc_files: $help_coldc_imp;

var $root manager = $help_coldc_files;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058124;
var $has_name name = ['prop, "Files", "Files"];
var $help_node links = #[["execute()", $help_func_execute], ["fchmod()", $help_func_fchmod], ["fclose()", $help_func_fclose], ["feof()", $help_func_feof], ["fflush()", $help_func_fflush], ["file()", $help_func_file], ["files()", $help_func_files], ["fmkdir()", $help_func_fmkdir], ["fopen()", $help_func_fopen], ["frmdir()", $help_func_frmdir], ["fstat()", $help_func_fstat], ["fread()", $help_func_fread], ["fremove()", $help_func_fremove], ["frename()", $help_func_frename], ["fseek()", $help_func_fseek], ["fwrite()", $help_func_fwrite]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdC gives the ability to handle files with the following functions: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "25%,25%,25%,25%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_execute"]], ["execute()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fchmod"]], ["fchmod()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fclose"]], ["fclose()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_feof"]], ["feof()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fflush"]], ["fflush()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_file"]], ["file()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_files"]], ["files()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fmkdir"]], ["fmkdir()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fopen"]], ["fopen()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_frmdir"]], ["frmdir()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fstat"]], ["fstat()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fread"]], ["fread()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fremove"]], ["fremove()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_frename"]], ["frename()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fseek"]], ["fseek()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fwrite"]], ["fwrite()"], 'do_link]>], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When a file is opened it is associated (i.e. bound) with the current object. Therefore, most file functions assume there is a file associated with the current object when used (such as ", <$format, ["tt", [], ["fwrite()"], 'do_tt]>, "). If there is not a file, the error ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "If the driver was compiled with ", <$format, ["tt", [], ["RESTRICTIVE_FILES"], 'do_tt]>, ", the driver will restrict where on the filesystem files can be manipulated (usually the ", <$format, ["tt", [], ["./root"], 'do_tt]>, " directory, with the exception of the function ", <$format, ["tt", [], ["execute()"], 'do_tt]>, ", which will use the directory ", <$format, ["tt", [], ["./dbbin"], 'do_tt]>, ". More information on where the directories are given in the ", <$format, ["a", [["href", "http\://www.cold.org/Genesis/"]], ["Genesis Manual"], 'do_a]>, "). ", <$format, ["np", [], [], 'do_np]>, "A file is opened using the function ", <$format, ["tt", [], ["fopen()"], 'do_tt]>, ", and is closed using the function ", <$format, ["tt", [], ["fclose()"], 'do_tt]>, ". Reaching the end of a file will not close it. Destroying the object for a file will close the file. ", <$format, ["np", [], [], 'do_np]>, "Example of opening, writing to and closing a simple text logfile:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["fopen(\"log\");\nfwrite(\"[\" + $time.format(\"%d %h %y %H:%M\") + \"] \" + message);\nfclose();"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Example of reading an image file:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["stat = fopen(\"image.gif\", \"-\");\nbuffer = fread(stat[2]);\nfclose();"], 'do_quote]>], 'do_dfn]>], #[['this, $help_coldc_files]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_files];
var $help_node nolist = 0;


new object $help_coldc_textdump: $help_coldc;

var $root manager = $help_coldc_textdump;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854926711;
var $has_name name = ['prop, "Textdump", "Textdump"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[['this, $help_coldc_textdump]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_textdump];
var $help_node nolist = 0;


new object $help_coldc_func: $help_coldc;

var $root manager = $help_coldc_func;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058130;
var $has_name name = ['prop, "Functions", "Functions"];
var $help_node links = #[["Buffer", $help_funcs_buf], ["Data", $help_funcs_data], ["Dictionary", $help_funcs_dict], ["Error", $help_funcs_err], ["File", $help_funcs_file], ["List", $help_funcs_list], ["Method", $help_funcs_meth], ["Misc", $help_funcs_misc], ["Network", $help_funcs_net], ["Numeric", $help_funcs_num], ["Object", $help_funcs_obj], ["String", $help_funcs_str], ["System", $help_funcs_sys], ["Task", $help_funcs_task], ["Variable", $help_funcs_var]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "18%,18%,18%,18%,18%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_buf"]], ["Buffer"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_data"]], ["Data"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_dict"]], ["Dictionary"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_err"]], ["Error"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_file"]], ["File"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_list"]], ["List"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_meth"]], ["Method"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_misc"]], ["Misc"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_net"]], ["Network"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_num"]], ["Numeric"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_obj"]], ["Object"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_str"]], ["String"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_sys"]], ["System"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_task"]], ["Task"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_funcs_var"]], ["Variable"], 'do_link]>], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_coldc_func]]]>;
var $root inited = 1;
var $root child_index = 16;
var $root managed = [$help_coldc_func];
var $help_node nolist = 0;

public method .generate_body() {
    var k, out, funcs, max, cols, col, x, f, fdict;
    
    (definer() == sender()) || (> .perms(sender()) <);
    if ((this() != definer()) && (!(definer() in parents())))
        throw(~ack, "Don't run this on " + this());
    if (this() == definer()) {
        for k in (children())
            k.generate_body();
    }
    out = "";
    funcs = children();
    fdict = #[];
    for f in (funcs) {
        for x in ((f.name()).explode("|"))
            fdict = dict_add(fdict, x, f);
    }
    funcs = (fdict.keys()).sort();
    max = ((fdict.keys()).element_maxlength()) + 4;
    cols = 75 / max;
    if (cols < 1) {
        $brandon.tell("fdict: " + (fdict.keys()));
        throw(~type, (("Columns are less than one: " + cols) + " ") + max);
    }
    col = toint((max / 75.0) * 100) + "%";
    out += "{table cols=" + col;
    if (cols > 1)
        out += ("," + col) * (cols - 1);
    out += ":";
    while (funcs) {
        refresh();
        out += "{tr:";
        for x in [1 .. cols] {
            out += "{td:";
            if (funcs) {
                f = funcs[1];
                funcs = delete(funcs, 1);
                out += ((("{link node=" + (fdict[f])) + ":") + f) + "}";
            }
            out += "}";
        }
        out += "}";
    }
    out += "}";
    .set_body(out);
    
    // $#Edited: 14 Feb 97 22:52 $brandon
};


new object $help_funcs_var: $help_coldc_func;

var $root manager = $help_funcs_var;
var $root child_index = 6;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384020;
var $has_name name = ['prop, "Variable", "Variable"];
var $help_node links = #[["add_var()", $help_func_add_var], ["clear_var()", $help_func_clear_var], ["del_var()", $help_func_del_var], ["get_var()", $help_func_get_var], ["set_var()", $help_func_set_var], ["variables()", $help_func_variables]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "20%,20%,20%,20%,20%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_add_var"]], ["add_var()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_clear_var"]], ["clear_var()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_del_var"]], ["del_var()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_get_var"]], ["get_var()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_var"]], ["set_var()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_variables"]], ["variables()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_var]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_var];
var $help_node nolist = 0;


new object $help_func_add_var: $help_funcs_var;

var $root manager = $help_func_add_var;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "add_var()", "add_var()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " add_var(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function defines an object variable on the current object. The name of the variable is defined by the symbol ", <$format, ["i", [], ["name"], 'do_i]>, ". If an object variable already exists by the desired name, the error ", <$format, ["tt", [], ["~varexists"], 'do_tt]>, " is thrown. ", <$format, ["tt", [], ["add_var()"], 'do_tt]>, " returns ", <$format, ["tt", [], ["1"], 'do_tt]>, " if it is successful."], #[['this, $help_func_add_var]]]>;
var $root inited = 1;
var $root managed = [$help_func_add_var];
var $help_node nolist = 0;


new object $help_func_clear_var: $help_funcs_var;

var $root manager = $help_func_clear_var;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "clear_var()", "clear_var()"];
var $help_node links = #[["Objects and Variables", $help_coldc_objs_vars]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " clear_var(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function clears the instance of an object variable, on a descendant. The variable specified by ", <$format, ["i", [], ["name"], 'do_i]>, " must be defined on the same ancestor defining the method which is calling ", <$format, ["tt", [], ["clear_var()"], 'do_tt]>, ". If not, the error ", <$format, ["tt", [], ["~varnf"], 'do_tt]>, " is thrown. If this function is not called before an an ancestor is removed, variables defined on that ancestor and set on the current object ", <$format, ["i", [], ["will remain"], 'do_i]>, " (due to encapsulation). This function is also useful in reducing database usage, as a cleared variable takes up no space, where a set variable (even to a value of ", <$format, ["tt", [], ["0"], 'do_tt]>, ") does. Upon successful execution ", <$format, ["tt", [], ["clear_var()"], 'do_tt]>, " returns ", <$format, ["tt", [], ["1"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "See the section ", <$format, ["link", [["node", "$help_coldc_objs_vars"]], ["Objects and Variables"], 'do_link]>, " for more information on the instance of an object variable."], #[['this, $help_func_clear_var]]]>;
var $root inited = 1;
var $root managed = [$help_func_clear_var];
var $help_node nolist = 0;


new object $help_func_del_var: $help_funcs_var;

var $root manager = $help_func_del_var;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "del_var()", "del_var()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " del_var(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function deletes the object variable pointed to by the argument ", <$format, ["i", [], ["name"], 'do_i]>, " defined on the current object (it does not delete an instance of a variable). If the object variable is not defined on the current object, the error ", <$format, ["tt", [], ["~varnf"], 'do_tt]>, " is thrown. Upon successful execution ", <$format, ["tt", [], ["del_var()"], 'do_tt]>, " returns ", <$format, ["tt", [], ["1"], 'do_tt]>, "."], #[['this, $help_func_del_var]]]>;
var $root inited = 1;
var $root managed = [$help_func_del_var];
var $help_node nolist = 0;


new object $help_func_get_var: $help_funcs_var;

var $root manager = $help_func_get_var;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "get_var()", "get_var()"];
var $help_node links = #[["Variable Expressions", $help_coldc_vars]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ANY"], 'do_i]>, " get_var(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the current object's instance of the object variable specified to by the argument ", <$format, ["i", [], ["name"], 'do_i]>, ". The variable must be defined on the same object which defined the method which calls ", <$format, ["tt", [], ["get_var()"], 'do_tt]>, ". If the object variable is not defined, the error ", <$format, ["tt", [], ["~varnf"], 'do_tt]>, " is thrown. Otherwise the current object's value for the variable is returned. ", <$format, ["np", [], [], 'do_np]>, "This is an obtuse way of retrieving the value of an object variable, and is generally only used when there is confusion with a local variable. For more information see ", <$format, ["link", [["node", "$help_coldc_vars"]], ["Variable Expressions"], 'do_link]>, "."], #[['this, $help_func_get_var]]]>;
var $root inited = 1;
var $root managed = [$help_func_get_var];
var $help_node nolist = 0;


new object $help_func_set_var: $help_funcs_var;

var $root manager = $help_func_set_var;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "set_var()", "set_var()"];
var $help_node links = #[["assignment operator", $help_coldc_assign]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ANY"], 'do_i]>, " set_var(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ", ", <$format, ["i", [], ["ANY value"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function sets the instance of an object variable on the current object. The variable must be defined on the same object which defined the method which calls ", <$format, ["tt", [], ["set_var()"], 'do_tt]>, ". Using this function is the same as using the ", <$format, ["link", [["node", "$help_coldc_assign"]], ["assignment operator"], 'do_link]>, ". If the object variable is not defined, the error ", <$format, ["tt", [], ["~varnf"], 'do_tt]>, " is thrown. The return value for ", <$format, ["tt", [], ["set_var()"], 'do_tt]>, " is the second argument ", <$format, ["tt", [], ["value"], 'do_tt]>, ". The following two examples are equivalent:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["set_var('time_stamp, time())", <$format, ["br", [], [], 'do_br]>, "=> 855723496"], 'do_dfn]>, " ", <$format, ["dfn", [], ["time_stamp = time()"], 'do_dfn]>], #[['this, $help_func_set_var]]]>;
var $root inited = 1;
var $root managed = [$help_func_set_var];
var $help_node nolist = 0;


new object $help_func_variables: $help_funcs_var;

var $root manager = $help_func_variables;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384460;
var $has_name name = ['prop, "variables()", "variables()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " variables()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is used to determine all of the object variables defined on the current object (not the instances of all variables). A list of symbols naming each variable is returned."], #[['this, $help_func_variables]]]>;
var $root inited = 1;
var $root managed = [$help_func_variables];
var $help_node nolist = 0;


new object $help_funcs_meth: $help_coldc_func;

var $root manager = $help_funcs_meth;
var $root child_index = 14;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Method", "Method"];
var $help_node links = #[["add_method()", $help_func_add_method], ["del_method()", $help_func_del_method], ["find_method()", $help_func_find_method], ["find_next_method()", $help_func_find_next_method], ["list_method()", $help_func_list_method], ["method_access()", $help_func_method_access], ["method_bytecode()", $help_func_method_bytecode], ["method_flags()", $help_func_method_flags], ["method_info()", $help_func_method_info], ["methods()", $help_func_methods], ["rename_method()", $help_func_rename_method], ["set_method_access()", $help_func_set_method_access], ["set_method_flags()", $help_func_set_method_flags]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "30%,30%,30%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_add_method"]], ["add_method()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_del_method"]], ["del_method()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_find_method"]], ["find_method()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_find_next_method"]], ["find_next_method()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_list_method"]], ["list_method()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_method_access"]], ["method_access()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_method_bytecode"]], ["method_bytecode()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_method_flags"]], ["method_flags()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_method_info"]], ["method_info()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_methods"]], ["methods()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_rename_method"]], ["rename_method()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_method_access"]], ["set_method_access()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_method_flags"]], ["set_method_flags()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_meth]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_meth];
var $help_node nolist = 0;


new object $help_func_add_method: $help_funcs_meth;

var $root manager = $help_func_add_method;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "add_method()", "add_method()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " add_method(", <$format, ["i", [], ["LIST code"], 'do_i]>, ", ", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function compiles ", <$format, ["i", [], ["code"], 'do_i]>, " (which should be a list of strings) and uses the result as the definition of the method named by the symbol ", <$format, ["i", [], ["name"], 'do_i]>, ". If there were errors in compiling, a list of strings describing the errors is returned, otherwise an empty list is returned. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["add_method([\"cwrite(\\\"foo\\\");\"], 'foo)", <$format, ["br", [], [], 'do_br]>, "=> [] ", <$format, ["np", [], [], 'do_np]>, "add_method([\"cwrite(\\\"foo\\\")\"], 'foo)", <$format, ["br", [], [], 'do_br]>, "=> [\"Line 2: parse error\"]"], 'do_tt]>], 'do_dfn]>], #[['this, $help_func_add_method]]]>;
var $root inited = 1;
var $root managed = [$help_func_add_method];
var $help_node nolist = 0;


new object $help_func_list_method: $help_funcs_meth;

var $root manager = $help_func_list_method;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "list_method()", "list_method()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " list_method(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER indent"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER flags"], 'do_i]>, "]])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is used to decompile a method. It accepts a symbol, assuming it to be the name of a method. If the method is defined on the current object it is decompiled and returned as a list of strings. If the method is not found, the error ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "The second argument ", <$format, ["i", [], ["indent"], 'do_i]>, " can be given to specify an alternate indentation to use (default is four spaces). The third argument can be specified to change the default formatting behaviour. The argument is an integer which can have three different values:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], ["1"], 'do_dt]>, <$format, ["dd", [], ["Full Parenthesis"], 'do_dd]>, <$format, ["dt", [], ["2"], 'do_dt]>, <$format, ["dd", [], ["Full Braces"], 'do_dd]>, <$format, ["dt", [], ["3"], 'do_dt]>, <$format, ["dd", [], ["Full Parenthesis and Braces"], 'do_dd]>], 'do_dl]>], #[['this, $help_func_list_method]]]>;
var $root inited = 1;
var $root managed = [$help_func_list_method];
var $help_node nolist = 0;


new object $help_func_del_method: $help_funcs_meth;

var $root manager = $help_func_del_method;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "del_method()", "del_method()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " del_method(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function removes the method named by the symbol ", <$format, ["i", [], ["name"], 'do_i]>, " from the current object. ", <$format, ["tt", [], ["del_method()"], 'do_tt]>, " returns ", <$format, ["tt", [], ["1"], 'do_tt]>, " if there was a method named ", <$format, ["i", [], ["name"], 'do_i]>, " on the current object; otherwise, a ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " error is thrown."], #[['this, $help_func_del_method]]]>;
var $root inited = 1;
var $root managed = [$help_func_del_method];
var $help_node nolist = 0;


new object $help_func_find_method: $help_funcs_meth;

var $root manager = $help_func_find_method;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "find_method()", "find_method()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " find_method(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function searches for the first occurance of the method named by the symbol ", <$format, ["i", [], ["name"], 'do_i]>, ", on an ancestor of the current object. If a method is found, the ancestor is returned. Otherwise the error ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " is thrown."], #[['this, $help_func_find_method]]]>;
var $root inited = 1;
var $root managed = [$help_func_find_method];
var $help_node nolist = 0;


new object $help_func_find_next_method: $help_funcs_meth;

var $root manager = $help_func_find_next_method;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "find_next_method()", "find_next_method()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " find_next_method(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ", ", <$format, ["i", [], ["OBJNUM after"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function searches for the occurance of the method named by the symbol ", <$format, ["i", [], ["name"], 'do_i]>, ", after the ancestor ", <$format, ["i", [], ["after"], 'do_i]>, ". If a method is found, the ancestor is returned. Otherwise the error ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " is thrown."], #[['this, $help_func_find_next_method]]]>;
var $root inited = 1;
var $root managed = [$help_func_find_next_method];
var $help_node nolist = 0;


new object $help_func_method_bytecode: $help_funcs_meth;

var $root manager = $help_func_method_bytecode;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "method_bytecode()", "method_bytecode()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " method_bytecode(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Returns the bytecode for the specified method, defined on the current object. For instance, consider the following method: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\npublic method .test() {\n    return \"test\";\n};"], 'do_quote]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Would return the following bytecode:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["method_bytecode('test)", <$format, ["br", [], [], 'do_br]>, "=> ['STRING, \"test\", 'RETURN_EXPR, 'RETURN]"], 'do_dfn]>], #[['this, $help_func_method_bytecode]]]>;
var $root inited = 1;
var $root managed = [$help_func_method_bytecode];
var $help_node nolist = 0;


new object $help_func_method_access: $help_funcs_meth;

var $root manager = $help_func_method_access;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "method_access()", "method_access()"];
var $help_node links = #[["Methods", $help_coldc_methods]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["SYMBOL"], 'do_i]>, " method_access(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the method access for the method specified with the argument ", <$format, ["i", [], ["name"], 'do_i]>, ". See ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Methods"], 'do_link]>, " for more information on method access."], #[['this, $help_func_method_access]]]>;
var $root inited = 1;
var $root managed = [$help_func_method_access];
var $help_node nolist = 0;


new object $help_func_method_flags: $help_funcs_meth;

var $root manager = $help_func_method_flags;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "method_flags()", "method_flags()"];
var $help_node links = #[["Defining Methods", $help_coldc_methods]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " method_flags(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function finds the method specified with the argument ", <$format, ["i", [], ["name"], 'do_i]>, " and returns the list of flags currently set on the method. Method flags are fully explained in the section on ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Defining Methods"], 'do_link]>, ". If the method ", <$format, ["i", [], ["name"], 'do_i]>, " cannot be found, the error ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " is thrown."], #[['this, $help_func_method_flags]]]>;
var $root inited = 1;
var $root managed = [$help_func_method_flags];
var $help_node nolist = 0;


new object $help_func_method_info: $help_funcs_meth;

var $root manager = $help_func_method_info;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "method_info()", "method_info()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " method_info(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a list of miscellaneous information on the method named by ", <$format, ["i", [], ["name"], 'do_i]>, ". If the method is not found, the error ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " is thrown. Otherwise a list is returned. The elements in the list are (in order):", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["STRING args"], 'do_li]>, <$format, ["li", [], ["INTEGER number of arguments"], 'do_li]>, <$format, ["li", [], ["INTEGER number of local variables defined"], 'do_li]>, <$format, ["li", [], ["INTEGER number of opcodes used"], 'do_li]>, <$format, ["li", [], ["SYMBOL method access"], 'do_li]>, <$format, ["li", [], ["LIST method flags"], 'do_li]>], 'do_ol]>], #[['this, $help_func_method_info]]]>;
var $root inited = 1;
var $root managed = [$help_func_method_info];
var $help_node nolist = 0;


new object $help_func_methods: $help_funcs_meth;

var $root manager = $help_func_methods;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "methods()", "methods()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " methods()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a list of symbols naming each method defined on the current object."], #[['this, $help_func_methods]]]>;
var $root inited = 1;
var $root managed = [$help_func_methods];
var $help_node nolist = 0;


new object $help_func_rename_method: $help_funcs_meth;

var $root manager = $help_func_rename_method;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "rename_method()", "rename_method()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " rename_method(", <$format, ["i", [], ["SYMBOL old_name"], 'do_i]>, ", ", <$format, ["i", [], ["SYMBOL new_name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function changes the name of the method on the current object, specified by the argument ", <$format, ["i", [], ["old_name"], 'do_i]>, ", and changes it to the name specified by the argument ", <$format, ["i", [], ["new_name"], 'do_i]>, ". If no method can be found by the name ", <$format, ["i", [], ["old_name"], 'do_i]>, ", the error ", <$format, ["tt", [], ["~methodnf"], 'do_tt]>, " is thrown."], #[['this, $help_func_rename_method]]]>;
var $root inited = 1;
var $root managed = [$help_func_rename_method];
var $help_node nolist = 0;


new object $help_func_set_method_access: $help_funcs_meth;

var $root manager = $help_func_set_method_access;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "set_method_access()", "set_method_access()"];
var $help_node links = #[["Methods", $help_coldc_methods]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " set_method_access(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ", ", <$format, ["i", [], ["SYMBOL access"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function sets the method access for the method ", <$format, ["i", [], ["name"], 'do_i]>, ". See ", <$format, ["link", [["node", "$help_coldc_methods"]], ["Methods"], 'do_link]>, " for more information on method access."], #[['this, $help_func_set_method_access]]]>;
var $root inited = 1;
var $root managed = [$help_func_set_method_access];
var $help_node nolist = 0;


new object $help_func_set_method_flags: $help_funcs_meth;

var $root manager = $help_func_set_method_flags;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "set_method_flags()", "set_method_flags()"];
var $help_node links = #[["Method Flags", $help_coldc_methods_flags]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " set_method_flags(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ", ", <$format, ["i", [], ["LIST flags"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function sets the method flags for the method specified with the first argument ", <$format, ["i", [], ["name"], 'do_i]>, ". The flags are specified as a list of symbols in ", <$format, ["i", [], ["flags"], 'do_i]>, ". Full information on method flags can be found in the section ", <$format, ["link", [["node", "$help_coldc_methods_flags"]], ["Method Flags"], 'do_link]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["set_method_flags('tell, ['nooverride])", <$format, ["br", [], [], 'do_br]>, "=> 1"], 'do_dfn]>], #[['this, $help_func_set_method_flags]]]>;
var $root inited = 1;
var $root managed = [$help_func_set_method_flags];
var $help_node nolist = 0;


new object $help_funcs_obj: $help_coldc_func;

var $root manager = $help_funcs_obj;
var $root child_index = 14;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Object", "Object"];
var $help_node links = #[["ancestors()", $help_func_ancestors], ["children()", $help_func_children], ["chparents()", $help_func_chparents], ["create()", $help_func_create], ["data()", $help_func_data], ["del_objname()", $help_func_del_objname], ["destroy()", $help_func_destroy], ["has_ancestor()", $help_func_has_ancestor], ["lookup()", $help_func_lookup], ["objname()", $help_func_objname], ["objnum()", $help_func_objnum], ["parents()", $help_func_parents], ["set_objname()", $help_func_set_objname]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "24%,24%,24%,24%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_ancestors"]], ["ancestors()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_children"]], ["children()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_chparents"]], ["chparents()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_create"]], ["create()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_data"]], ["data()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_del_objname"]], ["del_objname()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_destroy"]], ["destroy()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_has_ancestor"]], ["has_ancestor()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_lookup"]], ["lookup()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_objname"]], ["objname()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_objnum"]], ["objnum()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_parents"]], ["parents()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_objname"]], ["set_objname()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_obj]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_obj];
var $help_node nolist = 0;


new object $help_func_ancestors: $help_funcs_obj;

var $root manager = $help_func_ancestors;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "ancestors()", "ancestors()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " ancestors()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a list of the objnums of the ancestors of the current object, in the order that they would normally be searched for methods. The objnums of the current object will be the first element of the list."], #[['this, $help_func_ancestors]]]>;
var $root inited = 1;
var $root managed = [$help_func_ancestors];
var $help_node nolist = 0;


new object $help_func_children: $help_funcs_obj;

var $root manager = $help_func_children;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "children()", "children()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " children()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a list of object numbers for the children of the current object, in no particular order."], #[['this, $help_func_children]]]>;
var $root inited = 1;
var $root managed = [$help_func_children];
var $help_node nolist = 0;


new object $help_func_chparents: $help_funcs_obj;

var $root manager = $help_func_chparents;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "chparents()", "chparents()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " chparents(", <$format, ["i", [], ["LIST parents"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function changes the parents of the current object to the list of objnums in ", <$format, ["i", [], ["parents"], 'do_i]>, ". If any of the objnums in ", <$format, ["i", [], ["parents"], 'do_i]>, " do not refer to an existing object, then the error ", <$format, ["tt", [], ["~objnf"], 'do_tt]>, " is thrown. If any of the parents have the current object as an ancestor, or are the current object, then the error ", <$format, ["tt", [], ["~parent"], 'do_tt]>, " is thrown. If ", <$format, ["i", [], ["parents"], 'do_i]>, " is an empty list, then ", <$format, ["tt", [], ["~perm"], 'do_tt]>, " is thrown. Otherwise a ", <$format, ["tt", [], ["1"], 'do_tt]>, " is returned."], #[['this, $help_func_chparents]]]>;
var $root inited = 1;
var $root managed = [$help_func_chparents];
var $help_node nolist = 0;


new object $help_func_create: $help_funcs_obj;

var $root manager = $help_func_create;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "create()", "create()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " create(", <$format, ["i", [], ["LIST parents"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function creates and returns the objnum of an object with the parents in the list ", <$format, ["i", [], ["parents"], 'do_i]>, ", which should be a list of objnums referring to existing objects. If any of the parent objnums do not refer to existing objects, then ", <$format, ["tt", [], ["create()"], 'do_tt]>, " throws the error ", <$format, ["tt", [], ["~objnf"], 'do_tt]>, "."], #[['this, $help_func_create]]]>;
var $root inited = 1;
var $root managed = [$help_func_create];
var $help_node nolist = 0;


new object $help_func_data: $help_funcs_obj;

var $root manager = $help_func_data;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "data()", "data()"];
var $help_node links = #[["clear_var()", $help_func_clear_var]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["DICTIONARY"], 'do_i]>, " data([", <$format, ["i", [], ["OBJNUM ancestor"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This administrative function is used to retrieve all instances of object variables the current object has, as well as the values of any object variable they define. If ", <$format, ["i", [], ["ancestor"], 'do_i]>, " is not defined it will return ", <$format, ["i", [], ["all"], 'do_i]>, " instances defined by any ancestor. If ", <$format, ["i", [], ["ancestor"], 'do_i]>, " is defined it will only return data which is defined by the specific ancestor. ", <$format, ["np", [], [], 'do_np]>, "The data is returned in a dictionary, where each object variable is a key and the association to the key is the value for the object variable. If no ancestor is specified and all instances are returned, each ancestor's values are contained within another dictionary, where the key is the ancestor. ", <$format, ["np", [], [], 'do_np]>, "If an ancestor defines an object variable, but no instance of that variable has been created for the current object (or the instance has been cleared with the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_clear_var"]], ["clear_var()"], 'do_link]>], 'do_tt]>, "), it is not included in the dictionary. ", <$format, ["np", [], [], 'do_np]>, "The keys in a dictionary returned by ", <$format, ["tt", [], ["data()"], 'do_tt]>, " do not have any particular ordering."], #[['this, $help_func_data]]]>;
var $root inited = 1;
var $root managed = [$help_func_data];
var $help_node nolist = 0;


new object $help_func_del_objname: $help_funcs_obj;

var $root manager = $help_func_del_objname;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "del_objname()", "del_objname()"];
var $help_node links = #[["Referencing Objects", $help_coldc_objs_ref]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " del_objname()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function deletes an objname associated with the current object. When an objname is deleted the object may only be referenced with it's objnum (for more information on objnames and objnums read ", <$format, ["link", [["node", "$help_coldc_objs_ref"]], ["Referencing Objects"], 'do_link]>, "). If the current object does not have an objname, the error ", <$format, ["tt", [], ["~namenf"], 'do_tt]>, " is thrown."], #[['this, $help_func_del_objname]]]>;
var $root inited = 1;
var $root managed = [$help_func_del_objname];
var $help_node nolist = 0;


new object $help_func_destroy: $help_funcs_obj;

var $root manager = $help_func_destroy;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "destroy()", "destroy()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " destroy()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function marks the current object for removal from the database. The object is destroyed when all methods executing on it are completed (suspended and preempted methods as well as the current task). Objects left orphaned by the destruction of their only parent are reparented to the parents of the parent which was destroyed. ", <$format, ["np", [], [], 'do_np]>, "Attempts to destroy the root or system objects will fail with the error ", <$format, ["tt", [], ["~perm"], 'do_tt]>, "."], #[['this, $help_func_destroy]]]>;
var $root inited = 1;
var $root managed = [$help_func_destroy];
var $help_node nolist = 0;


new object $help_func_has_ancestor: $help_funcs_obj;

var $root manager = $help_func_has_ancestor;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "has_ancestor()", "has_ancestor()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " has_ancestor(", <$format, ["i", [], ["OBJNUM ancestor"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns one (1) if the current object has ", <$format, ["i", [], ["ancestor"], 'do_i]>, " as an ancestor, or zero (0) if it does not."], #[['this, $help_func_has_ancestor]]]>;
var $root inited = 1;
var $root managed = [$help_func_has_ancestor];
var $help_node nolist = 0;


new object $help_func_lookup: $help_funcs_obj;

var $root manager = $help_func_lookup;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "lookup()", "lookup()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " lookup(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function finds the object number for the object name specified by the argument ", <$format, ["i", [], ["name"], 'do_i]>, ". If no object exists with that name, the error ", <$format, ["tt", [], ["~namenf"], 'do_tt]>, " is thrown. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["lookup('root)", <$format, ["br", [], [], 'do_br]>, "=> #1"], 'do_dfn]>], #[['this, $help_func_lookup]]]>;
var $root inited = 1;
var $root managed = [$help_func_lookup];
var $help_node nolist = 0;


new object $help_func_objname: $help_funcs_obj;

var $root manager = $help_func_objname;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "objname()", "objname()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["SYMBOL"], 'do_i]>, " objname()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the symbol representation of the current object's name. If the current object does not have an object name assigned, this function throws the error ", <$format, ["tt", [], ["~namenf"], 'do_tt]>, "."], #[['this, $help_func_objname]]]>;
var $root inited = 1;
var $root managed = [$help_func_objname];
var $help_node nolist = 0;


new object $help_func_objnum: $help_funcs_obj;

var $root manager = $help_func_objnum;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "objnum()", "objnum()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " objnum()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns an integer representing the current object's object number."], #[['this, $help_func_objnum]]]>;
var $root inited = 1;
var $root managed = [$help_func_objnum];
var $help_node nolist = 0;


new object $help_func_parents: $help_funcs_obj;

var $root manager = $help_func_parents;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "parents()", "parents()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " parents()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a list of the objnums for the parents of the current object."], #[['this, $help_func_parents]]]>;
var $root inited = 1;
var $root managed = [$help_func_parents];
var $help_node nolist = 0;


new object $help_func_set_objname: $help_funcs_obj;

var $root manager = $help_func_set_objname;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "set_objname()", "set_objname()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " set_objname(", <$format, ["i", [], ["SYMBOL name"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function sets the argument ", <$format, ["i", [], ["name"], 'do_i]>, " as the current object's objname. If another object already has the object name ", <$format, ["i", [], ["name"], 'do_i]>, ", the error ", <$format, ["tt", [], ["~error"], 'do_tt]>, " is thrown. If the current object already has an object name, it is replaced with the new name. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["set_objname('user_bob)", <$format, ["br", [], [], 'do_br]>, "=> 1"], 'do_dfn]>], #[['this, $help_func_set_objname]]]>;
var $root inited = 1;
var $root managed = [$help_func_set_objname];
var $help_node nolist = 0;


new object $help_funcs_sys: $help_coldc_func;

var $root manager = $help_funcs_sys;
var $root child_index = 5;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "System", "System"];
var $help_node links = #[["anticipate_assignment()", $help_func_anticipate_assignment], ["backup()", $help_func_backup], ["config()", $help_func_config], ["set_heartbeat()", $help_func_set_heartbeat], ["shutdown()", $help_func_shutdown]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "36%,36%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_anticipate_assignment"]], ["anticipate_assignment()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_backup"]], ["backup()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_config"]], ["config()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_heartbeat"]], ["set_heartbeat()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_shutdown"]], ["shutdown()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_sys]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_sys];
var $help_node nolist = 0;


new object $help_func_backup: $help_funcs_sys;

var $root manager = $help_func_backup;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "backup()", "backup()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " backup()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function syncronizes the running database to disk and starts an asyncrynous backup (Genesis copies the files to the file ", <$format, ["i", [], ["binary"], 'do_i]>, ".bak, where ", <$format, ["i", [], ["binary"], 'do_i]>, " is the binary database directory name specified upon bootup). This function executes atomically, and a slight pause may be noticed while it syncronizes the object cache to disk and copies the index files. ", <$format, ["np", [], [], 'do_np]>, "The return value of ", <$format, ["tt", [], ["backup()"], 'do_tt]>, " is always ", <$format, ["tt", [], ["1"], 'do_tt]>, ", and should be ignored. If a backup is in progress the error ", <$format, ["tt", [], ["~perm"], 'do_tt]>, " is thrown. The error ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown if there are file or directory problems. When the asyncrynous backup is finished the driver calls ", <$format, ["tt", [], ["$sys.backup_done()"], 'do_tt]>, "."], #[['this, $help_func_backup]]]>;
var $root inited = 1;
var $root managed = [$help_func_backup];
var $help_node nolist = 0;


new object $help_func_set_heartbeat: $help_funcs_sys;

var $root manager = $help_func_set_heartbeat;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "set_heartbeat()", "set_heartbeat()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " set_heartbeat(", <$format, ["i", [], ["INTEGER interval"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function sets the peridic heartbeat for the database to the argument ", <$format, ["i", [], ["interval"], 'do_i]>, ", where ", <$format, ["i", [], ["interval"], 'do_i]>, " is in the delay in seconds. The heartbeat can be disabled by setting the interval to zero or a negative number. The default heartbeat interval is five seconds. The heartbeat is sent by the driver calling the method ", <$format, ["tt", [], ["$sys.heartbeat()"], 'do_tt]>, "."], #[['this, $help_func_set_heartbeat]]]>;
var $root inited = 1;
var $root managed = [$help_func_set_heartbeat];
var $help_node nolist = 0;


new object $help_func_shutdown: $help_funcs_sys;

var $root manager = $help_func_shutdown;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855385300;
var $root managed = [$help_func_shutdown];
var $has_name name = ['prop, "shutdown()", "shutdown()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " shutdown()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function completes all of the current tasks, syncronizes the database, flushes all output and shuts down the server."], #[['this, $help_func_shutdown]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_anticipate_assignment: $help_funcs_sys;

var $root manager = $help_func_anticipate_assignment;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855388597;
var $root managed = [$help_func_anticipate_assignment];
var $has_name name = ['prop, "anticipate_assignment()", "anticipate_assignment()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " anticipate_assignment()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Do not use this unless you know exactly what you are doing, and how stacks and frames work in the ColdC driver. This function is used to reduce the amount of references to data on the stack, in order to keep from unecessarily copying data. Essentially it is meant to optimize utility methods that will modify data and return the result, and the result is assigned to a variable. To keep from unecessarily copying the data the variable is cleared of any references before the data is modified."], #[['this, $help_func_anticipate_assignment]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_config: $help_funcs_sys;

var $root manager = $help_func_config;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855429715;
var $root managed = [$help_func_config];
var $has_name name = ['prop, "config()", "config()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ANY"], 'do_i]>, " config(", <$format, ["i", [], ["SYMBOL what"], 'do_i]>, "[, ", <$format, ["i", [], ["ANY value"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This administrative function is used to change run-time values for the driver and execution states. Current Genesis only partially implements this function--it recognizes the changes but does not fully comply with them. The value is specified with the argument ", <$format, ["i", [], ["what"], 'do_i]>, ". If no second argument is given the current value is returned. If a second argument is given, the value is set to that value, if appropriate--if the new value is inappropriate the error ", <$format, ["tt", [], ["~type"], 'do_tt]>, " is thrown. Values are: ", <$format, ["dfn", [["nobound", 1]], [<$format, ["table", [["cols", "20%,80%"]], [<$format, ["tr", [], [<$format, ["td", [], ["'datasize"], 'do_td]>, <$format, ["td", [], ["Maximum Data Size (in bytes)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["'forkdepth"], 'do_td]>, <$format, ["td", [], ["Maximum fork depth"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["'calldepth"], 'do_td]>, <$format, ["td", [], ["Maximum call depth"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["'recursion"], 'do_td]>, <$format, ["td", [], ["Maximum Swapping"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["'objswap"], 'do_td]>, <$format, ["td", [], ["Object Swapping"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['this, $help_func_config]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_funcs_task: $help_coldc_func;

var $root manager = $help_funcs_task;
var $root child_index = 22;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Task", "Task"];
var $help_node links = #[["atomic()", $help_func_atomic], ["call_trace()", $help_func_call_trace], ["caller()", $help_func_caller], ["cancel()", $help_func_cancel], ["debug_callers()", $help_func_debug_callers], ["definer()", $help_func_definer], ["method()", $help_func_method], ["pass()", $help_func_pass], ["pause()", $help_func_pause], ["refresh()", $help_func_refresh], ["resume()", $help_func_resume], ["sender()", $help_func_sender], ["set_user()", $help_func_set_user], ["stack()", $help_func_stack], ["suspend()", $help_func_suspend], ["task_id()", $help_func_task_id], ["task_info()", $help_func_task_info], ["tasks()", $help_func_tasks], ["this()", $help_func_this], ["tick()", $help_func_tick], ["ticks_left()", $help_func_ticks_left], ["user()", $help_func_user]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "25%,25%,25%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_atomic"]], ["atomic()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_call_trace"]], ["call_trace()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_caller"]], ["caller()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_cancel"]], ["cancel()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_debug_callers"]], ["debug_callers()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_definer"]], ["definer()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_method"]], ["method()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_pass"]], ["pass()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_pause"]], ["pause()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_refresh"]], ["refresh()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_resume"]], ["resume()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_sender"]], ["sender()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_set_user"]], ["set_user()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_stack"]], ["stack()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_suspend"]], ["suspend()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_task_id"]], ["task_id()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_task_info"]], ["task_info()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_tasks"]], ["tasks()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_this"]], ["this()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_tick"]], ["tick()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_ticks_left"]], ["ticks_left()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_user"]], ["user()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_task]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_task];
var $help_node nolist = 0;


new object $help_func_atomic: $help_funcs_task;

var $root manager = $help_func_atomic;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "atomic()", "atomic()"];
var $help_node links = #[["refresh()", $help_func_refresh], ["Frames and Tasks", $help_coldc_tasks]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " atomic(", <$format, ["i", [], ["INTEGER goatomic"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is used to turn on and off atomic execution. When executing atomically ", <$format, ["i", [], ["no other tasks will be run"], 'do_i]>, ". This also means that any function that normally preempts will throw an error (with the exception of ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_refresh"]], ["refresh()"], 'do_link]>], 'do_tt]>, "). If the argument is false (zero) the interpreter stops executing atomically. If the argument is true (non-zero) the interpreter starts executing atomically. Note: ", <$format, ["i", [], ["read the section ", <$format, ["link", [["node", "$help_coldc_tasks"]], ["Frames and Tasks"], 'do_link]>], 'do_i]>, " before using ", <$format, ["tt", [], ["atomic()"], 'do_tt]>, "."], #[['this, $help_func_atomic]]]>;
var $root inited = 1;
var $root managed = [$help_func_atomic];
var $help_node nolist = 0;


new object $help_func_caller: $help_funcs_task;

var $root manager = $help_func_caller;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "caller()", "caller()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " caller()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the objnum of the object which defines the method which called the current method. If the current method was called by the driver zero (0) is returned instead."], #[['this, $help_func_caller]]]>;
var $root inited = 1;
var $root managed = [$help_func_caller];
var $help_node nolist = 0;


new object $help_func_cancel: $help_funcs_task;

var $root manager = $help_func_cancel;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "cancel()", "cancel()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " cancel(", <$format, ["i", [], ["INTEGER task_id"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function cancels the suspended or preempted task with the task id given by ", <$format, ["i", [], ["task_id"], 'do_i]>, ". If the task does not exist, ", <$format, ["tt", [], ["~type"], 'do_tt]>, " is thrown."], #[['this, $help_func_cancel]]]>;
var $root inited = 1;
var $root managed = [$help_func_cancel];
var $help_node nolist = 0;


new object $help_func_definer: $help_funcs_task;

var $root manager = $help_func_definer;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "definer()", "definer()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " definer()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the objnum of the object which defines the current method."], #[['this, $help_func_definer]]]>;
var $root inited = 1;
var $root managed = [$help_func_definer];
var $help_node nolist = 0;


new object $help_func_method: $help_funcs_task;

var $root manager = $help_func_method;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "method()", "method()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["SYMBOL"], 'do_i]>, " method()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the name of the current method, as a symbol."], #[['this, $help_func_method]]]>;
var $root inited = 1;
var $root managed = [$help_func_method];
var $help_node nolist = 0;


new object $help_func_pause: $help_funcs_task;

var $root manager = $help_func_pause;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "pause()", "pause()"];
var $help_node links = #[["Frames and Tasks", $help_coldc_tasks]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " pause()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function instantly preempts the current task, letting other tasks execute before it resumes execution with a refreshed tick count. See ", <$format, ["link", [["node", "$help_coldc_tasks"]], ["Frames and Tasks"], 'do_link]>, " for more information on preempting and task control."], #[['this, $help_func_pause]]]>;
var $root inited = 1;
var $root managed = [$help_func_pause];
var $help_node nolist = 0;


new object $help_func_refresh: $help_funcs_task;

var $root manager = $help_func_refresh;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "refresh()", "refresh()"];
var $help_node links = #[["pause()", $help_func_pause], ["Frames and Tasks", $help_func_tasks]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " refresh()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When the server is running non-atomically this function checks the current frame's tick count and preempts the task if it is nearly depleted (similar to ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_pause"]], ["pause()"], 'do_link]>], 'do_tt]>, "), resuming it with a new tick count after all other current tasks have completed, otherwise it does nothing. If the server is running atomically the task will not preempt, but the tick count will automatically be refreshed. See ", <$format, ["link", [["node", "$help_func_tasks"]], ["Frames and Tasks"], 'do_link]>, " for more information on task preempting."], #[['this, $help_func_refresh]]]>;
var $root inited = 1;
var $root managed = [$help_func_refresh];
var $help_node nolist = 0;


new object $help_func_resume: $help_funcs_task;

var $root manager = $help_func_resume;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "resume()", "resume()"];
var $help_node links = #[["suspend()", $help_func_suspend], ["Frames and Tasks", $help_coldc_tasks]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], ["INTEGER resume(", <$format, ["i", [], ["INTEGER task_id"], 'do_i]>, "[, ", <$format, ["i", [], ["ANY value"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function resumes the suspended task specified by the argument ", <$format, ["i", [], ["task_id"], 'do_i]>, ". The error ", <$format, ["tt", [], ["~type"], 'do_tt]>, " is thrown if the task does not exist. The optional second argument ", <$format, ["i", [], ["value"], 'do_i]>, " is used as the return value for the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_suspend"]], ["suspend()"], 'do_link]>], 'do_tt]>, ". If a second argument is not specified the return value of ", <$format, ["tt", [], ["suspend()"], 'do_tt]>, " is zero. See ", <$format, ["link", [["node", "$help_coldc_tasks"]], ["Frames and Tasks"], 'do_link]>, " for more information on preempting and task control."], #[['this, $help_func_resume]]]>;
var $root inited = 1;
var $root managed = [$help_func_resume];
var $help_node nolist = 0;


new object $help_func_sender: $help_funcs_task;

var $root manager = $help_func_sender;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "sender()", "sender()"];
var $help_node links = #[["Tasks and Frames", $help_coldc_tasks]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " sender()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the objnum of the object which called the current method. If the current method was called by the driver, zero (0) is returned instead. Further information can be found in the section ", <$format, ["link", [["node", "$help_coldc_tasks"]], ["Tasks and Frames"], 'do_link]>, "."], #[['this, $help_func_sender]]]>;
var $root inited = 1;
var $root managed = [$help_func_sender];
var $help_node nolist = 0;


new object $help_func_stack: $help_funcs_task;

var $root manager = $help_func_stack;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "stack()", "stack()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " stack()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the call stack for the current task. Each element in the list is a list itself, representing a specific frame. The first element represents the first frame, and so on, up to the current frame. ", <$format, ["np", [], [], 'do_np]>, "Each frame list is ordered as follows:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["OBJNUM sender"], 'do_li]>, <$format, ["li", [], ["OBJNUM caller"], 'do_li]>, <$format, ["li", [], ["SYMBOL method name"], 'do_li]>, <$format, ["li", [], ["INTEGER line number"], 'do_li]>, <$format, ["li", [], ["INTEGER current op code"], 'do_li]>], 'do_ol]>], #[['this, $help_func_stack]]]>;
var $root inited = 1;
var $root managed = [$help_func_stack];
var $help_node nolist = 0;


new object $help_func_suspend: $help_funcs_task;

var $root manager = $help_func_suspend;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "suspend()", "suspend()"];
var $help_node links = #[["resume()", $help_func_resume], ["Frames and Tasks", $help_coldc_tasks]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ANY"], 'do_i]>, " suspend()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function suspends the current task indefinitely. A suspended task is resumed by calling the function (in another task) ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_resume"]], ["resume()"], 'do_link]>], 'do_tt]>, ". The return value of suspend is given as the second argument to ", <$format, ["tt", [], ["resume()"], 'do_tt]>, ". If no second argument is given, the return value of ", <$format, ["tt", [], ["suspend()"], 'do_tt]>, " is zero. See ", <$format, ["link", [["node", "$help_coldc_tasks"]], ["Frames and Tasks"], 'do_link]>, " for more information on task control."], #[['this, $help_func_suspend]]]>;
var $root inited = 1;
var $root managed = [$help_func_suspend];
var $help_node nolist = 0;


new object $help_func_task_id: $help_funcs_task;

var $root manager = $help_func_task_id;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "task_id()", "task_id()"];
var $help_node links = #[["Frames and Tasks", $help_coldc_tasks]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " task_id()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the task id for the current task. See ", <$format, ["link", [["node", "$help_coldc_tasks"]], ["Frames and Tasks"], 'do_link]>, " for more information on preempting and task control."], #[['this, $help_func_task_id]]]>;
var $root inited = 1;
var $root managed = [$help_func_task_id];
var $help_node nolist = 0;


new object $help_func_tasks: $help_funcs_task;

var $root manager = $help_func_tasks;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "tasks()", "tasks()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " tasks()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a list of integers, where each integer is the task id for a currently suspended or preempted task."], #[['this, $help_func_tasks]]]>;
var $root inited = 1;
var $root managed = [$help_func_tasks];
var $help_node nolist = 0;


new object $help_func_this: $help_funcs_task;

var $root manager = $help_func_this;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "this()", "this()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " this()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the objnum of the current object."], #[['this, $help_func_this]]]>;
var $root inited = 1;
var $root managed = [$help_func_this];
var $help_node nolist = 0;


new object $help_func_tick: $help_funcs_task;

var $root manager = $help_func_tick;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "tick()", "tick()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " tick()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the current system-wide tick. It exists for backwards compatability, and should not be used."], #[['this, $help_func_tick]]]>;
var $root inited = 1;
var $root managed = [$help_func_tick];
var $help_node nolist = 0;


new object $help_func_ticks_left: $help_funcs_task;

var $root manager = $help_func_ticks_left;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "ticks_left()", "ticks_left()"];
var $help_node links = #[["Frames and Tasks", $help_coldc_tasks]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " ticks_left()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the ticks remaining for the current frame. See ", <$format, ["link", [["node", "$help_coldc_tasks"]], ["Frames and Tasks"], 'do_link]>, " for more information on frames and ticks."], #[['this, $help_func_ticks_left]]]>;
var $root inited = 1;
var $root managed = [$help_func_ticks_left];
var $help_node nolist = 0;


new object $help_func_set_user: $help_funcs_task;

var $root manager = $help_func_set_user;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855723148;
var $root managed = [$help_func_set_user];
var $has_name name = ['prop, "set_user()", "set_user()"];
var $help_node links = #[["user()", $help_func_user]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " set_user()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function sets the task's user to the current object. Later calls to the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_user"]], ["user()"], 'do_link]>], 'do_tt]>, " will return this object, until this function is called again. If no user is set, zero is returned instead. This is intended as an easy means to define a controlling object for a task."], #[['this, $help_func_set_user]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_user: $help_funcs_task;

var $root manager = $help_func_user;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855723311;
var $root managed = [$help_func_user];
var $has_name name = ['prop, "user()", "user()"];
var $help_node links = #[["set_user()", $help_func_set_user]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " user()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the task's user, as it was set with ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_set_user"]], ["set_user()"], 'do_link]>], 'do_tt]>, ". If no user was set, zero is returned instead. This is intended as an easy means to define a controlling object for a task."], #[['this, $help_func_user]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_pass: $help_funcs_task;

var $root manager = $help_func_pass;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855811819;
var $root managed = [$help_func_pass];
var $has_name name = ['prop, "pass()", "pass()"];
var $help_node links = #[["Overridden Methods", $help_coldc_mcall_over]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ANY"], 'do_i]>, " pass(", <$format, ["i", [], ["..."], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is used to call an overridden method, from the current method. When called any arguments sent to ", <$format, ["tt", [], ["pass()"], 'do_tt]>, " are sent to the overridden method, as if it was called with those arguments. When passing to a method, the current frame's values do not change (i.e. the caller and sender stay the same as in the method that is passing back). For more information see the section ", <$format, ["link", [["node", "$help_coldc_mcall_over"]], ["Overridden Methods"], 'do_link]>, "."], #[['this, $help_func_pass]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_task_info: $help_funcs_task;

var $root manager = $help_func_task_info;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855811820;
var $root managed = [$help_func_task_info];
var $has_name name = ['prop, "task_info()", "task_info()"];
var $help_node links = #[["config()", $help_func_config]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " task_info(", <$format, ["i", [], ["INTEGER task_id"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns full information on the task specified with the argument ", <$format, ["i", [], ["task_id"], 'do_i]>, ". If the task does not exist, ", <$format, ["tt", [], ["~type"], 'do_tt]>, " is thrown. The returned list contains a minimum of seven elements, with subsequent elements defining the specific frames, these are:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["INTEGER task id"], 'do_li]>, <$format, ["li", [], ["INTEGER preempted"], 'do_li]>, <$format, ["li", [], ["INTEGER datasize limit"], 'do_li]>, <$format, ["li", [], ["INTEGER fork limit"], 'do_li]>, <$format, ["li", [], ["INTEGER recursion limit"], 'do_li]>, <$format, ["li", [], ["INTEGER objswap limit"], 'do_li]>, <$format, ["li", [], ["INTEGER calldepth limit"], 'do_li]>, <$format, ["li", [], ["LIST frame"], 'do_li]>, <$format, ["li", [], ["..."], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "The second element ", <$format, ["i", [], ["preempted"], 'do_i]>, " is true if this task was preempted, false if it was suspended. For more information on the limit elements, see ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_config"]], ["config()"], 'do_link]>], 'do_tt]>, ". Remaining frame elements are eight element lists formatted as:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["OBJNUM current object"], 'do_li]>, <$format, ["li", [], ["OBJNUM caller"], 'do_li]>, <$format, ["li", [], ["OBJNUM sender"], 'do_li]>, <$format, ["li", [], ["OBJNUM user"], 'do_li]>, <$format, ["li", [], ["INTEGER current opcode"], 'do_li]>, <$format, ["li", [], ["INTEGER last opcode"], 'do_li]>, <$format, ["li", [], ["INTEGER ticks remaining"], 'do_li]>, <$format, ["li", [], ["SYMBOL method name"], 'do_li]>], 'do_ol]>], #[['this, $help_func_task_info]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_call_trace: $help_funcs_task;

var $root manager = $help_func_call_trace;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855811820;
var $root managed = [$help_func_call_trace];
var $has_name name = ['prop, "call_trace()", "call_trace()"];
var $help_node links = #[["debug mode", $help_func_debug_callers]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST|INTEGER"], 'do_i]>], 'do_tt]>, " call_trace()"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Depending on the ", <$format, ["link", [["node", "$help_func_debug_callers"]], ["debug mode"], 'do_link]>, ", one of the following will be returned:", <$format, ["subj", [["level", "3"]], ["mode 0"], 'do_subj]>, "Return 0 ", <$format, ["subj", [["level", "3"]], ["mode 1"], 'do_subj]>, "Returns a list samples gathered by debugger. Each method call is sampled as the following list:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["[tick#, this, definer, method]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], ["tick#"], 'do_dt]>, <$format, ["dd", [], ["tick in which the call occured"], 'do_dd]>, <$format, ["dt", [], ["this"], 'do_dt]>, <$format, ["dd", [], ["receiver of the call"], 'do_dd]>, <$format, ["dt", [], ["definer"], 'do_dt]>, <$format, ["dd", [], ["definer of the called method"], 'do_dd]>, <$format, ["dt", [], ["method"], 'do_dt]>, <$format, ["dd", [], ["method name (a symbol)"], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "Each method return is sampled as a tick#.", <$format, ["np", [], [], 'do_np]>, "Note: The tick counts will be off if the task has been preepmpted and another task executed during the pause.", <$format, ["subj", [["level", "3"]], ["mode 2"], 'do_subj]>, "In addition to the above, each method call has fifth element, giving the list of all the arguments passed in the call. Optional arguments (those defined as @rest in the arg list) are gathered into a list and placed into the result as a single element.", <$format, ["np", [], [], 'do_np]>, "This function will automatically set the debug mode to 0."], #[['this, $help_func_call_trace]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_debug_callers: $help_funcs_task;

var $root manager = $help_func_debug_callers;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855811820;
var $root managed = [$help_func_debug_callers];
var $has_name name = ['prop, "debug_callers()", "debug_callers()"];
var $help_node links = #[["call_trace", $help_func_call_trace]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>], 'do_tt]>, " debug_callers(", <$format, ["i", [], ["INTEGER mode"], 'do_i]>, ")"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function sets the mode for ", <$format, ["link", [["node", "$help_func_call_trace"]], ["call_trace"], 'do_link]>, " function. If mode is set to non-zero value, the method calling sampler will automatically start. The result of this function is 0."], #[['this, $help_func_debug_callers]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_funcs_err: $help_coldc_func;

var $root manager = $help_funcs_err;
var $root child_index = 4;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Error", "Error"];
var $help_node links = #[["error()", $help_func_error], ["rethrow()", $help_func_rethrow], ["throw()", $help_func_throw], ["traceback()", $help_func_traceback]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "20%,20%,20%,20%,20%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_error"]], ["error()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_rethrow"]], ["rethrow()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_throw"]], ["throw()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_traceback"]], ["traceback()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_err]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_err];
var $help_node nolist = 0;


new object $help_func_error: $help_funcs_err;

var $root manager = $help_func_error;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "error()", "error()"];
var $help_node links = #[["Errors", $help_coldc_errors]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ERROR"], 'do_i]>, " error()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the error code associated with the current error. This function can only be called from within an error handler. For more information see the section on ", <$format, ["link", [["node", "$help_coldc_errors"]], ["Errors"], 'do_link]>, "."], #[['this, $help_func_error]]]>;
var $root inited = 1;
var $root managed = [$help_func_error];
var $help_node nolist = 0;


new object $help_func_rethrow: $help_funcs_err;

var $root manager = $help_func_rethrow;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "rethrow()", "rethrow()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], ["rethrow(", <$format, ["i", [], ["ERROR code"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function continues propagation of an error condition. The interpreter will abort the current method and throw the error specified by ", <$format, ["i", [], ["code"], 'do_i]>, " in the calling method. Calling this function outside of an error handler will result in the error ", <$format, ["tt", [], ["~error"], 'do_tt]>, "."], #[['this, $help_func_rethrow]]]>;
var $root inited = 1;
var $root managed = [$help_func_rethrow];
var $help_node nolist = 0;


new object $help_func_throw: $help_funcs_err;

var $root manager = $help_func_throw;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "throw()", "throw()"];
var $help_node links = #[["traceback()", $help_func_traceback], ["Errors", $help_coldc_errors]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], ["throw(", <$format, ["i", [], ["ERROR code"], 'do_i]>, ", ", <$format, ["i", [], ["STRING explanation"], 'do_i]>, "[, ", <$format, ["i", [], ["ANY additional"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function throws an error with the code ", <$format, ["i", [], ["code"], 'do_i]>, " in the calling method, not the current method. The current method does not have the ability to stop an error originating in itself. The variables ", <$format, ["i", [], ["explanation"], 'do_i]>, " and ", <$format, ["i", [], ["additional"], 'do_i]>, " appear in the traceback. For more information on error handling see ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_traceback"]], ["traceback()"], 'do_link]>], 'do_tt]>, " and ", <$format, ["link", [["node", "$help_coldc_errors"]], ["Errors"], 'do_link]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["throw(~perm, \"Sender is not the system object.\");"], 'do_dfn]>], #[['this, $help_func_throw]]]>;
var $root inited = 1;
var $root managed = [$help_func_throw];
var $help_node nolist = 0;


new object $help_func_traceback: $help_funcs_err;

var $root manager = $help_func_traceback;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384460;
var $has_name name = ['prop, "traceback()", "traceback()"];
var $help_node links = #[["Errors", $help_coldc_errors]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " traceback()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the propogated error stack. The first element in the traceback list is the error condition, the second element is what caused the error. The subsequent errors describe the method call stack from the point of origin. The error condition list is ordered as follows:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["ERROR code"], 'do_li]>, <$format, ["li", [], ["STRING explanation"], 'do_li]>, <$format, ["li", [], ["ANY additional"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "The second element (what caused the error) will vary, depending upon where the error came from. If the error came from an operator, function or native method, it is a two element list:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["SYMBOL which is one of ", <$format, ["tt", [], ["'opcode"], 'do_tt]>, ", ", <$format, ["tt", [], ["'function"], 'do_tt]>, " or ", <$format, ["tt", [], ["'native"], 'do_tt]>], 'do_li]>, <$format, ["li", [], ["SYMBOL what operator, or the name of the function/native method."], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "If the error originated in a method, this list is ordered as:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], [<$format, ["tt", [], ["'method"], 'do_tt]>], 'do_li]>, <$format, ["li", [], ["SYMBOL method name"], 'do_li]>, <$format, ["li", [], ["OBJNUM current object"], 'do_li]>, <$format, ["li", [], ["OBJNUM defining object"], 'do_li]>, <$format, ["li", [], ["INTEGER line in method"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "All other elements are ordered as:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["ERROR error code"], 'do_li]>, <$format, ["li", [], ["SYMBOL method name"], 'do_li]>, <$format, ["li", [], ["OBJNUM current object"], 'do_li]>, <$format, ["li", [], ["OBJNUM defining object"], 'do_li]>, <$format, ["li", [], ["INTEGER line in method"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "Keep in mind that the error code will change to ", <$format, ["tt", [], ["~methoderr"], 'do_tt]>, " when it propogates, unless the propogate expression is used. See the section ", <$format, ["link", [["node", "$help_coldc_errors"]], ["Errors"], 'do_link]>, " for more information. A full traceback might look like:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["[[~numargs, \"Called with no arguments, requires one.\", 0],", <$format, ["br", [], [], 'do_br]>, "['function, 'listlen],", <$format, ["br", [], [], 'do_br]>, "[~numargs, 'foo, $brandon, $brandon, 1],", <$format, ["br", [], [], 'do_br]>, "[~methoderr, 'tmp_eval_855796437, $brandon, $brandon, 6]]"], 'do_tt]>], 'do_dfn]>], #[['this, $help_func_traceback]]]>;
var $root inited = 1;
var $root managed = [$help_func_traceback];
var $help_node nolist = 0;


new object $help_funcs_net: $help_coldc_func;

var $root manager = $help_funcs_net;
var $root child_index = 8;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Network", "Network"];
var $help_node links = #[["bind_port()", $help_func_bind_port], ["close_connection()", $help_func_close_connection], ["connection()", $help_func_connection], ["cwrite()", $help_func_cwrite], ["cwritef()", $help_func_cwritef], ["open_connection()", $help_func_open_connection], ["reassign_connection()", $help_func_reassign_connection], ["unbind_port()", $help_func_unbind_port]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "33%,33%,33%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_bind_port"]], ["bind_port()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_close_connection"]], ["close_connection()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_connection"]], ["connection()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_cwrite"]], ["cwrite()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_cwritef"]], ["cwritef()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_open_connection"]], ["open_connection()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_reassign_connection"]], ["reassign_connection()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_unbind_port"]], ["unbind_port()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_net]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_net];
var $help_node nolist = 0;


new object $help_func_bind_port: $help_funcs_net;

var $root manager = $help_func_bind_port;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "bind_port()", "bind_port()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " bind_port(", <$format, ["i", [], ["INTEGER port"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING addr"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function binds a network port to the current object. If successful, the current object will receive connections on the port. The first argument specifies the port to bind to. Positive port numbers represent the TCP protocol. Negative port numbers represent the UDP protocol. The second optional argument is the address to bind to, which must be a standard IP address (not an internet domain name). This is usually not required, but can be useful if multiple addresses exist on the system and only one must be bound. ", <$format, ["np", [], [], 'do_np]>, "If the port is pre-bound (see the Genesis documentation) but the address does not match up, the error ", <$format, ["tt", [], ["~preaddr"], 'do_tt]>, " may be thrown. If the port is pre-bound and the protocols do not match, the error ", <$format, ["tt", [], ["~pretype"], 'do_tt]>, " is thrown. If the given address is not a valid IP address the error ", <$format, ["tt", [], ["~address"], 'do_tt]>, " is thrown. Other errors may be thrown as ", <$format, ["tt", [], ["~socket"], 'do_tt]>, " or ", <$format, ["tt", [], ["~bind"], 'do_tt]>, " if other problems arise."], #[['this, $help_func_bind_port]]]>;
var $root inited = 1;
var $root managed = [$help_func_bind_port];
var $help_node nolist = 0;


new object $help_func_close_connection: $help_funcs_net;

var $root manager = $help_func_close_connection;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "close_connection()", "close_connection()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " close_connection()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function closes the connection on the current object. If there is no connection on the current object, zero is returned."], #[['this, $help_func_close_connection]]]>;
var $root inited = 1;
var $root managed = [$help_func_close_connection];
var $help_node nolist = 0;


new object $help_func_connection: $help_funcs_net;

var $root manager = $help_func_connection;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "connection()", "connection()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " connection()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a list of information on the current connection. If no connection exists, ", <$format, ["tt", [], ["~net"], 'do_tt]>, " is thrown. The list is ordered as:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["INTEGER boolean (true if the connection is readable)"], 'do_li]>, <$format, ["li", [], ["INTEGER boolean (true if the connection is writable)"], 'do_li]>, <$format, ["li", [], ["INTEGER boolean (true if the connection is dead)"], 'do_li]>, <$format, ["li", [], ["INTEGER file descriptor"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "Most of this information is useful only for debugging, as it can change immediately (all but the file descriptor). This function is useful for determining if the current object has a valid connection."], #[['this, $help_func_connection]]]>;
var $root inited = 1;
var $root managed = [$help_func_connection];
var $help_node nolist = 0;


new object $help_func_cwrite: $help_funcs_net;

var $root manager = $help_func_cwrite;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "cwrite()", "cwrite()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " cwrite(", <$format, ["i", [], ["BUFFER buffer"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function writes the buffer data in the argument ", <$format, ["i", [], ["buffer"], 'do_i]>, " to the connection on the current object. If there is no connection on the current object a zero is returned. Otherwise a one is returned."], #[['this, $help_func_cwrite]]]>;
var $root inited = 1;
var $root managed = [$help_func_cwrite];
var $help_node nolist = 0;


new object $help_func_cwritef: $help_funcs_net;

var $root manager = $help_func_cwritef;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "cwritef()", "cwritef()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " cwritef(", <$format, ["i", [], ["STRING file_path"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER block"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function opens the file specified by ", <$format, ["i", [], ["file_path"], 'do_i]>, " and writes it's contents directly to the connection. The block size it reads and writes (defaulting to the driver defined variable in defs.h DEF_BLOCKSIZE, usually this is 512) can be changed by specifying an optional second argument. If the second is a negative one (-1) it will attempt to read the entire file at once, and write it to the connection (the old coldmud behavior). The size of the file (in bytes) is returned. If a problem arises the error ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown."], #[['this, $help_func_cwritef]]]>;
var $root inited = 1;
var $root managed = [$help_func_cwritef];
var $help_node nolist = 0;


new object $help_func_open_connection: $help_funcs_net;

var $root manager = $help_func_open_connection;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "open_connection()", "open_connection()"];
var $help_node links = #[["Networking", $help_coldc_net]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " open_connection(", <$format, ["i", [], ["STRING host"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER port"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function opens an outbound connection to ", <$format, ["i", [], ["host"], 'do_i]>, " at port ", <$format, ["i", [], ["port"], 'do_i]>, ", on the current object. If the host address ", <$format, ["i", [], ["host"], 'do_i]>, " is invalid, the error ", <$format, ["tt", [], ["~address"], 'do_tt]>, " is thrown. If the socket could not be established, ", <$format, ["tt", [], ["~socket"], 'do_tt]>, " is thrown. For more information, see the section on ", <$format, ["link", [["node", "$help_coldc_net"]], ["Networking"], 'do_link]>, "."], #[['this, $help_func_open_connection]]]>;
var $root inited = 1;
var $root managed = [$help_func_open_connection];
var $help_node nolist = 0;


new object $help_func_reassign_connection: $help_funcs_net;

var $root manager = $help_func_reassign_connection;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "reassign_connection()", "reassign_connection()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " reassign_connection(", <$format, ["i", [], ["OBJNUM new"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function changes the controlling object for a connection from the current object to the object specified by the argument ", <$format, ["i", [], ["new"], 'do_i]>, ". If the new object does not exist, ", <$format, ["tt", [], ["~objnf"], 'do_tt]>, " is thrown. If the new object already has a connection, the error ", <$format, ["tt", [], ["~perm"], 'do_tt]>, " is thrown."], #[['this, $help_func_reassign_connection]]]>;
var $root inited = 1;
var $root managed = [$help_func_reassign_connection];
var $help_node nolist = 0;


new object $help_func_unbind_port: $help_funcs_net;

var $root manager = $help_func_unbind_port;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384460;
var $has_name name = ['prop, "unbind_port()", "unbind_port()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " unbind_port(", <$format, ["i", [], ["INTEGER port"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function stops listening to the port specified by ", <$format, ["i", [], ["port"], 'do_i]>, ". If the object is not listening to the specified port, ", <$format, ["tt", [], ["~servnf"], 'do_tt]>, " is thrown."], #[['this, $help_func_unbind_port]]]>;
var $root inited = 1;
var $root managed = [$help_func_unbind_port];
var $help_node nolist = 0;


new object $help_funcs_file: $help_coldc_func;

var $root manager = $help_funcs_file;
var $root child_index = 17;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "File", "File"];
var $help_node links = #[["dblog()", $help_func_dblog], ["execute()", $help_func_execute], ["fchmod()", $help_func_fchmod], ["fclose()", $help_func_fclose], ["feof()", $help_func_feof], ["fflush()", $help_func_fflush], ["file()", $help_func_file], ["files()", $help_func_files], ["fmkdir()", $help_func_fmkdir], ["fopen()", $help_func_fopen], ["fread()", $help_func_fread], ["fremove()", $help_func_fremove], ["frename()", $help_func_frename], ["frmdir()", $help_func_frmdir], ["fseek()", $help_func_fseek], ["fstat()", $help_func_fstat], ["fwrite()", $help_func_fwrite]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "17%,17%,17%,17%,17%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_dblog"]], ["dblog()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_execute"]], ["execute()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fchmod"]], ["fchmod()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fclose"]], ["fclose()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_feof"]], ["feof()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fflush"]], ["fflush()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_file"]], ["file()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_files"]], ["files()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fmkdir"]], ["fmkdir()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fopen"]], ["fopen()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fread"]], ["fread()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fremove"]], ["fremove()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_frename"]], ["frename()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_frmdir"]], ["frmdir()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fseek"]], ["fseek()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_fstat"]], ["fstat()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fwrite"]], ["fwrite()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_file]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_file];
var $help_node nolist = 0;


new object $help_func_dblog: $help_funcs_file;

var $root manager = $help_func_dblog;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "dblog()", "dblog()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " dblog(", <$format, ["i", [], ["STRING line"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function writes ", <$format, ["i", [], ["line"], 'do_i]>, " to the database logfile (specified on startup, defaulting to ", <$format, ["tt", [], ["logs/db.log"], 'do_tt]>, ")."], #[['this, $help_func_dblog]]]>;
var $root inited = 1;
var $root managed = [$help_func_dblog];
var $help_node nolist = 0;


new object $help_func_execute: $help_funcs_file;

var $root manager = $help_func_execute;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "execute()", "execute()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " execute(", <$format, ["i", [], ["STRING program"], 'do_i]>, ", ", <$format, ["i", [], ["LIST args"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER nb"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function executes the program named by ", <$format, ["i", [], ["program"], 'do_i]>, " with the arguments given in the list ", <$format, ["i", [], ["arguments"], 'do_i]>, ". Each argument must be a string. By default, calling this function will block execution of genesis until the called program returns. If the optional third argument is specified as a true value, the program is forked and executed in a non-blocking manner. The return value is the return value of the program, or, in the case of a non-blocking execution it is zero. ", <$format, ["np", [], [], 'do_np]>, "This function looks for the program in the executable directory specified upon startup by the driver. This usually defaults to ", <$format, ["tt", [], ["dbbin"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "In the future input and output for the program may be handled as if it were a file."], #[['this, $help_func_execute]]]>;
var $root inited = 1;
var $root managed = [$help_func_execute];
var $help_node nolist = 0;


new object $help_func_fchmod: $help_funcs_file;

var $root manager = $help_func_fchmod;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fchmod()", "fchmod()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " fchmod(", <$format, ["i", [], ["STRING mode"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING file"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function changes the mode of a file or directory. The mode is an octal number constructed by logically OR-ing the following values:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], ["4000"], 'do_dt]>, <$format, ["dd", [], ["set-user-ID-on-execution"], 'do_dd]>, <$format, ["dt", [], ["2000"], 'do_dt]>, <$format, ["dd", [], ["set-group-ID-on-execution"], 'do_dd]>, <$format, ["dt", [], ["1000"], 'do_dt]>, <$format, ["dd", [], ["sticky bit, see the unix manual on chmod"], 'do_dd]>, <$format, ["dt", [], ["0400"], 'do_dt]>, <$format, ["dd", [], ["read by owner"], 'do_dd]>, <$format, ["dt", [], ["0200"], 'do_dt]>, <$format, ["dd", [], ["write by owner"], 'do_dd]>, <$format, ["dt", [], ["0100"], 'do_dt]>, <$format, ["dd", [], ["execute (or search for directories) by owner"], 'do_dd]>, <$format, ["dt", [], ["0070"], 'do_dt]>, <$format, ["dd", [], ["read, write, execute/search by group"], 'do_dd]>, <$format, ["dt", [], ["0007"], 'do_dt]>, <$format, ["dd", [], ["read, write, execute/search by others"], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "The read, write, and execute/search values for group and others are en- coded as described for owner. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["fchmod(\"0644\", \"home.html\")", <$format, ["br", [], [], 'do_br]>, "=> 1"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If the ", <$format, ["tt", [], ["RESTRICTIVE_FILES"], 'do_tt]>, " option has been compiled into the driver, sticky and setuid/setgid bits cannot be changed."], #[['this, $help_func_fchmod]]]>;
var $root inited = 1;
var $root managed = [$help_func_fchmod];
var $help_node nolist = 0;


new object $help_func_fclose: $help_funcs_file;

var $root manager = $help_func_fclose;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fclose()", "fclose()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " fclose()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function closes the file on the current object and returns one (1). If no file is open on the current object, the error ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown."], #[['this, $help_func_fclose]]]>;
var $root inited = 1;
var $root managed = [$help_func_fclose];
var $help_node nolist = 0;


new object $help_func_feof: $help_funcs_file;

var $root manager = $help_func_feof;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "feof()", "feof()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " feof()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns true (1) if the open file on the current object is at it's end, or false (0) if it is not. If the current object does not have an open file, ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown."], #[['this, $help_func_feof]]]>;
var $root inited = 1;
var $root managed = [$help_func_feof];
var $help_node nolist = 0;


new object $help_func_fflush: $help_funcs_file;

var $root manager = $help_func_fflush;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fflush()", "fflush()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " fflush()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function flushes any buffered output for the open file on the current object and returns one (1). If there is no file on the current object the error ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown."], #[['this, $help_func_fflush]]]>;
var $root inited = 1;
var $root managed = [$help_func_fflush];
var $help_node nolist = 0;


new object $help_func_file: $help_funcs_file;

var $root manager = $help_func_file;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "file()", "file()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " file()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the following ordered list of information on the file on the current object:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["BOOLEAN file is readable"], 'do_li]>, <$format, ["li", [], ["BOOLEAN file is writable"], 'do_li]>, <$format, ["li", [], ["BOOLEAN file is closed"], 'do_li]>, <$format, ["li", [], ["BOOLEAN file is binary"], 'do_li]>, <$format, ["li", [], ["STRING file path"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "If no file is bound to the current object, the error ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown."], #[['this, $help_func_file]]]>;
var $root inited = 1;
var $root managed = [$help_func_file];
var $help_node nolist = 0;


new object $help_func_files: $help_funcs_file;

var $root manager = $help_func_files;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "files()", "files()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " files(", <$format, ["i", [], ["STRING directory"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a lit of files in the specified directory. The current and previous directory (\".\" and \"..\") are not included in this listing. Each element in the list is a string. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["files(\"html/\");", <$format, ["br", [], [], 'do_br]>, "=> [\"index.html\", \"tCD.gif\", \"Intro\", \"history.html\"]"], 'do_dfn]>], #[['this, $help_func_files]]]>;
var $root inited = 1;
var $root managed = [$help_func_files];
var $help_node nolist = 0;


new object $help_func_fmkdir: $help_funcs_file;

var $root manager = $help_func_fmkdir;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fmkdir()", "fmkdir()"];
var $help_node links = #[["fchmod()", $help_func_fchmod]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " fmkdir(", <$format, ["i", [], ["STRING path"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function creates the directory specified by ", <$format, ["i", [], ["path"], 'do_i]>, ". If a file or directory already exists by that designation, the error ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown. Otherwise the directory is created with read, write and execute permission for the owner, and no permissions for group or others (these permissions can be changed with the function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_fchmod"]], ["fchmod()"], 'do_link]>], 'do_tt]>, "."], #[['this, $help_func_fmkdir]]]>;
var $root inited = 1;
var $root managed = [$help_func_fmkdir];
var $help_node nolist = 0;


new object $help_func_fopen: $help_funcs_file;

var $root manager = $help_func_fopen;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fopen()", "fopen()"];
var $help_node links = #[["Files", $help_coldc_files], ["fstat()", $help_func_fstat]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " fopen(", <$format, ["i", [], ["STRING filename"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING mode"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is used to open a file on the current object. It is called with one or two arguments. The first argument is the name of the file to open. If the driver was compiled with the ", <$format, ["tt", [], ["RESTRICTIVE_FILES"], 'do_tt]>, " option, the filename will have restrictions (see the section on ", <$format, ["link", [["node", "$help_coldc_files"]], ["Files"], 'do_link]>, " for more information). If ", <$format, ["tt", [], ["RESTRICTIVE_FILES"], 'do_tt]>, " was compiled, all files will have the ", <$format, ["i", [], ["root"], 'do_i]>, " directory prepended to them (this directory is defined by a command line argument to ", <$format, ["a", [["href", "http://www.cold.org/Software/Genesis/"]], [<$format, ["i", [], ["Genesis"], 'do_i]>], 'do_a]>, "). If it was not compiled, but the file does not begin with a slash (\"/\"), the ", <$format, ["i", [], ["root"], 'do_i]>, " directory will still be prepended. ", <$format, ["np", [], [], 'do_np]>, "The second argument is the mode for the file. If the mode begins with \"<\" or nothing, the file is opened for reading. If the mode begins with \">\", the file is truncated to zero length or created for writing. If the mode begins with \">>\", the file is opend for appending. If the second argument is not specified, the mode of file defaults to \"<\". ", <$format, ["np", [], [], 'do_np]>, "A \"+\" may be placed before \">\" or \"<\" to specify both read and write access to the file. Ending a mode with a \"-\" sets it as a binary file, meaning that input and output to the file is through buffers, rather than ColdC strings. ", <$format, ["np", [], [], 'do_np]>, "If successful, the return value of fopen() is stat information in the format returned by ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_fstat"]], ["fstat()"], 'do_link]>], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["stat = fopen(\"log\", \">>\")"], 'do_dfn]>, " ", <$format, ["dfn", [], ["stat = fopen(\"/usr/home/test.info\", \"+>-\")"], 'do_dfn]>], #[['this, $help_func_fopen]]]>;
var $root inited = 1;
var $root managed = [$help_func_fopen];
var $help_node nolist = 0;


new object $help_func_fread: $help_funcs_file;

var $root manager = $help_func_fread;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fread()", "fread()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING|BUFFER"], 'do_i]>, " fread([", <$format, ["i", [], ["INTEGER block"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Read from the existing file bound to this object. If the file is a binary file, a buffer is returned. If the file is a text file (default), a string is returned. If the file is at the end, the ", <$format, ["tt", [], ["~eof"], 'do_tt]>, " error is thrown. With binary files an optional block size may be specified. The default block size is 512 characters. Example: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\ncatch ~eof {\n    while (line = fread())  \n        .tell(line);\n}"], 'do_quote]>], 'do_dfn]>], #[['this, $help_func_fread]]]>;
var $root inited = 1;
var $root managed = [$help_func_fread];
var $help_node nolist = 0;


new object $help_func_fremove: $help_funcs_file;

var $root manager = $help_func_fremove;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fremove()", "fremove()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " fremove(", <$format, ["i", [], ["STRING path"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function removes a file. If the argument ", <$format, ["i", [], ["path"], 'do_i]>, " is given, it will attempt to remove that file."], #[['this, $help_func_fremove]]]>;
var $root inited = 1;
var $root managed = [$help_func_fremove];
var $help_node nolist = 0;


new object $help_func_frename: $help_funcs_file;

var $root manager = $help_func_frename;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "frename()", "frename()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["INTEGER frename(ANY from, STRING to)"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function renames the file specified by the argument ", <$format, ["i", [], ["from"], 'do_i]>, ", to the name specified by the argument ", <$format, ["i", [], ["to"], 'do_i]>, ". If ", <$format, ["i", [], ["from"], 'do_i]>, " is not a string or is logically false, the driver renames the file on the current object. Do not rename the file on the current object by specifying the file's name, as the driver will not know the name has changed and this may cause confusion at a later time. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["frename(\"\", \"old.txt\")", <$format, ["br", [], [], 'do_br]>, "=> 1"], 'do_dfn]>], #[['this, $help_func_frename]]]>;
var $root inited = 1;
var $root managed = [$help_func_frename];
var $help_node nolist = 0;


new object $help_func_frmdir: $help_funcs_file;

var $root manager = $help_func_frmdir;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "frmdir()", "frmdir()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " frmdir(", <$format, ["i", [], ["STRING path"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function removes the directory specified by ", <$format, ["i", [], ["path"], 'do_i]>, ". If an error occurs, ", <$format, ["tt", [], ["~file"], 'do_tt]>, " is thrown (the error explanation will vary depending upon what occurred)."], #[['this, $help_func_frmdir]]]>;
var $root inited = 1;
var $root managed = [$help_func_frmdir];
var $help_node nolist = 0;


new object $help_func_fseek: $help_funcs_file;

var $root manager = $help_func_fseek;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fseek()", "fseek()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " fseek(", <$format, ["i", [], ["INTEGER offset"], 'do_i]>, ", ", <$format, ["i", [], ["SYMBOL whence"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function changes the file position to ", <$format, ["i", [], ["offset"], 'do_i]>, ". The variable ", <$format, ["i", [], ["whence"], 'do_i]>, " is either ", <$format, ["tt", [], ["'SEEK_SET"], 'do_tt]>, ", ", <$format, ["tt", [], ["'SEEK_CUR"], 'do_tt]>, ", ", <$format, ["tt", [], ["'SEEK_END"], 'do_tt]>, ". Read the unix manual page for the function ", <$format, ["tt", [], ["fseek"], 'do_tt]>, ", for more information. ", <$format, ["np", [], [], 'do_np]>, "If the file is not both readable and writable, this function cannot be used."], #[['this, $help_func_fseek]]]>;
var $root inited = 1;
var $root managed = [$help_func_fseek];
var $help_node nolist = 0;


new object $help_func_fstat: $help_funcs_file;

var $root manager = $help_func_fstat;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fstat()", "fstat()"];
var $help_node links = #[["fchmod()", $help_func_fchmod]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " fstat([", <$format, ["i", [], ["STRING path"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns information on a file. If the file is not specified as ", <$format, ["i", [], ["path"], 'do_i]>, ", then it returns information on the open file on the current object. The information is returned as an ordered list:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["STRING octal file mode (see ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_fchmod"]], ["fchmod()"], 'do_link]>], 'do_tt]>, ")"], 'do_li]>, <$format, ["li", [], ["INTEGER file size (in bytes)"], 'do_li]>, <$format, ["li", [], ["INTEGER time when the file was last accessed"], 'do_li]>, <$format, ["li", [], ["INTEGER time when the file was last modified"], 'do_li]>, <$format, ["li", [], ["INTEGER time when the file was last changed"], 'do_li]>], 'do_ol]>, <$format, ["np", [], [], 'do_np]>, "For more information refer to the unix manual page on ", <$format, ["tt", [], ["stat"], 'do_tt]>, ". The octal file mode will likely include additional bit fields from what is commonly seen. These represent file attributes, such as directories, FIFO, etc. The last four bits will refer to the permissions. For instance:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["fstat(\"html\")", <$format, ["br", [], [], 'do_br]>, "=> [\"40775\", 512, 855442283, 851293545, 855435595]"], 'do_dfn]>], #[['this, $help_func_fstat]]]>;
var $root inited = 1;
var $root managed = [$help_func_fstat];
var $help_node nolist = 0;


new object $help_func_fwrite: $help_funcs_file;

var $root manager = $help_func_fwrite;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "fwrite()", "fwrite()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " fwrite(", <$format, ["i", [], ["STRING|BUFFER info"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Write to an existing file bound to this object. The argument is either a buffer (if it is a binary file), or a string (if it is a text file). The return value is an integer representing an offset value of characters which were ", <$format, ["i", [], ["not"], 'do_i]>, " written out (due to an error). In normal operating conditions the return value will be zero. ", <$format, ["np", [], [], 'do_np]>, "Using fwrite() with strings will always terminate the string with a newline character (ASCII 10)."], #[['this, $help_func_fwrite]]]>;
var $root inited = 1;
var $root managed = [$help_func_fwrite];
var $help_node nolist = 0;


new object $help_funcs_misc: $help_coldc_func;

var $root manager = $help_funcs_misc;
var $root child_index = 6;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Misc", "Misc"];
var $help_node links = #[["bind_function()", $help_func_bind_function], ["ctime()", $help_func_ctime], ["localtime()", $help_func_localtime], ["mtime()", $help_func_mtime], ["time()", $help_func_time], ["unbind_function()", $help_func_unbind_function]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "28%,28%,28%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_bind_function"]], ["bind_function()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_ctime"]], ["ctime()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_localtime"]], ["localtime()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_mtime"]], ["mtime()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_time"]], ["time()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_unbind_function"]], ["unbind_function()"], 'do_link]>], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_misc]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_misc];
var $help_node nolist = 0;


new object $help_func_bind_function: $help_funcs_misc;

var $root manager = $help_func_bind_function;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "bind_function()", "bind_function()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " bind_function(", <$format, ["i", [], ["SYMBOL function"], 'do_i]>, ", ", <$format, ["i", [], ["OBJNUM obj"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is used to secure other ColdC functions which may have potential security problems. It binds the function specified by the argument ", <$format, ["i", [], ["function"], 'do_i]>, " to the object specified by ", <$format, ["i", [], ["obj"], 'do_i]>, ". After a function is bound to an object, only methods ", <$format, ["i", [], ["defined"], 'do_i]>, " on that object may call the function. The error ", <$format, ["tt", [], ["~perm"], 'do_tt]>, " is thrown if methods defined on descendants of the object or on any other object call a bound function which is not bound to them."], #[['this, $help_func_bind_function]]]>;
var $root inited = 1;
var $root managed = [$help_func_bind_function];
var $help_node nolist = 0;


new object $help_func_ctime: $help_funcs_misc;

var $root manager = $help_func_ctime;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "ctime()", "ctime()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["STRING ctime([INTEGER time])"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function converts the integer ", <$format, ["i", [], ["time"], 'do_i]>, " into a string format. If ", <$format, ["i", [], ["time"], 'do_i]>, " is not specified, then ", <$format, ["tt", [], ["ctime()"], 'do_tt]>, " uses the current time. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["ctime(739180536)", <$format, ["br", [], [], 'do_br]>, "=> \"Fri Jun 4 03:55:36 1993\""], 'do_dfn]>], #[['this, $help_func_ctime]]]>;
var $root inited = 1;
var $root managed = [$help_func_ctime];
var $help_node nolist = 0;


new object $help_func_localtime: $help_funcs_misc;

var $root manager = $help_func_localtime;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "localtime()", "localtime()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " localtime([", <$format, ["i", [], ["INTEGER time"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns an 11 element list representing the specified by the argument ", <$format, ["i", [], ["time"], 'do_i]>, ". If no argument is given, it will use the current time instead. The elements are taken from ", <$format, ["tt", [], ["struct tm"], 'do_tt]>, " in C and altered as needed to begin at one instead of zero. Elements are broken down in the list as follows:", <$format, ["p", [], [], 'do_p]>, <$format, ["ol", [], [<$format, ["li", [], ["INTEGER time (same as returned by the function ", <$format, ["tt", [], ["time()"], 'do_tt]>, ")"], 'do_li]>, <$format, ["li", [], ["INTEGER seconds (1-60)"], 'do_li]>, <$format, ["li", [], ["INTEGER minutes (1-60)"], 'do_li]>, <$format, ["li", [], ["INTEGER hours (1-24))"], 'do_li]>, <$format, ["li", [], ["INTEGER day of month (1-31)"], 'do_li]>, <$format, ["li", [], ["INTEGER month in year (1-12)"], 'do_li]>, <$format, ["li", [], ["INTEGER year (use year + 1900 for the full year)"], 'do_li]>, <$format, ["li", [], ["INTEGER week day (1-7, Sunday=1)"], 'do_li]>, <$format, ["li", [], ["INTEGER year day (1-366)"], 'do_li]>, <$format, ["li", [], ["INTEGER is daylight savings in effect?"], 'do_li]>, <$format, ["li", [], ["STRING time zone name"], 'do_li]>], 'do_ol]>], #[['this, $help_func_localtime]]]>;
var $root inited = 1;
var $root managed = [$help_func_localtime];
var $help_node nolist = 0;


new object $help_func_mtime: $help_funcs_misc;

var $root manager = $help_func_mtime;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "mtime()", "mtime()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " mtime()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If the system the server is on does not have the unix function ", <$format, ["tt", [], ["gettimeofday()"], 'do_tt]>, " then this function will return ", <$format, ["tt", [], ["-1"], 'do_tt]>, ". If it does, this function will return the current microseconds, from the C structure ", <$format, ["tt", [], ["struct timeval"], 'do_tt]>, ". This is useful in certain situations, but in general its granularity is too fine for most cases. This will only work if cold is running on some unix systems."], #[['this, $help_func_mtime]]]>;
var $root inited = 1;
var $root managed = [$help_func_mtime];
var $help_node nolist = 0;


new object $help_func_time: $help_funcs_misc;

var $root manager = $help_func_time;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "time()", "time()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " time()"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the system time in seconds since midnight GMT, January 1, 1970. The functions ", <$format, ["tt", [], ["ctime()"], 'do_tt]>, ", ", <$format, ["tt", [], ["localtime()"], 'do_tt]>, " and the native method ", <$format, ["tt", [], ["$time.format()"], 'do_tt]>, " can be used in manipulating this number."], #[['this, $help_func_time]]]>;
var $root inited = 1;
var $root managed = [$help_func_time];
var $help_node nolist = 0;


new object $help_func_unbind_function: $help_funcs_misc;

var $root manager = $help_func_unbind_function;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384460;
var $has_name name = ['prop, "unbind_function()", "unbind_function()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " unbind_function(", <$format, ["i", [], ["SYMBOL function"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function unbinds a function from an object. The function is specified by the argument ", <$format, ["i", [], ["function"], 'do_i]>, "."], #[['this, $help_func_unbind_function]]]>;
var $root inited = 1;
var $root managed = [$help_func_unbind_function];
var $help_node nolist = 0;


new object $help_funcs_data: $help_coldc_func;

var $root manager = $help_funcs_data;
var $root child_index = 12;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Data", "Data"];
var $help_node links = #[["class()", $help_func_class], ["fromliteral()", $help_func_fromliteral], ["size()", $help_func_size], ["toerr()", $help_func_toerr], ["tofloat()", $help_func_tofloat], ["toint()", $help_func_toint], ["toliteral()", $help_func_toliteral], ["toobjnum()", $help_func_toobjnum], ["tostr()", $help_func_tostr], ["tosym()", $help_func_tosym], ["type()", $help_func_type], ["valid()", $help_func_valid]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "22%,22%,22%,22%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_class"]], ["class()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_fromliteral"]], ["fromliteral()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_size"]], ["size()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_toerr"]], ["toerr()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_tofloat"]], ["tofloat()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_toint"]], ["toint()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_toliteral"]], ["toliteral()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_toobjnum"]], ["toobjnum()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_tostr"]], ["tostr()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_tosym"]], ["tosym()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_type"]], ["type()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_valid"]], ["valid()"], 'do_link]>], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_data]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_data];
var $help_node nolist = 0;


new object $help_func_class: $help_funcs_data;

var $root manager = $help_func_class;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "class()", "class()"];
var $help_node links = #[["Frobs", $help_coldc_types]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " class(", <$format, ["i", [], ["FROB frob"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the class of a frob. See ", <$format, ["link", [["node", "$help_coldc_types"]], ["Frobs"], 'do_link]>, " for more details on Frobs."], #[['this, $help_func_class]]]>;
var $root inited = 1;
var $root managed = [$help_func_class];
var $help_node nolist = 0;


new object $help_func_size: $help_funcs_data;

var $root manager = $help_func_size;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "size()", "size()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " size([", <$format, ["i", [], ["ANY data"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is used for sizing data. If no arguments are specified, it will return the size of the current object, including all of the methods and object variable instances defined on it. Otherwise it returns the size of the first argument. Note: specifying an objnum as the argument will return the size of the objnum, not the size of the object it represents!", <$format, ["p", [], [], 'do_p]>, "The number returned represents the size, in bytes, ", <$format, ["i", [], ["on disk"], 'do_i]>, ". Because data is packed when written to the disk database, what is returned will not be comparable to runtime memory footprints.", <$format, ["p", [], [], 'do_p]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["size(#1234)", <$format, ["br", [], [], 'do_br]>, "=> 4"], 'do_dfn]>, " ", <$format, ["dfn", [], ["size([1, 2, 3, 4])", <$format, ["br", [], [], 'do_br]>, "=> 15"], 'do_dfn]>, " ", <$format, ["dfn", [], ["size(#[['key1, 1], ['key2, \"test\"]])", <$format, ["br", [], [], 'do_br]>, "=> 45"], 'do_dfn]>, " ", <$format, ["dfn", [], ["size(<$root, #[['name, \"foo\"]]>);", <$format, ["br", [], [], 'do_br]>, "=> 37"], 'do_dfn]>, " ", <$format, ["dfn", [], ["size()", <$format, ["br", [], [], 'do_br]>, "=> 5822"], 'do_dfn]>], #[['this, $help_func_size]]]>;
var $root inited = 1;
var $root managed = [$help_func_size];
var $help_node nolist = 0;


new object $help_func_toerr: $help_funcs_data;

var $root manager = $help_func_toerr;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "toerr()", "toerr()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ERROR"], 'do_i]>, " toerr(", <$format, ["i", [], ["SYMBOL errname"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function converts the argument specified by ", <$format, ["i", [], ["errname"], 'do_i]>, " to an error code."], #[['this, $help_func_toerr]]]>;
var $root inited = 1;
var $root managed = [$help_func_toerr];
var $help_node nolist = 0;


new object $help_func_tofloat: $help_funcs_data;

var $root manager = $help_func_tofloat;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "tofloat()", "tofloat()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["FLOAT"], 'do_i]>, " tofloat(", <$format, ["i", [], ["STRING|INTEGER|OBJNUM data"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function accepts a STRING, INTEGER or OBJNUM data type and converts it to a FLOAT data type. Specifying any other data type will result in a ", <$format, ["tt", [], ["~type"], 'do_tt]>, " error."], #[['this, $help_func_tofloat]]]>;
var $root inited = 1;
var $root managed = [$help_func_tofloat];
var $help_node nolist = 0;


new object $help_func_toint: $help_funcs_data;

var $root manager = $help_func_toint;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "toint()", "toint()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " toint(", <$format, ["i", [], ["FLOAT|STRING|OBJNUM data"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function accepts a FLOAT, STRING or OBJNUM data type and converts it to an integer data type. Specifying any other data type will result in a ", <$format, ["tt", [], ["~type"], 'do_tt]>, " error."], #[['this, $help_func_toint]]]>;
var $root inited = 1;
var $root managed = [$help_func_toint];
var $help_node nolist = 0;


new object $help_func_toliteral: $help_funcs_data;

var $root manager = $help_func_toliteral;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "toliteral()", "toliteral()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " toliteral(", <$format, ["i", [], ["ANY data"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function converts any data to a literal representation of itself, which, if re-compiled, would result in the same data."], #[['this, $help_func_toliteral]]]>;
var $root inited = 1;
var $root managed = [$help_func_toliteral];
var $help_node nolist = 0;


new object $help_func_toobjnum: $help_funcs_data;

var $root manager = $help_func_toobjnum;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "toobjnum()", "toobjnum()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["OBJNUM"], 'do_i]>, " toobjnum(", <$format, ["tt", [], ["INTEGER number"], 'do_tt]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function converts the integer data type specified by ", <$format, ["i", [], ["number"], 'do_i]>, " to an objnum data type. The returned objnum may or may not point to a valid object."], #[['this, $help_func_toobjnum]]]>;
var $root inited = 1;
var $root managed = [$help_func_toobjnum];
var $help_node nolist = 0;


new object $help_func_tostr: $help_funcs_data;

var $root manager = $help_func_tostr;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "tostr()", "tostr()"];
var $help_node links = #[["toliteral()", $help_func_toliteral]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " tostr(", <$format, ["i", [], ["ANY data"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a simple representation of the data specified by ", <$format, ["i", [], ["data"], 'do_i]>, ". It is not a literal representation, as ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_toliteral"]], ["toliteral()"], 'do_link]>], 'do_tt]>, " does, but insteads is more succinct. For instance, with complex data types such as lists, the returned representation is simply ", <$format, ["tt", [], ["\"[list]\""], 'do_tt]>, ". Less complex data types such as integers will still return the correct integer value."], #[['this, $help_func_tostr]]]>;
var $root inited = 1;
var $root managed = [$help_func_tostr];
var $help_node nolist = 0;


new object $help_func_tosym: $help_funcs_data;

var $root manager = $help_func_tosym;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "tosym()", "tosym()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["SYMBOL"], 'do_i]>, " tosym(", <$format, ["i", [], ["STRING input"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function creates a symbol from the string ", <$format, ["i", [], ["input"], 'do_i]>, ". Symbols can only contain alphanumeric characters, and the underscore character. If a string is specified with more than these characters, the error ", <$format, ["tt", [], ["~symbol"], 'do_tt]>, " is thrown."], #[['this, $help_func_tosym]]]>;
var $root inited = 1;
var $root managed = [$help_func_tosym];
var $help_node nolist = 0;


new object $help_func_type: $help_funcs_data;

var $root manager = $help_func_type;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384460;
var $has_name name = ['prop, "type()", "type()"];
var $help_node links = #[["Data Types", $help_coldc_types]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["SYMBOL"], 'do_i]>, " type(", <$format, ["i", [], ["ANY data"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a symbol name for the data type of ", <$format, ["i", [], ["data"], 'do_i]>, ". The following symbols represent the respective types:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], ["INTEGER"], 'do_dt]>, <$format, ["dd", [], ["'integer"], 'do_dd]>, <$format, ["dt", [], ["FLOAT"], 'do_dt]>, <$format, ["dd", [], ["'float"], 'do_dd]>, <$format, ["dt", [], ["STRING"], 'do_dt]>, <$format, ["dd", [], ["'string"], 'do_dd]>, <$format, ["dt", [], ["SYMBOL"], 'do_dt]>, <$format, ["dd", [], ["'symbol"], 'do_dd]>, <$format, ["dt", [], ["LIST"], 'do_dt]>, <$format, ["dd", [], ["'list"], 'do_dd]>, <$format, ["dt", [], ["OBJNUM"], 'do_dt]>, <$format, ["dd", [], ["'objnum"], 'do_dd]>, <$format, ["dt", [], ["DICTIONARY"], 'do_dt]>, <$format, ["dd", [], ["'dictionary"], 'do_dd]>, <$format, ["dt", [], ["ERROR"], 'do_dt]>, <$format, ["dd", [], ["'error"], 'do_dd]>, <$format, ["dt", [], ["FROB"], 'do_dt]>, <$format, ["dd", [], ["'frob"], 'do_dd]>, <$format, ["dt", [], ["BUFFER"], 'do_dt]>, <$format, ["dd", [], ["'buffer"], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "More information can be found in the section on ", <$format, ["link", [["node", "$help_coldc_types"]], ["Data Types"], 'do_link]>, "."], #[['this, $help_func_type]]]>;
var $root inited = 1;
var $root managed = [$help_func_type];
var $help_node nolist = 0;


new object $help_func_valid: $help_funcs_data;

var $root manager = $help_func_valid;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384460;
var $has_name name = ['prop, "valid()", "valid()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " valid(", <$format, ["i", [], ["OBJNUM objnum"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns one (true) if the object pointed to by ", <$format, ["i", [], ["objnum"], 'do_i]>, " exists, or zero (false) if it does not."], #[['this, $help_func_valid]]]>;
var $root inited = 1;
var $root managed = [$help_func_valid];
var $help_node nolist = 0;


new object $help_func_fromliteral: $help_funcs_data;

var $root manager = $help_func_fromliteral;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855441374;
var $root managed = [$help_func_fromliteral];
var $has_name name = ['prop, "fromliteral()", "fromliteral()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ANY"], 'do_i]>, " fromliteral(", <$format, ["i", [], ["STRING data"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function takes the literal representation of the data given in the string argument ", <$format, ["i", [], ["data"], 'do_i]>, " and parses it to actual data, returning the result. If it cannot parse the data, the error ", <$format, ["tt", [], ["~type"], 'do_tt]>, " is thrown. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["fromliteral(\"[1, 'foo]\")", <$format, ["br", [], [], 'do_br]>, "=> [1, 'foo]"], 'do_dfn]>], #[['this, $help_func_fromliteral]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_funcs_buf: $help_coldc_func;

var $root manager = $help_funcs_buf;
var $root child_index = 10;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Buffer", "Buffer"];
var $help_node links = #[["buf_replace()", $help_func_buf_replace], ["buf_to_str()", $help_func_buf_to_str], ["buf_to_strings()", $help_func_buf_to_strings], ["bufgraft()", $help_func_bufgraft], ["bufidx()", $help_func_bufidx], ["buflen()", $help_func_buflen], ["str_to_buf()", $help_func_str_to_buf], ["strings_to_buf()", $help_func_strings_to_buf], ["subbuf()", $help_func_subbuf]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "26%,26%,26%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_buf_replace"]], ["buf_replace()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_buf_to_str"]], ["buf_to_str()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_buf_to_strings"]], ["buf_to_strings()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_bufgraft"]], ["bufgraft()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_bufidx"]], ["bufidx()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_buflen"]], ["buflen()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_str_to_buf"]], ["str_to_buf()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_strings_to_buf"]], ["strings_to_buf()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_subbuf"]], ["subbuf()"], 'do_link]>], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_buf]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_buf];
var $help_node nolist = 0;


new object $help_func_buf_replace: $help_funcs_buf;

var $root manager = $help_func_buf_replace;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "buf_replace()", "buf_replace()"];
var $help_node links = #[["bufgraft()", $help_func_bufgraft]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["BUFFER"], 'do_i]>, " buf_replace(", <$format, ["i", [], ["BUFFER buf"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER pos"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER char"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function replaces the character in the buffer at position ", <$format, ["i", [], ["pos"], 'do_i]>, " with the character specified by the integer ", <$format, ["i", [], ["char"], 'do_i]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["buf_replace(`[98, 111, 111], 1, 102)", <$format, ["br", [], [], 'do_br]>, "=> `[102, 111, 111]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_bufgraft"]], ["bufgraft()"], 'do_link]>], 'do_tt]>, " performs a similar role."], #[['this, $help_func_buf_replace]]]>;
var $root inited = 1;
var $root managed = [$help_func_buf_replace];
var $help_node nolist = 0;


new object $help_func_buf_to_str: $help_funcs_buf;

var $root manager = $help_func_buf_to_str;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "buf_to_str()", "buf_to_str()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " buf_to_str(", <$format, ["i", [], ["BUFFER buf"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function converts the entire buffer specified by ", <$format, ["i", [], ["buf"], 'do_i]>, " to a string. Newlines are converted to ", <$format, ["tt", [], ["\"\\\n\""], 'do_tt]>, ". To just get the first string in the buffer (seperated by a newline) do: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\ni = bufidx(buffer, 10);\nstr = buf_to_str(subbuf(buffer, 1, i - 1));\nbuffer = subbuf(buffer, i + 1);"], 'do_quote]>], 'do_dfn]>], #[['this, $help_func_buf_to_str]]]>;
var $root inited = 1;
var $root managed = [$help_func_buf_to_str];
var $help_node nolist = 0;


new object $help_func_buf_to_strings: $help_funcs_buf;

var $root manager = $help_func_buf_to_strings;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "buf_to_strings()", "buf_to_strings()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " buf_to_strings(", <$format, ["i", [], ["BUFFER buf"], 'do_i]>, "[, ", <$format, ["i", [], ["BUFFER sep"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function converts the buffer specified by ", <$format, ["i", [], ["buf"], 'do_i]>, " to a list of printable strings, with a final buffer element. Each string is a line in the buffer, terminated by a newline. If any characters remain unterminted, they are placed in the last element as a buffer. The last element will always be a buffer, regarless of whether any characters are in it. ", <$format, ["np", [], [], 'do_np]>, <$format, ["tt", [], ["buf_to_strings()"], 'do_tt]>, " will alternatively split the strings based off the optional second argument. Note: it is not necessary to specify both a carriage return and a newline as the seperator--if both exist--as the newline will be sufficient to break the string, and the carriage return will be discarded as an unprintable character in the string."], #[['this, $help_func_buf_to_strings]]]>;
var $root inited = 1;
var $root managed = [$help_func_buf_to_strings];
var $help_node nolist = 0;


new object $help_func_bufgraft: $help_funcs_buf;

var $root manager = $help_func_bufgraft;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "bufgraft()", "bufgraft()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["BUFFER"], 'do_i]>, " bufgraft(", <$format, ["i", [], ["BUFFER buf"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER pos"], 'do_i]>, ", ", <$format, ["i", [], ["BUFFER what"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function will graft the buffer ", <$format, ["i", [], ["what"], 'do_i]>, " into the buffer ", <$format, ["i", [], ["buf"], 'do_i]>, " at ", <$format, ["i", [], ["pos"], 'do_i]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["bufgraft(`[1, 2, 3, 4], 2, `[100, 100])", <$format, ["br", [], [], 'do_br]>, "=> `[1, 100, 100, 2, 3, 4]"], 'do_dfn]>], #[['this, $help_func_bufgraft]]]>;
var $root inited = 1;
var $root managed = [$help_func_bufgraft];
var $help_node nolist = 0;


new object $help_func_buflen: $help_funcs_buf;

var $root manager = $help_func_buflen;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "buflen()", "buflen()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " buflen(", <$format, ["i", [], ["BUFFER buf"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the length of the buffer ", <$format, ["i", [], ["buf"], 'do_i]>, "."], #[['this, $help_func_buflen]]]>;
var $root inited = 1;
var $root managed = [$help_func_buflen];
var $help_node nolist = 0;


new object $help_func_str_to_buf: $help_funcs_buf;

var $root manager = $help_func_str_to_buf;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "str_to_buf()", "str_to_buf()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["BUFFER"], 'do_i]>, " str_to_buf(", <$format, ["i", [], ["STRING str"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function converts the string specified by the argument ", <$format, ["i", [], ["str"], 'do_i]>, " to a buffer. The character sequence ", <$format, ["tt", [], ["\"\\\n\""], 'do_tt]>, " will be converted to a carriage return and line feed (ASCII 13 and 10)."], #[['this, $help_func_str_to_buf]]]>;
var $root inited = 1;
var $root managed = [$help_func_str_to_buf];
var $help_node nolist = 0;


new object $help_func_strings_to_buf: $help_funcs_buf;

var $root manager = $help_func_strings_to_buf;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "strings_to_buf()", "strings_to_buf()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["BUFFER"], 'do_i]>, " strings_to_buf(", <$format, ["i", [], ["LIST strings"], 'do_i]>, "[, ", <$format, ["i", [], ["BUFFER sep"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function builds a buffer from the strings given in the list ", <$format, ["i", [], ["strings"], 'do_i]>, ". Each string represents a line which is terminated with a carriage return and a newline (ASCII 13 and 10). If the argument ", <$format, ["i", [], ["sep"], 'do_i]>, " is specified, each string is terminated with it instead. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["strings_to_buf([\"a\", \"b\", \"c\"])", <$format, ["br", [], [], 'do_br]>, "=> `[97, 13, 10, 98, 13, 10, 99, 13, 10]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["strings_to_buf([\"a\", \"b\", \"c\"], `[9])", <$format, ["br", [], [], 'do_br]>, "=> `[97, 9, 98, 9, 99, 9]"], 'do_dfn]>], #[['this, $help_func_strings_to_buf]]]>;
var $root inited = 1;
var $root managed = [$help_func_strings_to_buf];
var $help_node nolist = 0;


new object $help_func_subbuf: $help_funcs_buf;

var $root manager = $help_func_subbuf;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "subbuf()", "subbuf()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["BUFFER"], 'do_i]>, " subbuf(", <$format, ["i", [], ["BUFFER buf"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER start"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER length"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a subrange of the buffer specified by ", <$format, ["i", [], ["buf"], 'do_i]>, ". The subrange starts at position ", <$format, ["i", [], ["start"], 'do_i]>, ", and continues ", <$format, ["i", [], ["length"], 'do_i]>, " characters. If ", <$format, ["i", [], ["length"], 'do_i]>, " is unspecified, it will continue to the end of the buffer. If ", <$format, ["i", [], ["start"], 'do_i]>, " is outside of the range of the buffer, or ", <$format, ["i", [], ["length"], 'do_i]>, " will extend past the end of the buffer, the error ", <$format, ["tt", [], ["~range"], 'do_tt]>, " is thrown. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["subbuf(`[1, 2, 3, 4], 2, 2)", <$format, ["br", [], [], 'do_br]>, "=> `[2, 3]"], 'do_dfn]>], #[['this, $help_func_subbuf]]]>;
var $root inited = 1;
var $root managed = [$help_func_subbuf];
var $help_node nolist = 0;


new object $help_func_bufidx: $help_funcs_buf;

var $root manager = $help_func_bufidx;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855393081;
var $root managed = [$help_func_bufidx];
var $has_name name = ['prop, "bufidx()", "bufidx()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " bufidx(", <$format, ["i", [], ["BUFFER buf"], 'do_i]>, ", ", <$format, ["i", [], ["BUFFER|INTEGER what"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER origin"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the position in ", <$format, ["i", [], ["buf"], 'do_i]>, " where ", <$format, ["i", [], ["what"], 'do_i]>, " exists--starting from ", <$format, ["i", [], ["origin"], 'do_i]>, "--or a zero if it does not exist. If ", <$format, ["i", [], ["origin"], 'do_i]>, " is not specified it will default to ", <$format, ["i", [], ["1"], 'do_i]>, ". If ", <$format, ["i", [], ["what"], 'do_i]>, " is an integer, it is equivalent to ", <$format, ["i", [], ["`[what]"], 'do_i]>, ". The ", <$format, ["i", [], ["origin"], 'do_i]>, " represents where to start searching in the buffer. If it is a positive number it starts that many elements into the buffer. If it is a negative number it starts that many elements from the end of the buffer, and searches backwards--from the end of the buffer to the start. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["bufidx(`[1, 7, 1, 6, 7, 1], 7)", <$format, ["br", [], [], 'do_br]>, "=> 2 ", <$format, ["np", [], [], 'do_np]>, "bufidx(`[1, 7, 1, 6, 7, 1], 7, -1)", <$format, ["br", [], [], 'do_br]>, "=> 5 ", <$format, ["np", [], [], 'do_np]>, "bufidx(`[1, 7, 1, 6, 7, 1], `[6, 7])", <$format, ["br", [], [], 'do_br]>, "=> 4 ", <$format, ["np", [], [], 'do_np]>, "bufidx(`[1, 7, 1, 6, 7, 1], `[6, 8])", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>], #[['this, $help_func_bufidx]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_funcs_dict: $help_coldc_func;

var $root manager = $help_funcs_dict;
var $root child_index = 6;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Dictionary", "Dictionary"];
var $help_node links = #[["dict_add()", $help_func_dict_add], ["dict_contains()", $help_func_dict_contains], ["dict_del()", $help_func_dict_del], ["dict_keys()", $help_func_dict_keys], ["dict_union()", $help_func_dict_union], ["dict_values()", $help_func_dict_values]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "25%,25%,25%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_dict_add"]], ["dict_add()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_dict_contains"]], ["dict_contains()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_dict_del"]], ["dict_del()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_dict_keys"]], ["dict_keys()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_dict_union"]], ["dict_union()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_dict_values"]], ["dict_values()"], 'do_link]>], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_dict]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_dict];
var $help_node nolist = 0;


new object $help_func_dict_add: $help_funcs_dict;

var $root manager = $help_func_dict_add;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "dict_add()", "dict_add()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["DICTIONARY"], 'do_i]>, " dict_add(", <$format, ["i", [], ["DICTIONARY dict"], 'do_i]>, ", ", <$format, ["i", [], ["ANY key"], 'do_i]>, ", ", <$format, ["i", [], ["ANY value"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function adds an association to the dictionary ", <$format, ["i", [], ["dict"], 'do_i]>, ". The key and value of the association are given as the ", <$format, ["i", [], ["key"], 'do_i]>, " and ", <$format, ["i", [], ["value"], 'do_i]>, " arguments. The new dictionary is returned. If ", <$format, ["i", [], ["key"], 'do_i]>, " already exists in ", <$format, ["i", [], ["dict"], 'do_i]>, ", then the value of the existing key is replaced with ", <$format, ["i", [], ["value"], 'do_i]>, ". Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["dict_add(#[[\"foo\", \"bar\"]], 3, 'quux)", <$format, ["br", [], [], 'do_br]>, "=> #[[\"foo\", \"bar\"], [3, 'quux]]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["dict_add(#[[\"foo\", 1], [\"bar\", 2], [\"baz\", 3]], \"bar\", 4)", <$format, ["br", [], [], 'do_br]>, "=> #[[\"foo\", 1], [\"bar\", 4], [\"baz\", 3]]"], 'do_dfn]>], #[['this, $help_func_dict_add]]]>;
var $root inited = 1;
var $root managed = [$help_func_dict_add];
var $help_node nolist = 0;


new object $help_func_dict_contains: $help_funcs_dict;

var $root manager = $help_func_dict_contains;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "dict_contains()", "dict_contains()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " dict_contains(", <$format, ["i", [], ["DICTIONARY dict"], 'do_i]>, ", ", <$format, ["i", [], ["ANY key"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns 1 if there is an association in ", <$format, ["i", [], ["dict"], 'do_i]>, " with the specified key, or 0 otherwise. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["dict_contains(#[[\"foo\", \"bar\"]], \"foo\")", <$format, ["br", [], [], 'do_br]>, "=> 1"], 'do_dfn]>, " ", <$format, ["dfn", [], ["dict_contains(#[[\"foo\", \"bar\"]], \"bar\")", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>], #[['this, $help_func_dict_contains]]]>;
var $root inited = 1;
var $root managed = [$help_func_dict_contains];
var $help_node nolist = 0;


new object $help_func_dict_del: $help_funcs_dict;

var $root manager = $help_func_dict_del;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "dict_del()", "dict_del()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["DICTIONARY"], 'do_i]>, " dict_del(", <$format, ["i", [], ["DICTIONARY dict"], 'do_i]>, ", ", <$format, ["i", [], ["ANY key"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function the ", <$format, ["i", [], ["key"], 'do_i]>, " ", <$format, ["i", [], ["value"], 'do_i]>, " association from the dictionary ", <$format, ["i", [], ["dict"], 'do_i]>, " and returns the result. If there is no association with the specified key, then the error ", <$format, ["tt", [], ["~keynf"], 'do_tt]>, " is thrown. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["dict_del(#[[\"foo\", 1], [\"bar\", 2]], \"foo\")", <$format, ["br", [], [], 'do_br]>, "=> #[[\"bar\", 2]]"], 'do_dfn]>], #[['this, $help_func_dict_del]]]>;
var $root inited = 1;
var $root managed = [$help_func_dict_del];
var $help_node nolist = 0;


new object $help_func_dict_keys: $help_funcs_dict;

var $root manager = $help_func_dict_keys;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "dict_keys()", "dict_keys()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " dict_keys(", <$format, ["i", [], ["DICTIONARY dict"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a correctly ordered list of the keys of the associations in ", <$format, ["i", [], ["dict"], 'do_i]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["dict_keys(#[[\"foo\", 1], [\"bar\", 2], ['baz, 3]])", <$format, ["br", [], [], 'do_br]>, "=> [\"foo\", \"bar\", 'baz]"], 'do_dfn]>], #[['this, $help_func_dict_keys]]]>;
var $root inited = 1;
var $root managed = [$help_func_dict_keys];
var $help_node nolist = 0;


new object $help_func_dict_union: $help_funcs_dict;

var $root manager = $help_func_dict_union;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855434224;
var $root managed = [$help_func_dict_union];
var $has_name name = ['prop, "dict_union()", "dict_union()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["DICTIONARY"], 'do_i]>, " dict_union(", <$format, ["i", [], ["DICTIONARY dict1"], 'do_i]>, ", ", <$format, ["i", [], ["DICTIONARY dict2"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function mergest the two dictionaries by adding each association from ", <$format, ["i", [], ["dict2"], 'do_i]>, " into ", <$format, ["i", [], ["dict1"], 'do_i]>, ". In the case of conflicts, the values in ", <$format, ["i", [], ["dict2"], 'do_i]>, " take precedence. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["dict_union(#[[\"foo\", 1], ['baz, 3]], #[[\"foo\", 2], [\"bar\", 2]])", <$format, ["br", [], [], 'do_br]>, "=> #[[\"foo\", 2], ['baz, 3], [\"bar\", 2]]"], 'do_dfn]>], #[['this, $help_func_dict_union]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_dict_values: $help_funcs_dict;

var $root manager = $help_func_dict_values;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855434224;
var $root managed = [$help_func_dict_values];
var $has_name name = ['prop, "dict_values()", "dict_values()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " dict_values(", <$format, ["i", [], ["DICTIONARY dict"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a correctly ordered list of the keys of the associations in ", <$format, ["i", [], ["dict"], 'do_i]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["dict_values(#[[\"foo\", 1], [\"bar\", 2], ['baz, 3]])", <$format, ["br", [], [], 'do_br]>, "=> [1, 2, 3]"], 'do_dfn]>], #[['this, $help_func_dict_values]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_funcs_list: $help_coldc_func;

var $root manager = $help_funcs_list;
var $root child_index = 11;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "List", "List"];
var $help_node links = #[["delete()", $help_func_delete], ["insert()", $help_func_insert], ["join()", $help_func_join], ["listgraft()", $help_func_listgraft], ["listidx()", $help_func_listidx], ["listlen()", $help_func_listlen], ["replace()", $help_func_replace], ["setadd()", $help_func_setadd], ["setremove()", $help_func_setremove], ["sublist()", $help_func_sublist], ["union()", $help_func_union]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "20%,20%,20%,20%,20%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_delete"]], ["delete()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_insert"]], ["insert()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_join"]], ["join()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_listgraft"]], ["listgraft()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_listidx"]], ["listidx()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_listlen"]], ["listlen()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_replace"]], ["replace()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_setadd"]], ["setadd()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_setremove"]], ["setremove()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_sublist"]], ["sublist()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_union"]], ["union()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_list]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_list];
var $help_node nolist = 0;


new object $help_func_delete: $help_funcs_list;

var $root manager = $help_func_delete;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "delete()", "delete()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " delete(", <$format, ["i", [], ["LIST list"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER pos"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function deletes the element in the argument ", <$format, ["i", [], ["list"], 'do_i]>, ", pointed to by the position argument ", <$format, ["i", [], ["pos"], 'do_i]>, ", and returns the result. If ", <$format, ["i", [], ["position"], 'do_i]>, " is less than ", <$format, ["tt", [], ["1"], 'do_tt]>, " or is greater than the length of ", <$format, ["i", [], ["list"], 'do_i]>, ", then ", <$format, ["tt", [], ["delete()"], 'do_tt]>, " throws a ", <$format, ["tt", [], ["~range"], 'do_tt]>, " error. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["delete([2, 3, 4], 2)", <$format, ["br", [], [], 'do_br]>, "=> [2, 4]"], 'do_dfn]>], #[['this, $help_func_delete]]]>;
var $root inited = 1;
var $root managed = [$help_func_delete];
var $help_node nolist = 0;


new object $help_func_insert: $help_funcs_list;

var $root manager = $help_func_insert;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "insert()", "insert()"];
var $help_node links = #[["listgraft()", $help_func_listgraft]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " insert(", <$format, ["i", [], ["LIST list"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER pos"], 'do_i]>, ", ", <$format, ["i", [], ["ANY value"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function inserts ", <$format, ["i", [], ["value"], 'do_i]>, " into ", <$format, ["i", [], ["list"], 'do_i]>, " before the element specified by the integer ", <$format, ["i", [], ["pos"], 'do_i]>, ". If ", <$format, ["i", [], ["pos"], 'do_i]>, " is outside the range of the list, the error ", <$format, ["tt", [], ["~range"], 'do_tt]>, " is thrown. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["insert([2, 3, 4], 3, 'foo)", <$format, ["br", [], [], 'do_br]>, "=> [2, 3, 'foo, 4]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["insert([\"foo\", 'bar, ~none], 4, 'baz)", <$format, ["br", [], [], 'do_br]>, "=> [\"foo\", 'bar, ~none, 'baz]"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_listgraft"]], ["listgraft()"], 'do_link]>], 'do_tt]>, " performs a similar role to ", <$format, ["tt", [], ["insert()"], 'do_tt]>, "."], #[['this, $help_func_insert]]]>;
var $root inited = 1;
var $root managed = [$help_func_insert];
var $help_node nolist = 0;


new object $help_func_join: $help_funcs_list;

var $root manager = $help_func_join;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "join()", "join()"];
var $help_node links = #[["Non Arithmetic Operators", $help_coldc_non_arith]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " join(", <$format, ["i", [], ["LIST list"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING seperator"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function joins a list together as a string. The second argument is used to specify what seperates each element in the list. If the second argument is unspecified, this will default to a single space. If any element in the list is not a string, it will have a literal representation used instead, in the same manner as when using ", <$format, ["link", [["node", "$help_coldc_non_arith"]], ["Non Arithmetic Operators"], 'do_link]>, ". Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["join([\"Joe\", \"Sally\", \"Bob\", \"Sue\"])", <$format, ["br", [], [], 'do_br]>, "=> \"Joe Sally Bob Sue\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["join([\"This\", \"That\", 'there, 10], \", \")", <$format, ["br", [], [], 'do_br]>, "=> \"This, That, there, 10\""], 'do_dfn]>], #[['this, $help_func_join]]]>;
var $root inited = 1;
var $root managed = [$help_func_join];
var $help_node nolist = 0;


new object $help_func_listgraft: $help_funcs_list;

var $root manager = $help_func_listgraft;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "listgraft()", "listgraft()"];
var $help_node links = #[["splice operator", $help_coldc_splice], ["insert()", $help_func_insert]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " listgraft(", <$format, ["i", [], ["LIST list1"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER"], 'do_i]>, " pos, ", <$format, ["i", [], ["LIST list2"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is similar to the ", <$format, ["link", [["node", "$help_coldc_splice"]], ["splice operator"], 'do_link]>, " and ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_insert"]], ["insert()"], 'do_link]>], 'do_tt]>, ", except it grafts a list into another list, rather than inserting an element at a point in the list. It will take the list specified by ", <$format, ["i", [], ["list2"], 'do_i]>, " and place each element in that list into the list specified by ", <$format, ["i", [], ["list1"], 'do_i]>, ", starting at the position specified by ", <$format, ["i", [], ["pos"], 'do_i]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["listgraft([1, 2, 3, 4, 5], 3, [\"foo\", \"bar\", \"baz\"])", <$format, ["br", [], [], 'do_br]>, "=> [1, 2, \"foo\", \"bar\", \"baz\", 3, 4, 5]"], 'do_dfn]>], #[['this, $help_func_listgraft]]]>;
var $root inited = 1;
var $root managed = [$help_func_listgraft];
var $help_node nolist = 0;


new object $help_func_listlen: $help_funcs_list;

var $root manager = $help_func_listlen;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "listlen()", "listlen()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " listlen(", <$format, ["i", [], ["LIST list"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the length of ", <$format, ["i", [], ["list"], 'do_i]>, "."], #[['this, $help_func_listlen]]]>;
var $root inited = 1;
var $root managed = [$help_func_listlen];
var $help_node nolist = 0;


new object $help_func_replace: $help_funcs_list;

var $root manager = $help_func_replace;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "replace()", "replace()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " replace(", <$format, ["i", [], ["LIST list"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER pos"], 'do_i]>, ", ", <$format, ["i", [], ["ANY value"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function replaces the element in the argument ", <$format, ["i", [], ["list"], 'do_i]>, "--pointed to by the position argument ", <$format, ["i", [], ["pos"], 'do_i]>, "--with the argument ", <$format, ["tt", [], ["value"], 'do_tt]>, ", and returns the result. If the position argument is outside the range of the list, the error ", <$format, ["tt", [], ["~range"], 'do_tt]>, " is thrown. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["replace([2, 3, 4], 2, 'foo)", <$format, ["br", [], [], 'do_br]>, "=> [2, 'foo, 4]"], 'do_dfn]>], #[['this, $help_func_replace]]]>;
var $root inited = 1;
var $root managed = [$help_func_replace];
var $help_node nolist = 0;


new object $help_func_setadd: $help_funcs_list;

var $root manager = $help_func_setadd;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "setadd()", "setadd()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " setadd(", <$format, ["tt", [], ["LIST list"], 'do_tt]>, ", ", <$format, ["i", [], ["ANY value"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function appends the argument ", <$format, ["i", [], ["value"], 'do_i]>, " to the argument ", <$format, ["i", [], ["list"], 'do_i]>, " if it is not already in the list, and returns the result. If ", <$format, ["i", [], ["value"], 'do_i]>, " is already in the list, it does not add it. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["setadd([2, 3, 4], 'foo)", <$format, ["br", [], [], 'do_br]>, "=> [2, 3, 4, 'foo]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["setadd([2, 3, 4], 3)", <$format, ["br", [], [], 'do_br]>, "=> [2, 3, 4]"], 'do_dfn]>], #[['this, $help_func_setadd]]]>;
var $root inited = 1;
var $root managed = [$help_func_setadd];
var $help_node nolist = 0;


new object $help_func_setremove: $help_funcs_list;

var $root manager = $help_func_setremove;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "setremove()", "setremove()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " setremove(", <$format, ["i", [], ["LIST list"], 'do_i]>, ", ", <$format, ["i", [], ["ANY value"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function removes the argument ", <$format, ["i", [], ["value"], 'do_i]>, " from the argument ", <$format, ["i", [], ["list"], 'do_i]>, ", if it exists, and returns the result. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["setremove([2, 3, 4, 'foo], 'foo)", <$format, ["br", [], [], 'do_br]>, "=> [2, 3, 4]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["setremove([2, 3, 4], 5)", <$format, ["br", [], [], 'do_br]>, "=> [2, 3, 4]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["setremove([2, 3, 2, 4], 2)", <$format, ["br", [], [], 'do_br]>, "=> [3, 2, 4]"], 'do_dfn]>], #[['this, $help_func_setremove]]]>;
var $root inited = 1;
var $root managed = [$help_func_setremove];
var $help_node nolist = 0;


new object $help_func_sublist: $help_funcs_list;

var $root manager = $help_func_sublist;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "sublist()", "sublist()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " sublist(", <$format, ["i", [], ["LIST list"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER start"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER length"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a subrange of the list specified by ", <$format, ["i", [], ["list"], 'do_i]>, ". The subrange starts at position ", <$format, ["i", [], ["start"], 'do_i]>, ", and continues ", <$format, ["i", [], ["length"], 'do_i]>, " elements. If ", <$format, ["i", [], ["length"], 'do_i]>, " is unspecified, it will continue to the end of the list. If ", <$format, ["i", [], ["start"], 'do_i]>, " is outside of the range of the list, or ", <$format, ["i", [], ["length"], 'do_i]>, " will extend past the end of the list, the error ", <$format, ["tt", [], ["~range"], 'do_tt]>, " is thrown. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["sublist([2, 3, 4, 5, 6, 7], 2, 3)", <$format, ["br", [], [], 'do_br]>, "=> [3, 4, 5]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["sublist([2, 3, 4, 5, 6, 7], 3)", <$format, ["br", [], [], 'do_br]>, "=> [4, 5, 6, 7]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["sublist([2, 3, 4, 5, 6, 7], 7)", <$format, ["br", [], [], 'do_br]>, "=> []"], 'do_dfn]>], #[['this, $help_func_sublist]]]>;
var $root inited = 1;
var $root managed = [$help_func_sublist];
var $help_node nolist = 0;


new object $help_func_union: $help_funcs_list;

var $root manager = $help_func_union;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384460;
var $has_name name = ['prop, "union()", "union()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " union(", <$format, ["i", [], ["LIST list1"], 'do_i]>, ", ", <$format, ["i", [], ["LIST list2"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function adds each element of ", <$format, ["i", [], ["list2"], 'do_i]>, " to ", <$format, ["i", [], ["list1"], 'do_i]>, " which does not already exist in ", <$format, ["i", [], ["list1"], 'do_i]>, ". Elements which exist more than once in ", <$format, ["i", [], ["list2"], 'do_i]>, " will only be added to ", <$format, ["i", [], ["list1"], 'do_i]>, " once, but duplicate elements in ", <$format, ["i", [], ["list1"], 'do_i]>, " will remain. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["union([2, 3, 4], [4, 5, 4, 6])", <$format, ["br", [], [], 'do_br]>, "=> [2, 3, 4, 5, 6]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["union([2, 2, 4, 5], [4, 5, 6, 6, 7])", <$format, ["br", [], [], 'do_br]>, "=> [2, 2, 4, 5, 6, 7])"], 'do_dfn]>], #[['this, $help_func_union]]]>;
var $root inited = 1;
var $root managed = [$help_func_union];
var $help_node nolist = 0;


new object $help_func_listidx: $help_funcs_list;

var $root manager = $help_func_listidx;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855452888;
var $root managed = [$help_func_listidx];
var $has_name name = ['prop, "listidx()", "listidx()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " listidx(", <$format, ["i", [], ["LIST list"], 'do_i]>, ", ", <$format, ["i", [], ["ANY what"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER origin"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the position in the ", <$format, ["i", [], ["list"], 'do_i]>, " where ", <$format, ["i", [], ["what"], 'do_i]>, " exists--starting from ", <$format, ["i", [], ["origin"], 'do_i]>, "--or a zero if it does not exist. If ", <$format, ["i", [], ["origin"], 'do_i]>, " is not specified it will default to ", <$format, ["i", [], ["1"], 'do_i]>, ". The ", <$format, ["i", [], ["origin"], 'do_i]>, " represents where to start searching in the list. If it is a positive number it starts that many elements into the list. If it is a negative number it starts that many elements from the end of the list, and searches backwards--from the end of the list to the start. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["listidx([4, \"this\", [], 'bar], [])", <$format, ["br", [], [], 'do_br]>, "=> 3"], 'do_dfn]>, " ", <$format, ["dfn", [], ["listidx([4, \"this\", [], \"this\", 'bar], \"this\", -1)", <$format, ["br", [], [], 'do_br]>, "=> 4"], 'do_dfn]>, " ", <$format, ["dfn", [], ["listidx([4, \"this\", [], \"this\", 'bar], \"this\", -3)", <$format, ["br", [], [], 'do_br]>, "=> 2"], 'do_dfn]>], #[['this, $help_func_listidx]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_funcs_str: $help_coldc_func;

var $root manager = $help_funcs_str;
var $root child_index = 20;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "String", "String"];
var $help_node links = #[["crypt()", $help_func_crypt], ["explode()", $help_func_explode], ["lowercase()", $help_func_lowercase], ["match_begin()", $help_func_match_begin], ["match_crypted()", $help_func_match_crypted], ["match_pattern()", $help_func_match_pattern], ["match_regexp()", $help_func_match_regexp], ["match_template()", $help_func_match_template], ["pad()", $help_func_pad], ["regexp()", $help_func_regexp], ["split()", $help_func_split], ["strcmp()", $help_func_strcmp], ["strfmt()", $help_func_strfmt], ["strgraft()", $help_func_strgraft], ["stridx()", $help_func_stridx], ["strlen()", $help_func_strlen], ["strsed()", $help_func_strsed], ["strsub()", $help_func_strsub], ["substr()", $help_func_substr], ["uppercase()", $help_func_uppercase]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "26%,26%,26%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_crypt"]], ["crypt()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_explode"]], ["explode()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_lowercase"]], ["lowercase()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_match_begin"]], ["match_begin()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_match_crypted"]], ["match_crypted()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_match_pattern"]], ["match_pattern()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_match_regexp"]], ["match_regexp()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_match_template"]], ["match_template()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_pad"]], ["pad()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_regexp"]], ["regexp()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_split"]], ["split()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_strcmp"]], ["strcmp()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_strfmt"]], ["strfmt()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_strgraft"]], ["strgraft()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_stridx"]], ["stridx()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_strlen"]], ["strlen()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_strsed"]], ["strsed()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_strsub"]], ["strsub()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_substr"]], ["substr()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_uppercase"]], ["uppercase()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_str]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_str];
var $help_node nolist = 0;


new object $help_func_crypt: $help_funcs_str;

var $root manager = $help_func_crypt;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384455;
var $has_name name = ['prop, "crypt()", "crypt()"];
var $help_node links = #[["match_crypted()", $help_func_match_crypted]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " crypt(", <$format, ["i", [], ["STRING str"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING salt"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function performs one-way encryption on ", <$format, ["i", [], ["str"], 'do_i]>, ", using the SHA encryption routine. If ", <$format, ["i", [], ["salt"], 'do_i]>, " is not specified, it is chosen randomly. The return value of ", <$format, ["tt", [], ["crypt()"], 'do_tt]>, " is the encrypted string. ", <$format, ["np", [], [], 'do_np]>, "The encryption performed by this function has the property that it is very difficult to find a string which will produce a given result; however, a given string and a given salt will always yield the same encrypted string. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["crypt(\"foo\", \"ab\")", <$format, ["br", [], [], 'do_br]>, "=> \"$2$ab$TmSIW.xT3sTkwqUhTLxCH192J37\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "When matching an encrypted string versus a non-encrypted string, the function ", <$format, ["link", [["node", "$help_func_match_crypted"]], ["match_crypted()"], 'do_link]>, " should be used, as it will take into consideration any possible futer changes to the crypt() implementation."], #[['this, $help_func_crypt]]]>;
var $root inited = 1;
var $root managed = [$help_func_crypt];
var $help_node nolist = 0;


new object $help_func_explode: $help_funcs_str;

var $root manager = $help_func_explode;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384456;
var $has_name name = ['prop, "explode()", "explode()"];
var $help_node links = #[["split()", $help_func_split]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " explode(", <$format, ["i", [], ["STRING str"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING sep"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER want-blanks"], 'do_i]>, "]])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function breaks ", <$format, ["i", [], ["string"], 'do_i]>, " into a list of strings, using the string ", <$format, ["i", [], ["sep"], 'do_i]>, " as the delimiter. If ", <$format, ["i", [], ["sep"], 'do_i]>, " is unspecified it uses spaces as the delimiter. If ", <$format, ["i", [], ["want-blanks"], 'do_i]>, " is specified and is true ", <$format, ["tt", [], ["explode()"], 'do_tt]>, " will include zero-length strings in the final list, otherwise it will not. The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_split"]], ["split()"], 'do_link]>], 'do_tt]>, " is similar, but uses a regular expression as the delimiter. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["explode(\" foo bar baz\")", <$format, ["br", [], [], 'do_br]>, "=> [\"foo\", \"bar\", \"baz\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["explode(\"foo:bar::baz\", \":\")", <$format, ["br", [], [], 'do_br]>, "=> [\"foo\", \"bar\", \"baz\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["explode(\"foo:bar::baz\", \":\", 1)", <$format, ["br", [], [], 'do_br]>, "=> [\"foo\", \"bar\", \"\", \"baz\"]"], 'do_dfn]>], #[['this, $help_func_explode]]]>;
var $root inited = 1;
var $root managed = [$help_func_explode];
var $help_node nolist = 0;


new object $help_func_lowercase: $help_funcs_str;

var $root manager = $help_func_lowercase;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "lowercase()", "lowercase()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " lowercase(", <$format, ["i", [], ["STRING str"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function changes each character in ", <$format, ["i", [], ["str"], 'do_i]>, " to it's lowercase value and returns the result."], #[['this, $help_func_lowercase]]]>;
var $root inited = 1;
var $root managed = [$help_func_lowercase];
var $help_node nolist = 0;


new object $help_func_match_begin: $help_funcs_str;

var $root manager = $help_func_match_begin;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "match_begin()", "match_begin()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " match_begin(", <$format, ["i", [], ["STRING str"], 'do_i]>, ", ", <$format, ["i", [], ["STRING search"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING sep"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function looks for the string ", <$format, ["i", [], ["search"], 'do_i]>, " at the beginning of each word in ", <$format, ["i", [], ["str"], 'do_i]>, ". The word separator is given by the string ", <$format, ["i", [], ["sep"], 'do_i]>, " if it is specified; otherwise, a space (", <$format, ["tt", [], ["\" \""], 'do_tt]>, ") is used. The return value of ", <$format, ["tt", [], ["match_begin()"], 'do_tt]>, " is ", <$format, ["tt", [], ["1"], 'do_tt]>, " if ", <$format, ["i", [], ["search"], 'do_i]>, " was found at the beginning of a word in ", <$format, ["i", [], ["string"], 'do_i]>, ", or ", <$format, ["tt", [], ["0"], 'do_tt]>, " if not. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["match_begin(\"foo:bar:baz\", \"fo\", \":\")", <$format, ["br", [], [], 'do_br]>, "=> 1"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_begin(\"foo bar baz\", \"ar\")", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>], #[['this, $help_func_match_begin]]]>;
var $root inited = 1;
var $root managed = [$help_func_match_begin];
var $help_node nolist = 0;


new object $help_func_match_pattern: $help_funcs_str;

var $root manager = $help_func_match_pattern;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "match_pattern()", "match_pattern()"];
var $help_node links = #[["Matching Conventions", $help_commands_matching]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " match_pattern(", <$format, ["i", [], ["STRING string"], 'do_i]>, ", ", <$format, ["i", [], ["STRING pattern"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function matches the wildcard pattern ", <$format, ["i", [], ["pattern"], 'do_i]>, " against ", <$format, ["i", [], ["string"], 'do_i]>, ". A wildcard pattern is a string with asterixes (", <$format, ["tt", [], ["`*'"], 'do_tt]>, ") signifying wildcards. A regular character matches itself, while a wildcard matches any number of arbitrary characters. The return value of ", <$format, ["tt", [], ["match_pattern()"], 'do_tt]>, " is a list of the substrings of ", <$format, ["i", [], ["string"], 'do_i]>, " which matched the wildcards in ", <$format, ["i", [], ["pattern"], 'do_i]>, ", or ", <$format, ["tt", [], ["0"], 'do_tt]>, " if the match fails. More information on pattern matching can be found in the section ", <$format, ["link", [["node", "$help_commands_matching"]], ["Matching Conventions"], 'do_link]>, ". Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["match_pattern(\"foobar\", \"*\")", <$format, ["br", [], [], 'do_br]>, "=> [\"foobar\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_pattern(\"foo quux bar quuux baz\", \"foo * bar * baz\")", <$format, ["br", [], [], 'do_br]>, "=> [\"quux\", \"quuux\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_pattern(\"narf:fnord\", \"narf:*\")", <$format, ["br", [], [], 'do_br]>, "=> [\"fnord\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_pattern(\"foo baz\", \"foo * bar\")", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>], #[['this, $help_func_match_pattern]]]>;
var $root inited = 1;
var $root managed = [$help_func_match_pattern];
var $help_node nolist = 0;


new object $help_func_match_regexp: $help_funcs_str;

var $root manager = $help_func_match_regexp;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "match_regexp()", "match_regexp()"];
var $help_node links = #[["regexp()", $help_func_regexp], ["ColdC Regular Expressions", $help_func_regexp]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " match_regexp(", <$format, ["i", [], ["STRING str"], 'do_i]>, ", ", <$format, ["i", [], ["STRING regexp"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER cs"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function matches the regular expression argument ", <$format, ["i", [], ["regexp"], 'do_i]>, " against the argument ", <$format, ["i", [], ["str"], 'do_i]>, ". If ", <$format, ["i", [], ["cs"], 'do_i]>, " is specified and is true, the match is case-sensitive; otherwise, it is case-insensitive. If the match succeeds, ", <$format, ["tt", [], ["match_regexp()"], 'do_tt]>, " returns a ten-element list giving the substitutions for the match (see below); otherwise, ", <$format, ["tt", [], ["match_regexp()"], 'do_tt]>, " returns 0. If the argument ", <$format, ["i", [], ["regexp"], 'do_i]>, " is not a valid regular expression, the error ", <$format, ["tt", [], ["~regexp"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "This function is often used when all that is desired is whether a match was made or not. The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_regexp"]], ["regexp()"], 'do_link]>], 'do_tt]>, " is better for handling the full results of a regexp match. For more information on ColdC Regular Expressions see the section ", <$format, ["link", [["node", "$help_func_regexp"]], ["ColdC Regular Expressions"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "The substitutions are the text in ", <$format, ["i", [], ["str"], 'do_i]>, " which matches the parenthesized subexpressions in ", <$format, ["i", [], ["regexp"], 'do_i]>, ". The first substitution is the text in ", <$format, ["i", [], ["str"], 'do_i]>, " which matches the whole regexp. Thus, a regular expression can contain no more than nine parenthesized subexpressions. Substitutions are returned as two-element lists ", <$format, ["tt", [], [<$format, ["i", [], ["[start, len]"], 'do_i]>], 'do_tt]>, " giving the index of the matching text in ", <$format, ["i", [], ["str"], 'do_i]>, " and the length of the text. ", <$format, ["np", [], [], 'do_np]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["match_regexp(\"fooBAR\", \"bar\")", <$format, ["br", [], [], 'do_br]>, "=> [[4, 3], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_regexp(\"Greg says, 'Hello.'\", \"^([^ ]+) says, '(.*)'$\")", <$format, ["br", [], [], 'do_br]>, "=> [[1, 19], [1, 4], [13, 6], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_regexp(\" 300 100 200 \", \"[0-9]+\")", <$format, ["br", [], [], 'do_br]>, "=> [[2, 3], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_regexp(\"foo\", \"bar\")", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_regexp(\"Foo\", \"foo\", 1)", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>], #[['this, $help_func_match_regexp]]]>;
var $root inited = 1;
var $root managed = [$help_func_match_regexp];
var $help_node nolist = 0;


new object $help_func_match_template: $help_funcs_str;

var $root manager = $help_func_match_template;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "match_template()", "match_template()"];
var $help_node links = #[["Matching Conventions", $help_commands_matching]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " match_template(", <$format, ["i", [], ["STRING string"], 'do_i]>, ", ", <$format, ["i", [], ["STRING template"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function matches the template ", <$format, ["i", [], ["template"], 'do_i]>, " against the command ", <$format, ["i", [], ["string"], 'do_i]>, ". The return value of ", <$format, ["tt", [], ["match_template()"], 'do_tt]>, " is a list of fields resulting from the template match, or ", <$format, ["tt", [], ["0"], 'do_tt]>, " if the match fails or if ", <$format, ["i", [], ["template"], 'do_i]>, " is an invalid template. ", <$format, ["np", [], [], 'do_np]>, "General information on matching can be found in the section ", <$format, ["link", [["node", "$help_commands_matching"]], ["Matching Conventions"], 'do_link]>, ". Templates are composed of ", <$format, ["i", [], ["word-patterns"], 'do_i]>, " and ", <$format, ["i", [], ["wildcards"], 'do_i]>, ". ", <$format, ["i", [], ["Word-patterns"], 'do_i]>, " may contain a mix of the ", <$format, ["i", [], ["partial-match"], 'do_i]>, " operator and the ", <$format, ["i", [], ["or"], 'do_i]>, " operator. ", <$format, ["np", [], [], 'do_np]>, "A ", <$format, ["i", [], ["word-pattern"], 'do_i]>, " is any sequence of characters bounded by spaces, or the beginning or end of the string. The pattern may include a question mark (", <$format, ["tt", [], ["'?'"], 'do_tt]>, "), which is the ", <$format, ["i", [], ["partial-match"], 'do_i]>, " operator; or it may include any number of pipe characters (", <$format, ["tt", [], ["'|'"], 'do_tt]>, "), which is the ", <$format, ["i", [], ["or"], 'do_i]>, " operator. The result from a word-pattern match is the string which matched the word-pattern. ", <$format, ["np", [], [], 'do_np]>, "The ", <$format, ["i", [], ["partial-match"], 'do_i]>, " operator is used to indicate that partial matches that extend at least as far as the question mark are ok. For instance, the ", <$format, ["i", [], ["word-pattern"], 'do_i]>, " ", <$format, ["tt", [], ["\"ex?am\""], 'do_tt]>, " matches any of the words ", <$format, ["tt", [], ["\"ex\""], 'do_tt]>, ", ", <$format, ["tt", [], ["\"exa\""], 'do_tt]>, " and ", <$format, ["tt", [], ["\"exam\""], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "The ", <$format, ["i", [], ["or"], 'do_i]>, " operator is used to group more than one word where any of the words in the group can be matched as one word. For instance, the template ", <$format, ["tt", [], ["\"this|that|there\""], 'do_tt]>, " would match ", <$format, ["tt", [], ["\"this\""], 'do_tt]>, " ", <$format, ["i", [], ["OR"], 'do_i]>, " ", <$format, ["tt", [], ["\"that\""], 'do_tt]>, " ", <$format, ["i", [], ["OR"], 'do_i]>, " ", <$format, ["tt", [], ["\"there\""], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, <$format, ["i", [], ["Wildcards"], 'do_i]>, " can be either ", <$format, ["i", [], ["simple"], 'do_i]>, " or ", <$format, ["i", [], ["coupled"], 'do_i]>, ". A ", <$format, ["i", [], ["simple wildcard"], 'do_i]>, " is represented by an asterix (", <$format, ["tt", [], ["'*'"], 'do_tt]>, "). A simple wildcard matches any number of words in ", <$format, ["i", [], ["string"], 'do_i]>, ", and must be bounded by spaces or the beginning or end of the template. If the wildcard is followed in the template by a word-pattern, then it can also match a ", <$format, ["i", [], ["quoted wildcard match"], 'do_i]>, ". ", <$format, ["np", [], [], 'do_np]>, "A quoted wildcard match is just like a ColdC string literal: it begins and ends with a double quote (", <$format, ["tt", [], ["'\"'"], 'do_tt]>, "), and can include a literal double quote or backslash by preceding the character with a backslash (", <$format, ["tt", [], ["'\'"], 'do_tt]>, "). If the simple wildcard is followed by a word-pattern, and the words in ", <$format, ["i", [], ["string"], 'do_i]>, " that the wildcard would match begin with a double quote, then the match must be a quoted wildcard match or the match fails, even if the match would have succeeded if the words were not treated as a quoted wildcard match. However, if the words that the wildcard would match begin with a backslash followed by a double quote, then the backslash is ignored and the double quote and the text following it are treated as regular words. ", <$format, ["np", [], [], 'do_np]>, "The following template using a ", <$format, ["i", [], ["simple wildcard"], 'do_i]>, " ", <$format, ["tt", [], ["\"* bar\""], 'do_tt]>, " matches any of the following strings:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["foo bar", <$format, ["br", [], [], 'do_br]>, "foo baz bar", <$format, ["br", [], [], 'do_br]>, "\"foo bar \" baz\" bar", <$format, ["br", [], [], 'do_br]>, "\"foo baz bar"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Matching against a simple wildcard produces one result per wildcard--the words that the simple wildcard matched. If the wildcard matches a quoted wildcard match, then the beginning and ending double quotes are stripped out of the result, as well as any backslashes used to escape characters inside the double quotes. ", <$format, ["np", [], [], 'do_np]>, "A ", <$format, ["i", [], ["coupled wildcard"], 'do_i]>, " is represented by the three-character sequence ", <$format, ["tt", [], ["'*=*'"], 'do_tt]>, ". It matches any sequence of words containing an equal sign (", <$format, ["tt", [], ["'='"], 'do_tt]>, "), and results in two strings, the text before the equal sign and the text after it. Any spaces surrounding the equal sign in the matched string are ignored and do not show up in the results. The text before the equal sign can be a quoted wildcard match (as before, if it begins with a double quote, then it must be a quoted wildcard match or the match fails, unless the initial double quote is escaped by a backslash). If the coupled wildcard is followed by a word pattern, then the text after the equal sign can also be a quoted wildcard match. The coupled wildcard is a special feature intended for parsing TinyMUD command formats. ", <$format, ["np", [], [], 'do_np]>, " Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["match_template(\"@descr me as foobar\", \"@desc?ribe * as *\")", <$format, ["br", [], [], 'do_br]>, "=> [\"@descr\", \"me\", \"as\", \"foobar\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_template(\"@desc \\\"as is\\\" as foobar\", \"@desc?ribe * as *\")", <$format, ["br", [], [], 'do_br]>, "=> [\"@desc\", \"as is\", \"as\", \"foobar\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_template(\"@desc \\\"as\\\" is as foobar\", \"@desc?ribe * as *\")", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_template(\"@desc \\\"as\" is as foobar\", \"@desc?ribe * as *\")", <$format, ["br", [], [], 'do_br]>, "=> [\"@desc\", \"\\\"as\\\" is\", \"as\", \"foobar\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_template(\"@descr me =foobar\", \"@desc?ribe *=*\")", <$format, ["br", [], [], 'do_br]>, "=> [\"@descr\", \"me\", \"foobar\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_template(\"@desc \"2+2=4\"= an equation\", \"@desc?ribe *=*\")", <$format, ["br", [], [], 'do_br]>, "=> [\"@desc\", \"2+2=4\", \"an equation\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["match_template(\"look at rose\", \"l?ook|ex?amine *\")", <$format, ["br", [], [], 'do_br]>, "=> [\"look\", \"at rose\"]"], 'do_dfn]>], #[['this, $help_func_match_template]]]>;
var $root inited = 1;
var $root managed = [$help_func_match_template];
var $help_node nolist = 0;


new object $help_func_pad: $help_funcs_str;

var $root manager = $help_func_pad;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "pad()", "pad()"];
var $help_node links = #[["strfmt()", $help_func_strfmt]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " pad(", <$format, ["i", [], ["STRING str"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER length"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING filler"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function pads or truncates the argument ", <$format, ["i", [], ["string"], 'do_i]>, " to the length given with the argument ", <$format, ["i", [], ["length"], 'do_i]>, ". If the argument ", <$format, ["i", [], ["filler"], 'do_i]>, " is specified, then it is used to pad the string, otherwise a space is used. If ", <$format, ["i", [], ["length"], 'do_i]>, " is greater than the length of ", <$format, ["i", [], ["string"], 'do_i]>, ", then ", <$format, ["i", [], ["pad"], 'do_i]>, " adds filler characters on the right. If the length is a negative amount, filler will be added on the left instead. The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_strfmt"]], ["strfmt()"], 'do_link]>], 'do_tt]>, " may also be used for string padding. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["pad(\"foo\", 6)", <$format, ["br", [], [], 'do_br]>, "=> \"foo \""], 'do_dfn]>, " ", <$format, ["dfn", [], ["pad(\"foobar\", 3)", <$format, ["br", [], [], 'do_br]>, "=> \"foo\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["pad(tostr(29), -4, \"0\")", <$format, ["br", [], [], 'do_br]>, "=> \"0029\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["pad(\"what\", 20, \"!?!\")", <$format, ["br", [], [], 'do_br]>, "=> \"what!?!!?!!?!!?!!?!!\""], 'do_dfn]>], #[['this, $help_func_pad]]]>;
var $root inited = 1;
var $root managed = [$help_func_pad];
var $help_node nolist = 0;


new object $help_func_regexp: $help_funcs_str;

var $root manager = $help_func_regexp;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "regexp()", "regexp()"];
var $help_node links = #[["ColdC Regular Expressions", $help_coldc_regexp], ["match_regexp()", $help_func_match_regexp]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " regexp(", <$format, ["i", [], ["STRING str"], 'do_i]>, ", ", <$format, ["i", [], ["STRING regexp"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER cs"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function matches the regular expression argument ", <$format, ["i", [], ["regexp"], 'do_i]>, " against the argument ", <$format, ["i", [], ["str"], 'do_i]>, ". If ", <$format, ["i", [], ["cs"], 'do_i]>, " is specified and is true, the match is case-sensitive; otherwise, it is case-insensitive. If the match succeeds, ", <$format, ["tt", [], ["regexp()"], 'do_tt]>, " returns a list of the matches in ", <$format, ["i", [], ["string"], 'do_i]>, ", or zero if it did not match. If ", <$format, ["i", [], ["regexp"], 'do_i]>, " is not a valid regular expression the error ", <$format, ["tt", [], ["~regexp"], 'do_tt]>, " is thrown. ", <$format, ["np", [], [], 'do_np]>, "For more information on Regular Expressions see the section ", <$format, ["link", [["node", "$help_coldc_regexp"]], ["ColdC Regular Expressions"], 'do_link]>, ". The function ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_match_regexp"]], ["match_regexp()"], 'do_link]>], 'do_tt]>, " is similar, and better when all that is desired is whether the regexp matches or not. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["regexp(\"bar\", \"fooBAR\")", <$format, ["br", [], [], 'do_br]>, "=> [\"BAR\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["regexp(\"^([^ ]+) says, '(.*)'$\", \"Greg says, 'Hello.'\")", <$format, ["br", [], [], 'do_br]>, "=> [\"Greg\", \"Hello.\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["regexp(\"[0-9]+\", \" 300 100 200 \")", <$format, ["br", [], [], 'do_br]>, "=> [\"300\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["regexp(\"foo\", \"bar\")", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>, " ", <$format, ["dfn", [], ["regexp(\"foo\", \"Foo\", 1)", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>], #[['this, $help_func_regexp]]]>;
var $root inited = 1;
var $root managed = [$help_func_regexp];
var $help_node nolist = 0;


new object $help_func_strcmp: $help_funcs_str;

var $root manager = $help_func_strcmp;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "strcmp()", "strcmp()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " strcmp(", <$format, ["i", [], ["STRING str1"], 'do_i]>, ", ", <$format, ["i", [], ["STRING str2"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function compares ", <$format, ["i", [], ["str1"], 'do_i]>, " against ", <$format, ["i", [], ["str2"], 'do_i]>, " and returns zero if they are equal, greater than zero if ", <$format, ["i", [], ["string1"], 'do_i]>, " is lexically greater than ", <$format, ["i", [], ["string2"], 'do_i]>, ", and less than zero if ", <$format, ["i", [], ["string1"], 'do_i]>, " is lexically less than ", <$format, ["i", [], ["string2"], 'do_i]>, ". The comparison performed by ", <$format, ["tt", [], ["strcmp()"], 'do_tt]>, " is case-sensitive. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["strcmp(\"Foo\", \"bar\")", <$format, ["br", [], [], 'do_br]>, "=> -28"], 'do_dfn]>, " ", <$format, ["dfn", [], ["strcmp(\"cashmir\", \"cashmiR\")", <$format, ["br", [], [], 'do_br]>, "=> 32"], 'do_dfn]>, " ", <$format, ["dfn", [], ["strcmp(\"foo\", \"foo\")", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>], #[['this, $help_func_strcmp]]]>;
var $root inited = 1;
var $root managed = [$help_func_strcmp];
var $help_node nolist = 0;


new object $help_func_strfmt: $help_funcs_str;

var $root manager = $help_func_strfmt;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "strfmt()", "strfmt()"];
var $help_node links = #[["using the arithmetic operator", $help_coldc_non_arith]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " strfmt(", <$format, ["i", [], ["STRING format"], 'do_i]>, ", ", <$format, ["i", [], ["ANY arg"], 'do_i]>, ", ", <$format, ["i", [], ["..."], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function formats its arguments and returns the result. How the arguments are formatted depends upon the argument ", <$format, ["i", [], ["format"], 'do_i]>, ". The format contains two types of sequences: plain characters, which are simply copied to the new string, and format specifications, each of which causes printing of the next successive argument. The format begins with a percent character (", <$format, ["tt", [], ["%"], 'do_tt]>, "), followed by:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], ["Pad Length"], 'do_dt]>, <$format, ["dd", [], ["The pad length is an integer which specifies the length of characters to pad the argument in. Pad Length is optional. Specifying a zero pad length will be ignored, and is equivalent to not specifying a pad length."], 'do_dd]>, <$format, ["dt", [], ["Precision"], 'do_dt]>, <$format, ["dd", [], ["A period (", <$format, ["tt", [], ["."], 'do_tt]>, "), followed by an integer specifies the precision, which specifies the number of digits to appear after the decimal point when printing FLOAT arguments. Precision is optional, and does not have to be specified. If it is specified it must come after the Pad Length (if specified), and before the Filler (if specified) or Format Type."], 'do_dd]>, <$format, ["dt", [], ["Filler"], 'do_dt]>, <$format, ["dd", [], ["Filler specifies what is used when padding a string within the Pad Length. Filler is specified within curly braces (", <$format, ["tt", [], ["{"], 'do_tt]>, " and ", <$format, ["tt", [], ["}"], 'do_tt]>, "). To include a curly brace in the filler prefix it with a backslash. The Filler must come after Pad Length or Precision, if they are specified, and before Format Type."], 'do_dd]>, <$format, ["dt", [], ["Format Type"], 'do_dt]>, <$format, ["dd", [], ["Format type must be specified last, and is not optional. Format Type specifies how the argument is to be handled. It is one of the following characters:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["b", [], ["d"], 'do_b]>, " or ", <$format, ["b", [], ["D"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["literal data"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["s"], 'do_b]>, " or ", <$format, ["b", [], ["S"], 'do_b]>, " or ", <$format, ["b", [], ["l"], 'do_b]>, " or ", <$format, ["b", [], ["L"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["any data, align left"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["r"], 'do_b]>, " or ", <$format, ["b", [], ["R"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["any data, align right"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["c"], 'do_b]>, " or ", <$format, ["b", [], ["C"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["any data, align centered "], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], ["e"], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["any data, align left with an elipse"], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "If the Format Type is anything but ", <$format, ["b", [], ["d"], 'do_b]>, " or ", <$format, ["b", [], ["D"], 'do_b]>, ", the data will be converted as if it were \"added\" to a string ", <$format, ["link", [["node", "$help_coldc_non_arith"]], ["using the arithmetic operator"], 'do_link]>, ". If an uppercase character is used in the Format Type, any argument which has a length longer than the Pad Length will be truncated accordingly. Otherwise the argument will not be truncated. If an elipse is used, the argument will always be truncated three characters shorter than the Pad Length, with ", <$format, ["tt", [], ["\"...\""], 'do_tt]>, " being placed at the end."], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["strfmt(\"%r\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \"test\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%l\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \"test\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%c\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \"test\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%d\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \"\"test\"\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%10r\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \" test\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%10l\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \"test \""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%10c\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \" test \""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%10{|>}r\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \"|>|>|>test\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%10{|>}l\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \"test|>|>|>\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%10{|>}c\", \"test\")", <$format, ["br", [], [], 'do_br]>, "=> \"|>|test|>|\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%.2l\", 1.1214)", <$format, ["br", [], [], 'do_br]>, "=> \"1.12\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%10.3{0}r\", 1.1214)", <$format, ["br", [], [], 'do_br]>, "=> \"000001.121\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%10.3{0}r\", 1.1214)", <$format, ["br", [], [], 'do_br]>, "=> \"1.12100000\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%5e\", \"testing\")", <$format, ["br", [], [], 'do_br]>, "=> \"te...\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["strfmt(\"%s parents: %25e\", \"$user\", [$body, $interaction, $mail_ui]);", <$format, ["br", [], [], 'do_br]>, "=> \"$user parents: [$body, $interaction, ...\""], 'do_dfn]>], #[['this, $help_func_strfmt]]]>;
var $root inited = 1;
var $root managed = [$help_func_strfmt];
var $help_node nolist = 0;


new object $help_func_strgraft: $help_funcs_str;

var $root manager = $help_func_strgraft;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "strgraft()", "strgraft()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " strgraft(", <$format, ["i", [], ["STRING str"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER pos"], 'do_i]>, ", ", <$format, ["i", [], ["STRING str2"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function grafts a string into another string. It will take the string specified by ", <$format, ["i", [], ["str2"], 'do_i]>, " and insert it into ", <$format, ["i", [], ["str"], 'do_i]>, ", starting at the position specified by ", <$format, ["i", [], ["pos"], 'do_i]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["strgraft(\"this string\", 6, \"is a \")", <$format, ["br", [], [], 'do_br]>, "=> \"this is a string\""], 'do_dfn]>], #[['this, $help_func_strgraft]]]>;
var $root inited = 1;
var $root managed = [$help_func_strgraft];
var $help_node nolist = 0;


new object $help_func_strlen: $help_funcs_str;

var $root manager = $help_func_strlen;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "strlen()", "strlen()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " strlen(", <$format, ["i", [], ["STRING string"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the length of ", <$format, ["i", [], ["string"], 'do_i]>, "."], #[['this, $help_func_strlen]]]>;
var $root inited = 1;
var $root managed = [$help_func_strlen];
var $help_node nolist = 0;


new object $help_func_strsed: $help_funcs_str;

var $root manager = $help_func_strsed;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384458;
var $has_name name = ['prop, "strsed()", "strsed()"];
var $help_node links = #[["Regular Expressions", $help_coldc_regexp]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STR"], 'do_i]>, " strsed(", <$format, ["i", [], ["STR rx"], 'do_i]>, ", ", <$format, ["i", [], ["STR str"], 'do_i]>, ", ", <$format, ["i", [], ["STR replace"], 'do_i]>, "[, ", <$format, ["i", [], ["STR flags"], 'do_i]>, "[, ", <$format, ["i", [], ["INT count"], 'do_i]>, "]])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This functions similar ", <$format, ["tt", [], ["sed"], 'do_tt]>, " in many unix systems. It searches for any occurances of ", <$format, ["i", [], ["regexp"], 'do_i]>, " in ", <$format, ["i", [], ["string"], 'do_i]>, " and replaces them with ", <$format, ["i", [], ["replace"], 'do_i]>, ", returning the result. The optional fourth argument is used to specify flags for sed. Flags are any of the following characters within a string: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "5%,95%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["g"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Match the regular expression globally througout the string"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["s"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Single match--Match the first occurance only (default)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["c"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Case matters when matching"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["i"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Case doesn't matter when matching (default)"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "For more information, see the section on ", <$format, ["link", [["node", "$help_coldc_regexp"]], ["Regular Expressions"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "The fifth argument ", <$format, ["i", [], ["count"], 'do_i]>, " is intended to optimize the use of this function, and is generally not used. It is simply an optimizing guideline which specifies how many expected occurances of the regular expression are expected in the string. This value is used when computing the initial size of the resulting string, to lower the amount of memory allocations which may have to be performed. ", <$format, ["np", [], [], 'do_np]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["strsed(\"foObar\", \"o+\", \"X\")", <$format, ["br", [], [], 'do_br]>, "=> \"fXbar\" ", <$format, ["np", [], [], 'do_np]>, "strsed(\"foObar\", \"o+\", \"X\", \"o\")", <$format, ["br", [], [], 'do_br]>, "=> \"fXObar\""], 'do_dfn]>], #[['this, $help_func_strsed]]]>;
var $root inited = 1;
var $root managed = [$help_func_strsed];
var $help_node nolist = 0;


new object $help_func_strsub: $help_funcs_str;

var $root manager = $help_func_strsub;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "strsub()", "strsub()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " strsub(", <$format, ["i", [], ["STRING str"], 'do_i]>, ", ", <$format, ["i", [], ["STRING what"], 'do_i]>, ", ", <$format, ["i", [], ["STRING replace"], 'do_i]>, "[, ", <$format, ["i", [], ["STRING flags"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function searches for occurances of the string ", <$format, ["i", [], ["what"], 'do_i]>, " within the string ", <$format, ["i", [], ["str"], 'do_i]>, " and replaces them with ", <$format, ["i", [], ["replace"], 'do_i]>, ". By default it will replace any occurance, and will do case-insensitive comparisons. The optional fourth argument can be any of the following characters within the string: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "5%,95%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["g"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Match globally througout the string (default)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["s"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Single match--Match the first occurance only"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["c"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Case matters when matching"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], ["i"], 'do_b]>], 'do_td]>, <$format, ["td", [], ["Case doesn't matter when matching (default)"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["strsub(\"fooBar\", \"bar\", \"baz\")", <$format, ["br", [], [], 'do_br]>, "=> \"foobaz\" ", <$format, ["np", [], [], 'do_np]>, "strsub(\"fooBar\", \"bar\", \"baz\", \"c\")", <$format, ["br", [], [], 'do_br]>, "=> \"fooBar\""], 'do_dfn]>], #[['this, $help_func_strsub]]]>;
var $root inited = 1;
var $root managed = [$help_func_strsub];
var $help_node nolist = 0;


new object $help_func_substr: $help_funcs_str;

var $root manager = $help_func_substr;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384459;
var $has_name name = ['prop, "substr()", "substr()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " substr(", <$format, ["i", [], ["STRING str"], 'do_i]>, ", ", <$format, ["i", [], ["INTEGER start"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER length"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a subrange of ", <$format, ["i", [], ["string"], 'do_i]>, ". The subrange starts at the character specified by ", <$format, ["i", [], ["start"], 'do_i]>, " and continues ", <$format, ["i", [], ["length"], 'do_i]>, " characters. If ", <$format, ["i", [], ["length"], 'do_i]>, " is unspecified it continues to the end of the string. If ", <$format, ["i", [], ["start"], 'do_i]>, " is outside of the range of the string, or ", <$format, ["i", [], ["length"], 'do_i]>, " will extend past the end of the string, the error ", <$format, ["tt", [], ["~range"], 'do_tt]>, " is thrown. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["substr(\"foobar\", 2, 3)", <$format, ["br", [], [], 'do_br]>, "=> \"oob\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["substr(\"foobar\", 3)", <$format, ["br", [], [], 'do_br]>, "=> \"obar\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["substr(\"foobar\", 7)", <$format, ["br", [], [], 'do_br]>, "=> \"\""], 'do_dfn]>], #[['this, $help_func_substr]]]>;
var $root inited = 1;
var $root managed = [$help_func_substr];
var $help_node nolist = 0;


new object $help_func_uppercase: $help_funcs_str;

var $root manager = $help_func_uppercase;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384460;
var $has_name name = ['prop, "uppercase()", "uppercase()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["STRING"], 'do_i]>, " uppercase(", <$format, ["i", [], ["STRING str"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function changes each character in ", <$format, ["i", [], ["str"], 'do_i]>, " to it's uppercase value and returns the result."], #[['this, $help_func_uppercase]]]>;
var $root inited = 1;
var $root managed = [$help_func_uppercase];
var $help_node nolist = 0;


new object $help_func_match_crypted: $help_funcs_str;

var $root manager = $help_func_match_crypted;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855385456;
var $root managed = [$help_func_match_crypted];
var $has_name name = ['prop, "match_crypted()", "match_crypted()"];
var $help_node links = #[["crypt()", $help_func_crypt]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " match_crypted(", <$format, ["i", [], ["STRING crypted"], 'do_i]>, ", ", <$format, ["i", [], ["STRING matchwith"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function is used to match strings encrypted with the ", <$format, ["tt", [], [<$format, ["link", [["node", "$help_func_crypt"]], ["crypt()"], 'do_link]>], 'do_tt]>, " function. This function should be used instead of directly comparing the result, as it will take into account possible older encryption methods. It returns one if there is a correct match, or zero if there is not. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["match_crypted(\"$SHA1$dEqOGo3d$.lpP/K19QevbwpgSiCsGVnCnrv2\", \"foo\")", <$format, ["br", [], [], 'do_br]>, "=> 1"], 'do_dfn]>], #[['this, $help_func_match_crypted]]]>;
var $root inited = 1;
var $help_node index = $help_index_function;
var $help_node nolist = 0;


new object $help_func_split: $help_funcs_str;

var $root manager = $help_func_split;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855434905;
var $root managed = [$help_func_split];
var $has_name name = ['prop, "split()", "split()"];
var $help_node links = #[["regular expression", $help_coldc_regexp]];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["LIST"], 'do_i]>, " split(", <$format, ["i", [], ["STRING str"], 'do_i]>, ", ", <$format, ["i", [], ["STRING regexp"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER regexp-args"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function breaks ", <$format, ["i", [], ["string"], 'do_i]>, " into a list of strings, using the second argument ", <$format, ["i", [], ["regexp"], 'do_i]>, " (a ", <$format, ["link", [["node", "$help_coldc_regexp"]], ["regular expression"], 'do_link]>, ") as a delimiter. The third argument is optional, and is a string containing character flags which can change the behaviour of ", <$format, ["tt", [], ["split()"], 'do_tt]>, ". Flags can be any: ", <$format, ["dfn", [["ind", "4"], ["nobound", 1]], [<$format, ["table", [["cols", "5%,95%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["b"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Keep blank entries (default is to ignore)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["c"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Case sensitive match"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["i"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Case insensitive match (default)"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["split(\" foo bar baz\", \" +\")", <$format, ["br", [], [], 'do_br]>, "=> [\"foo\", \"bar\", \"baz\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["split(\"foo:bar::baz\", \":\", \"b\")", <$format, ["br", [], [], 'do_br]>, "=> [\"foo\", \"bar\", \"\", \"baz\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["split(\"fobibobIbidilly\", \"i\")", <$format, ["br", [], [], 'do_br]>, "=> [\"fob\", \"bob\", \"b\", \"d\", \"lly\"]"], 'do_dfn]>, " ", <$format, ["dfn", [], ["split(\"fobIbobibidIlly\", \"i\", \"cb\")", <$format, ["br", [], [], 'do_br]>, "=> [\"fobIbob\", \"b\", \"dIlly\"]"], 'do_dfn]>], #[['this, $help_func_split]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_func_stridx: $help_funcs_str;

var $root manager = $help_func_stridx;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855767859;
var $root managed = [$help_func_stridx];
var $has_name name = ['prop, "stridx()", "stridx()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " stridx(", <$format, ["i", [], ["BUFFER str"], 'do_i]>, ", ", <$format, ["i", [], ["STRING what"], 'do_i]>, "[, ", <$format, ["i", [], ["INTEGER origin"], 'do_i]>, "])"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the position in ", <$format, ["i", [], ["str"], 'do_i]>, " where ", <$format, ["i", [], ["what"], 'do_i]>, " exists--starting from ", <$format, ["i", [], ["origin"], 'do_i]>, "--or a zero if it does not exist. If ", <$format, ["i", [], ["origin"], 'do_i]>, " is not specified it will default to ", <$format, ["i", [], ["1"], 'do_i]>, ". The ", <$format, ["i", [], ["origin"], 'do_i]>, " represents where to start searching in the string. If it is a positive number it starts that many elements into the string. If it is a negative number it starts that many elements from the end of the string, and searches backwards--from the end of the string to the start. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["stridx(\"this test ok\", \"e\")", <$format, ["br", [], [], 'do_br]>, "=> 7 ", <$format, ["np", [], [], 'do_np]>, "stridx(\"this test ok\", \"t\", -1)", <$format, ["br", [], [], 'do_br]>, "=> 9 ", <$format, ["np", [], [], 'do_np]>, "stridx(\"this test ok\", \"t\", -5)", <$format, ["br", [], [], 'do_br]>, "=> 6 ", <$format, ["np", [], [], 'do_np]>, "stridx(\"this test ok\", \"alf\")", <$format, ["br", [], [], 'do_br]>, "=> 0"], 'do_dfn]>], #[['this, $help_func_stridx]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_funcs_num: $help_coldc_func;

var $root manager = $help_funcs_num;
var $root child_index = 5;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384021;
var $has_name name = ['prop, "Numeric", "Numeric"];
var $help_node links = #[["abs()", $help_func_abs], ["acos()", $help_func_math], ["asin()", $help_func_math], ["atan()", $help_func_math], ["atan2()", $help_func_math], ["cos()", $help_func_math], ["exp()", $help_func_math], ["log()", $help_func_math], ["Math", $help_func_math], ["max()", $help_func_max], ["min()", $help_func_min], ["pow()", $help_func_math], ["random()", $help_func_random], ["sin()", $help_func_math], ["sqrt()", $help_func_math], ["tan()", $help_func_math]];
var $help_node body = <$ctext_frob, [[<$format, ["table", [["cols", "16%,16%,16%,16%,16%,16%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_abs"]], ["abs()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["acos()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["asin()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["atan()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["atan2()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["cos()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["exp()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["log()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["Math"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_max"]], ["max()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_min"]], ["min()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["pow()"], 'do_link]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["link", [["node", "$help_func_random"]], ["random()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["sin()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["sqrt()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [<$format, ["link", [["node", "$help_func_math"]], ["tan()"], 'do_link]>], 'do_td]>, <$format, ["td", [], [], 'do_td]>, <$format, ["td", [], [], 'do_td]>], 'do_tr]>], 'do_table]>], #[['this, $help_funcs_num]]]>;
var $root inited = 1;
var $root managed = [$help_funcs_num];
var $help_node nolist = 0;


new object $help_func_abs: $help_funcs_num;

var $root manager = $help_func_abs;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384033;
var $has_name name = ['prop, "abs()", "abs()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER|FLOAT"], 'do_i]>, " abs(", <$format, ["i", [], ["INTEGER|FLOAT number"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the absolute value of ", <$format, ["i", [], ["number"], 'do_i]>, ", where ", <$format, ["i", [], ["number"], 'do_i]>, " can be either a float or an integer (and the same type of value is returned). Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["tt", [], ["abs(-6)", <$format, ["br", [], [], 'do_br]>, "=> 6 ", <$format, ["np", [], [], 'do_np]>, "abs(7)", <$format, ["br", [], [], 'do_br]>, "=> 7 ", <$format, ["np", [], [], 'do_np]>, "abs(-000.12)", <$format, ["br", [], [], 'do_br]>, "=> 0.120000"], 'do_tt]>], 'do_dfn]>], #[['this, $help_func_abs]]]>;
var $root inited = 1;
var $root managed = [$help_func_abs];
var $help_node nolist = 0;


new object $help_func_math: $help_funcs_num;

var $root manager = $help_func_math;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384130;
var $has_name name = ['prop, "Math|sin()|exp()|log()|cos()|tan()|sqrt()|asin()|acos()|atan()|pow()|atan2()", "Math|sin()|exp()|log()|cos()|tan()|sqrt()|asin()|acos()|atan()|pow()|atan2()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["FLOAT"], 'do_i]>, " sin(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " exp(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " log(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " cos(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " tan(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " sqrt(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " asin(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " acos(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " atan(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " pow(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ", ", <$format, ["i", [], ["FLOAT y"], 'do_i]>, ")", <$format, ["br", [], [], 'do_br]>, <$format, ["i", [], ["FLOAT"], 'do_i]>, " atan2(", <$format, ["i", [], ["FLOAT x"], 'do_i]>, ", ", <$format, ["i", [], ["FLOAT y"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function performs the relevant mathematic function on the argument(s) and returns the result. Further information on each function can be found in the unix man page on the same relative function, in C. The precision of the function may vary by the implementation. If a floating point exception occurs, the error ~fpe is thrown."], #[['this, $help_func_math]]]>;
var $root inited = 1;
var $root child_index = 1;
var $root managed = [$help_func_math];
var $help_node nolist = 0;


new object $help_func_max: $help_funcs_num;

var $root manager = $help_func_max;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "max()", "max()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ANY"], 'do_i]>, " max(", <$format, ["i", [], ["ANY arg"], 'do_i]>, ", ", <$format, ["i", [], ["..."], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the maximum of its arguments. All of the arguments must be of the same type, and must be integers or strings.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["max(3, 7, 9, 5)", <$format, ["br", [], [], 'do_br]>, "=> 9"], 'do_dfn]>, " ", <$format, ["dfn", [], ["max(\"Foo\", \"aardvark\", \"bar\", \"Quux\")", <$format, ["br", [], [], 'do_br]>, "=> \"Quux\""], 'do_dfn]>], #[['this, $help_func_max]]]>;
var $root inited = 1;
var $root managed = [$help_func_max];
var $help_node nolist = 0;


new object $help_func_min: $help_funcs_num;

var $root manager = $help_func_min;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "min()", "min()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["ANY"], 'do_i]>, " min(", <$format, ["i", [], ["ANY arg"], 'do_i]>, ", ", <$format, ["i", [], ["..."], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns the minimum of its arguments. All of the arguments must be of the same type, and must be integers or strings.", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["min(3, 7, 9, 5)", <$format, ["br", [], [], 'do_br]>, "=> 3"], 'do_dfn]>, " ", <$format, ["dfn", [], ["min(\"Foo\", \"aardvark\", \"bar\", \"Quux\")", <$format, ["br", [], [], 'do_br]>, "=> \"aardvark\""], 'do_dfn]>], #[['this, $help_func_min]]]>;
var $root inited = 1;
var $root managed = [$help_func_min];
var $help_node nolist = 0;


new object $help_func_random: $help_funcs_num;

var $root manager = $help_func_random;
var $help_node index = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855384457;
var $has_name name = ['prop, "random()", "random()"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], [<$format, ["tt", [], [<$format, ["i", [], ["INTEGER"], 'do_i]>, " random(", <$format, ["i", [], ["INTEGER max"], 'do_i]>, ")"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "This function returns a random integer between one and ", <$format, ["i", [], ["max"], 'do_i]>, ". Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["random(10)", <$format, ["br", [], [], 'do_br]>, "=> 3"], 'do_dfn]>], #[['this, $help_func_random]]]>;
var $root inited = 1;
var $root managed = [$help_func_random];
var $help_node nolist = 0;


new object $help_coldc_native: $help_coldc;

var $root manager = $help_coldc_native;
var $help_node index = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854058134;
var $has_name name = ['prop, "Native Method Reference", "Native Method Reference"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[['this, $help_coldc_native]]]>;
var $root inited = 1;
var $root managed = [$help_coldc_native];
var $help_node nolist = 0;


new object $help_reference: $help_coldcore;

var $root manager = $help_reference;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847916304;
var $has_name name = ['prop, "Reference Library", "Reference Library"];
var $help_node links = #[["Subsystem", $help_index_subsystem], ["Object", $help_index_objects]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Nodes from this point down are for core subsystem documentation and documentation on specific objects.", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_index_subsystem"]], ["Subsystem"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Subsystems Index"], 'do_dd]>, <$format, ["dt", [], [<$format, ["b", [], [<$format, ["link", [["node", "$help_index_objects"]], ["Object"], 'do_link]>], 'do_b]>], 'do_dt]>, <$format, ["dd", [], ["Core Objects Index"], 'do_dd]>], 'do_dl]>], #[['this, $help_reference]]]>;
var $root inited = 1;
var $help_node index = $help_index_core;
var $root managed = [$help_reference];
var $root owned = [$help_reference];
var $help_node nolist = 0;


new object $help_updates: $help_coldcore;

var $root manager = $help_updates;
var $help_updates dirty = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848537316;
var $help_node index = $help_index_subsystem;
var $has_name name = ['prop, "Updates", "Updates"];
var $help_node links = #[["Word", $help_sys_word], ["@nh", $help_cmd_nh], ["Attributes", $help_sys_weather_attributes], ["Climate", $help_sys_climate], ["Weather", $help_weather_system], ["@ant", $help_cmd_ant], ["@dnt", $help_cmd_dnt], ["@remember", $help_cmd_remember], ["@rename", $help_cmd_rename], ["Appearance", $help_appearance], ["Building", $help_building], ["Description", $help_app_desc], ["Environment", $help_environment], ["Gender", $help_app_gender], ["General", $help_general], ["Names", $help_app_names], ["Wearing", $help_app_wearing], ["match_crypted()", $help_func_match_crypted], ["@describe", $help_cmd_describe], ["Frob", $help_coldc_types_frobs], ["localtime()", $help_func_localtime], ["Assignments", $help_coldc_assign], ["Default", $help_coldc_default_assign], ["Operator", $help_coldc_prec], ["Mutex", $help_mutex], ["anticipate_assignment()", $help_func_anticipate_assignment], ["Heap", $help_heap], ["ColdC", $help_coldc], ["Formatters", $help_cml_formatters], ["Object", $help_coldc_oop], ["@reap", $help_cmd_reap], ["@set", $help_cmd_set]];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], ["19-Feb-1997"], 'do_dt]>, <$format, ["dd", [], [<$format, ["link", [["node", "$help_sys_word"]], ["Word"], 'do_link]>], 'do_dd]>, <$format, ["dt", [], ["20-Feb-1997"], 'do_dt]>, <$format, ["dd", [], [<$format, ["link", [["node", "$help_cmd_nh"]], ["@nh"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_sys_weather_attributes"]], ["Attributes"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_sys_climate"]], ["Climate"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_sys_weather"]], ["Weather"], 'do_link]>], 'do_dd]>, <$format, ["dt", [], ["22-Feb-1997"], 'do_dt]>, <$format, ["dd", [], [<$format, ["link", [["node", "$help_cmd_ant"]], ["@ant"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_dnt"]], ["@dnt"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_remember"]], ["@remember"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cmd_rename"]], ["@rename"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_appearance"]], ["Appearance"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_building"]], ["Building"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_app_desc"]], ["Description"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_environment"]], ["Environment"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_app_gender"]], ["Gender"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_general"]], ["General"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_app_names"]], ["Names"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_app_wearing"]], ["Wearing"], 'do_link]>], 'do_dd]>, <$format, ["dt", [], ["25-Feb-1997"], 'do_dt]>, <$format, ["dd", [], [<$format, ["link", [["node", "$help_func_match_crypted"]], ["match_crypted()"], 'do_link]>], 'do_dd]>, <$format, ["dt", [], ["28-Feb-1997"], 'do_dt]>, <$format, ["dd", [], [<$format, ["link", [["node", "$help_cmd_describe"]], ["@describe"], 'do_link]>], 'do_dd]>, <$format, ["dt", [], ["2-Mar-1997"], 'do_dt]>, <$format, ["dd", [], [<$format, ["link", [["node", "$help_coldc_types_frobs"]], ["Frob"], 'do_link]>], 'do_dd]>, <$format, ["dt", [], ["5-Mar-1997"], 'do_dt]>, <$format, ["dd", [], [<$format, ["link", [["node", "$help_func_localtime"]], ["localtime()"], 'do_link]>], 'do_dd]>, <$format, ["dt", [], ["7-Mar-1997"], 'do_dt]>, <$format, ["dd", [], [<$format, ["link", [["node", "$help_sys_weather_attributes"]], ["Attributes"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_weather_system"]], ["Weather"], 'do_link]>], 'do_dd]>, <$format, ["dt", [], ["8-Mar-1997"], 'do_dt]>, <$format, ["dd", [], [<$format, ["link", [["node", "$help_coldc_assign"]], ["Assignments"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_coldc_default_assign"]], ["Default"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_coldc_prec"]], ["Operator"], 'do_link]>], 'do_dd]>, <$format, ["dt", [], ["11-Mar-1997"], 'do_dt]>, <$format, ["dd", [], [<$format, ["link", [["node", "$help_mutex"]], ["Mutex"], 'do_link]>], 'do_dd]>, <$format, ["dt", [], ["14-Mar-1997"], 'do_dt]>, <$format, ["dd", [], [<$format, ["link", [["node", "$help_func_anticipate_assignment"]], ["anticipate_assignment()"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_heap"]], ["Heap"], 'do_link]>], 'do_dd]>, <$format, ["dt", [], ["17-Mar-1997"], 'do_dt]>, <$format, ["dd", [], [<$format, ["link", [["node", "$help_coldc"]], ["ColdC"], 'do_link]>, ", ", <$format, ["link", [["node", "$help_cml_formatters"]], ["Formatters"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_coldc_oop"]], ["Object"], 'do_link]>], 'do_dd]>, <$format, ["dt", [], ["18-Mar-1997"], 'do_dt]>, <$format, ["dd", [], [<$format, ["link", [["node", "$help_cmd_reap"]], ["@reap"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_cmd_set"]], ["@set"], 'do_link]>], 'do_dd]>], 'do_dl]>], #[['this, $help_updates]]]>;
var $root inited = 1;
var $help_updates update_list = [[856594800, [$help_environment, $help_building, $help_appearance, $help_general, $help_app_names, $help_app_desc, $help_app_gender, $help_app_wearing, $help_cmd_rename, $help_cmd_ant, $help_cmd_dnt, $help_cmd_remember]], [856854000, [$help_func_match_crypted]], [857113200, [$help_cmd_describe]], [857286000, [$help_coldc_types_frobs]], [857545200, [$help_func_localtime]], [857718000, [$help_sys_weather_attributes, $help_weather_system]], [857804400, [$help_coldc_prec, $help_coldc_default_assign, $help_coldc_assign]], [858063600, [$help_mutex]], [858322800, [$help_func_anticipate_assignment, $help_heap]], [858582000, [$help_coldc, $help_coldc_oop, $help_cml_formatters]], [858668400, [$help_cmd_reap, $help_cmd_set]], [859014000, [$help_sys_message]]];
var $help_updates cleanup_time = 2592000;
var $root trusted = [$help_node];
var $root managed = [$help_updates];
var $root child_index = 1;
var $help_node nolist = 0;

public method .touched() {
    var i, j, t;
    
    (> .perms(caller(), 'trusts) <);
    dirty++;
    t = localtime();
    t = (((t[1]) - (t[2])) - (60 * (t[3]))) - (3600 * (t[4]));
    if ((i = t in (update_list.slice(1))))
        update_list = update_list.replace(i, [(update_list[i])[1], ((update_list[i])[2]).setadd(sender())]);
    else
        update_list += [[t, [sender()]]];
    update_list = map i in (update_list || []) to ([i[1], filter j in (i[2]) where ((| j.has_ancestor($help_node) |))]);
    update_list = filter i in (update_list || []) where ((i[2]) && ((i[1]) > (t - cleanup_time)));
    
    // $#Edited: 14 Feb 97 02:01 $miro
};

public method .body() {
    var i, j, out, body;
    
    body = pass();
    if (dirty || (!body)) {
        if (!update_list) {
            out = ["There weren't any recent updates."];
        } else {
            out = ["{dl:"];
            for i in (update_list) {
                j = map j in (i[2]) to ([j.small_name(), "" + j]).sort();
                out += [((("{dt:" + ($time.format("%v", i[1]))) + "}{dd:") + (map j in (j) to (strfmt("{link node=%l:%l}", j[2], j[1])).to_english())) + "}"];
            }
            out += ["}"];
        }
        .set_body(out);
        body = pass();
        dirty = 0;
    }
    return body;
};


new object $help_index: $has_name, $registry, $help_node;

var $root child_index = 5;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "Index", "Index"];
var $db database = #[];
var $root manager = $help_index;
var $root managed = [$help_index];
var $root owned = [$help_index];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[], #[]]>;
var $help_index dirty = 1;
var $help_node holder = 1;
var $help_node nolist = 0;

root method .init_help_index() {
    .add_trusted($help_node);
    
    // $#Edited: 20 Feb 97 08:40 $miro
};

root method .uninit_help_index() {
    var key;
    
    for key in ((.database()).keys())
        (.match_exact(key)).index_going_away();
};

public method .add_help_node() {
    arg node;
    var part;
    
    if ((caller() != $help_node) && (!(.is_writable_by(caller()))))
        throw(~perm, "Permission denied.");
    for part in ((node.name()).explode("|"))
        .insert(part, node);
};

public method .del_help_node() {
    arg node;
    var part;
    
    if ((!(caller() in [$help_node, definer()])) && ((!(.is_writable_by(sender()))) && (sender() != this())))
        throw(~perm, "Permission denied.");
    for part in ((node.name()).explode("|"))
        .remove(node.name());
};

public method .node_going_away() {
    (> .perms(caller(), $help_node) <);
    .del_help_node(sender());
};

public method .body() {
    var key, out, body, col, db;
    
    body = pass();
    if (dirty || (!body)) {
        (| clear_var('dirty) |);
        db = .database();
        out = ["{table cols=25%,25%,25%,25%:"];
        for key in ((db.keys()).sort()) {
            if (!col)
                out += ["{tr:"];
            out += [((("{td:{link node=" + (db[key])) + ":") + key) + "}}"];
            if (col == 3) {
                out += ["}"];
                col = 0;
            } else {
                col++;
            }
        }
        if (col != 0)
            out += ["}}"];
        else
            out += ["}"];
        .set_body(out);
        body = pass();
    }
    return body;
};

public method .node_name() {
    return (.name()) + " INDEX";
};

public method .html_node_name() {
    arg @args;
    
    return .node_name();
};

public method .insert() {
    arg name, obj;
    
    (> pass(name, obj) <);
    dirty++;
};

public method .remove() {
    arg name;
    
    (> pass(name) <);
    dirty++;
};

public method .node_changed_name() {
    arg old;
    var node, part;
    
    (> .perms(caller(), $help_node) <);
    node = sender();
    for part in (old.explode("|"))
        (| .remove(part) |);
    for part in ((node.name()).explode("|"))
        (| .insert(part, node) |);
};

public method .strip_key() {
    arg key;
    
    anticipate_assignment();
    return key.strip("!#$%^&*()");
};

root method .core_help_index(): nooverride {
    .set_body("");
    dirty++;
};

public method .reset_index() {
    var v, part, dbv;
    
    (> .perms(sender()) <);
    dirty++;
    dbv = ((.database()).values()).compress();
    .set_database(#[]);
    for v in (dbv) {
        if (valid(v)) {
            for part in ((v.name()).explode("|"))
                (| .insert(part, v) |);
        }
    }
};


new object $help_index_driver: $help_index;

var $root manager = $help_index_driver;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837910423;
var $db database = #[["Object Oriented Programming", $help_coldc_oop], ["OOP", $help_coldc_oop], ["Regexps", $help_coldc_regexp], ["Regular Expressions", $help_coldc_regexp], ["Integer", $help_coldc_types_ints], ["Number", $help_coldc_types_ints], ["Object Number", $help_coldc_types_dbref], ["objnum", $help_coldc_types_dbref], ["Object Name", $help_coldc_types_dbref], ["objname", $help_coldc_types_dbref], ["dbref", $help_coldc_types_dbref], ["Error Codes", $help_coldc_types_errors], ["Error-Handling", $help_coldc_err_stmts], ["catch", $help_coldc_err_stmts], ["Overridden Methods", $help_coldc_mcall_over], ["override", $help_coldc_mcall_over], ["if-else", $help_coldc_cond_ifelse], ["else", $help_coldc_cond_ifelse], ["Increment", $help_coldc_incdec], ["Decrement", $help_coldc_incdec], ["Unnamed Interaction Shortcuts", $help_cmd_shortcuts], ["ColdC Reference Manual", $help_coldc], ["Objects", $help_coldc_objs], ["Textdump", $help_coldc_textdump], ["Functions", $help_coldc_func], ["Native Method Reference", $help_coldc_native], ["Referencing Objects", $help_coldc_objs_ref], ["Variables", $help_coldc_objs_vars], ["Special Object Status", $help_coldc_objs_special], ["Tokens", $help_coldc_tokens], ["Data Types", $help_coldc_types], ["Expressions", $help_coldc_expr], ["Statements", $help_coldc_stmts], ["Methods", $help_coldc_methods], ["Tasks and Frames", $help_coldc_tasks], ["Errors", $help_coldc_types_errors], ["Security", $help_coldc_security], ["Networking", $help_coldc_net], ["Files", $help_coldc_files], ["Float", $help_coldc_types_floats], ["String", $help_coldc_types_strings], ["Symbol", $help_coldc_types_symbols], ["List", $help_coldc_types_lists], ["Dictionary", $help_coldc_types_dicts], ["Frob", $help_coldc_types_frobs], ["Buffer", $help_coldc_types_buffers], ["Data", $help_coldc_data], ["Operators", $help_coldc_ops], ["Variable Expression", $help_coldc_vars], ["Function Call Expression", $help_coldc_fcall], ["Method Call Expression", $help_coldc_mcall], ["Error Handling Expression", $help_coldc_err_expr], ["Looping Expressions", $help_coldc_loop_expr], ["Simple", $help_coldc_simple_stmts], ["Looping Statements", $help_coldc_loop_stmts], ["Flags", $help_coldc_methods_flags], ["Access", $help_coldc_methods_access], ["Frames", $help_coldc_tasks_frames], ["Preempting", $help_coldc_tasks_preempt], ["Server Connection", $help_coldc_net_server], ["Client Connection", $help_coldc_net_client], ["Operator Precedence", $help_coldc_prec], ["Index Operators", $help_coldc_index], ["Arithmetic Operators", $help_coldc_arith], ["Assignments", $help_coldc_assign], ["Logical Operators", $help_coldc_logical], ["Conditional", $help_coldc_cond], ["List Splice Operator", $help_coldc_splice], ["map", $help_coldc_map], ["hash", $help_coldc_hash], ["find", $help_coldc_find], ["filter", $help_coldc_filter], ["Comment", $help_coldc_comment_stmt], ["Compound", $help_coldc_compound_stmt], ["Return", $help_coldc_return_stmt], ["if", $help_coldc_cond_if], ["switch", $help_coldc_cond_switch], ["for-list", $help_coldc_forlist], ["for-range", $help_coldc_forrange], ["while", $help_coldc_while], ["break", $help_coldc_break], ["continue", $help_coldc_continue], ["Scatter", $help_coldc_scatter_assign], ["Dual", $help_coldc_dual_assign], ["Default", $help_coldc_default_assign]];
var $has_name name = ['prop, "Driver", "Driver"];
var $registry stripped_characters = "!@#$%^&*()";
var $root trusted = [$help_node];
var $root inited = 1;
var $root managed = [$help_index_driver];
var $root owned = [$help_index_driver];
var $help_node body = <$ctext_frob, [[], #[]]>;
var $help_node links = #[];
var $help_index dirty = 155;
var $help_node nolist = 0;


new object $help_index_core: $help_index;

var $root manager = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837910430;
var $db database = #[["CML", $help_cml], ["Cold Markup Language", $help_cml], ["Heap", $help_heap], ["Cold Help System", $help_coldcore], ["Help", $help_help], ["General Information", $help_general], ["Building", $help_building], ["Programming", $help_prog], ["Reference Library", $help_reference], ["Weather System", $help_weather_system], ["Mutex", $help_mutex], ["Help Options", $help_help_options], ["Navigating Help", $help_help_navigating], ["Conventions", $help_conventions], ["Objects", $help_objects], ["Environment", $help_environment], ["Appearance", $help_appearance], ["Security", $help_security], ["Commands", $help_commands], ["Interaction", $help_interaction], ["Interface", $help_interface], ["Theme", $help_theme], ["Places", $help_build_places], ["Programming Commands", $help_prog_commands], ["Element", $help_list_element], ["Formatting", $help_list_formatting], ["Maps", $help_list_maps], ["Sets", $help_list_sets], ["Other", $help_list_other], ["Climate", $help_sys_climate], ["Weather", $help_sys_weather], ["Attributes", $help_sys_weather_attributes], ["Names", $help_app_names], ["Description", $help_app_desc], ["Gender", $help_app_gender], ["Wearing", $help_app_wearing], ["VR vs Non-VR", $help_commands_vr], ["Matching Conventions", $help_commands_matching], ["Clients", $help_interface_client], ["Format", $help_interface_format], ["Settings", $help_interface_settings], ["Formatters", $help_cml_formatters], ["Generators", $help_cml_generators], ["Realms", $help_places_realms], ["Exits and Entrances", $help_places_exen], ["Environment Conditions", $help_places_env]];
var $has_name name = ['prop, "Core", "Core"];
var $registry stripped_characters = "!@#$%^&*()";
var $root trusted = [$help_node];
var $root inited = 1;
var $root managed = [$help_index_core];
var $root owned = [$help_index_core];
var $help_node body = <$ctext_frob, [[], #[]]>;
var $help_node links = #[];
var $help_node nolist = 0;
var $help_index dirty = 1;


new object $help_index_cmds: $help_index;

var $root manager = $help_index_cmds;
var $help_node links = #[];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847043048;
var $db database = #[["@add-command", $help_cmd_addcmd], ["@ac", $help_cmd_addcmd], ["@del-command", $help_cmd_delcmd], ["@dc", $help_cmd_delcmd], ["wear", $help_cmd_wear], ["shed", $help_cmd_wear], ["@def-msg", $help_cmd_defmsg], ["@undef-msg", $help_cmd_defmsg], ["@nh", $help_cmd_nh], ["@new-help-node", $help_cmd_nh], ["@ant", $help_cmd_ant], ["@add-name-template", $help_cmd_ant], ["@dnt", $help_cmd_dnt], ["@del-name-template", $help_cmd_dnt], ["say", $help_cmd_say], ["emote", $help_cmd_emote], ["to say", $help_cmd_tosay], ["whisper", $help_cmd_whisper], ["@page", $help_cmd_page], ["think", $help_cmd_think], ["spoof", $help_cmd_spoof], ["@paste", $help_cmd_paste], ["@display", $help_cmd_display], ["@program", $help_cmd_program], ["@set", $help_cmd_set], ["@add-setting", $help_cmd_addsetting], ["@adjust", $help_cmd_adjust], ["@mojo", $help_cmd_mojo], ["@new-password", $help_cmd_newpwd], ["@rehash-all", $help_cmd_rehashall], ["@backup", $help_cmd_backup], ["@shutdown", $help_cmd_shutdown], ["@tasks", $help_cmd_tasks], ["@kill", $help_cmd_kill], ["@reap", $help_cmd_reap], ["@core", $help_cmd_core], ["@descendants", $help_cmd_descendants], ["@describe", $help_cmd_describe], ["@new", $help_cmd_new], ["@spawn", $help_cmd_spawn], ["@build", $help_cmd_build], ["@dig", $help_cmd_dig], ["@rename", $help_cmd_rename], ["@remember", $help_cmd_remember], ["@msg", $help_cmd_msg]];
var $has_name name = ['prop, "Commands", "Commands"];
var $registry stripped_characters = "!#^$&*()";
var $root trusted = [$help_node];
var $root inited = 1;
var $help_node body = <$ctext_frob, [[], #[]]>;
var $root managed = [$help_index_cmds];
var $root owned = [$help_index_cmds];
var $root child_index = 5;
var $help_node nolist = 0;
var $help_index dirty = 1;


new object $help_index_subsystem: $help_index;

var $root manager = $help_index_subsystem;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847916269;
var $has_name name = ['prop, "Subsystems", "Subsystems"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[], #[]]>;
var $db database = #[["Updates", $help_updates], ["Events", $help_sys_events], ["Editor", $help_sys_editor], ["Channels", $help_sys_channels], ["Messages", $help_sys_message], ["Word Generator", $help_sys_word]];
var $registry stripped_characters = "!#$%^&*()";
var $root trusted = [$help_node];
var $root inited = 1;
var $root managed = [$help_index_subsystem];
var $root owned = [$help_index_subsystem];
var $help_node nolist = 0;
var $help_index dirty = 1;


new object $help_index_function: $help_index;

var $root manager = $help_index_function;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847916275;
var $has_name name = ['prop, "Function", "Function"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[], #[]]>;
var $db database = #[["Math", $help_func_math], ["sin", $help_func_math], ["exp", $help_func_math], ["log", $help_func_math], ["cos", $help_func_math], ["tan", $help_func_math], ["sqrt", $help_func_math], ["asin", $help_func_math], ["acos", $help_func_math], ["atan", $help_func_math], ["pow", $help_func_math], ["atan2", $help_func_math], ["add_var", $help_func_add_var], ["clear_var", $help_func_clear_var], ["del_var", $help_func_del_var], ["get_var", $help_func_get_var], ["set_var", $help_func_set_var], ["variables", $help_func_variables], ["add_method", $help_func_add_method], ["list_method", $help_func_list_method], ["del_method", $help_func_del_method], ["find_method", $help_func_find_method], ["find_next_method", $help_func_find_next_method], ["method_bytecode", $help_func_method_bytecode], ["method_access", $help_func_method_access], ["method_flags", $help_func_method_flags], ["method_info", $help_func_method_info], ["methods", $help_func_methods], ["rename_method", $help_func_rename_method], ["set_method_access", $help_func_set_method_access], ["set_method_flags", $help_func_set_method_flags], ["ancestors", $help_func_ancestors], ["children", $help_func_children], ["chparents", $help_func_chparents], ["create", $help_func_create], ["data", $help_func_data], ["del_objname", $help_func_del_objname], ["destroy", $help_func_destroy], ["has_ancestor", $help_func_has_ancestor], ["lookup", $help_func_lookup], ["objname", $help_func_objname], ["objnum", $help_func_objnum], ["parents", $help_func_parents], ["set_objname", $help_func_set_objname], ["backup", $help_func_backup], ["set_heartbeat", $help_func_set_heartbeat], ["shutdown", $help_func_shutdown], ["anticipate_assignment", $help_func_anticipate_assignment], ["config", $help_func_config], ["atomic", $help_func_atomic], ["caller", $help_func_caller], ["cancel", $help_func_cancel], ["definer", $help_func_definer], ["method", $help_func_method], ["pause", $help_func_pause], ["refresh", $help_func_refresh], ["resume", $help_func_resume], ["sender", $help_func_sender], ["stack", $help_func_stack], ["suspend", $help_func_suspend], ["task_id", $help_func_task_id], ["tasks", $help_func_tasks], ["this", $help_func_this], ["tick", $help_func_tick], ["ticks_left", $help_func_ticks_left], ["set_user", $help_func_set_user], ["user", $help_func_user], ["pass", $help_func_pass], ["task_info", $help_func_task_info], ["call_trace", $help_func_call_trace], ["debug_callers", $help_func_debug_callers], ["error", $help_func_error], ["rethrow", $help_func_rethrow], ["throw", $help_func_throw], ["traceback", $help_func_traceback], ["bind_port", $help_func_bind_port], ["close_connection", $help_func_close_connection], ["connection", $help_func_connection], ["cwrite", $help_func_cwrite], ["cwritef", $help_func_cwritef], ["open_connection", $help_func_open_connection], ["reassign_connection", $help_func_reassign_connection], ["unbind_port", $help_func_unbind_port], ["dblog", $help_func_dblog], ["execute", $help_func_execute], ["fchmod", $help_func_fchmod], ["fclose", $help_func_fclose], ["feof", $help_func_feof], ["fflush", $help_func_fflush], ["file", $help_func_file], ["files", $help_func_files], ["fmkdir", $help_func_fmkdir], ["fopen", $help_func_fopen], ["fread", $help_func_fread], ["fremove", $help_func_fremove], ["frename", $help_func_frename], ["frmdir", $help_func_frmdir], ["fseek", $help_func_fseek], ["fstat", $help_func_fstat], ["fwrite", $help_func_fwrite], ["bind_function", $help_func_bind_function], ["ctime", $help_func_ctime], ["localtime", $help_func_localtime], ["mtime", $help_func_mtime], ["time", $help_func_time], ["unbind_function", $help_func_unbind_function], ["class", $help_func_class], ["size", $help_func_size], ["toerr", $help_func_toerr], ["tofloat", $help_func_tofloat], ["toint", $help_func_toint], ["toliteral", $help_func_toliteral], ["toobjnum", $help_func_toobjnum], ["tostr", $help_func_tostr], ["tosym", $help_func_tosym], ["type", $help_func_type], ["valid", $help_func_valid], ["fromliteral", $help_func_fromliteral], ["buf_replace", $help_func_buf_replace], ["buf_to_str", $help_func_buf_to_str], ["buf_to_strings", $help_func_buf_to_strings], ["bufgraft", $help_func_bufgraft], ["buflen", $help_func_buflen], ["str_to_buf", $help_func_str_to_buf], ["strings_to_buf", $help_func_strings_to_buf], ["subbuf", $help_func_subbuf], ["bufidx", $help_func_bufidx], ["dict_add", $help_func_dict_add], ["dict_contains", $help_func_dict_contains], ["dict_del", $help_func_dict_del], ["dict_keys", $help_func_dict_keys], ["dict_union", $help_func_dict_union], ["dict_values", $help_func_dict_values], ["delete", $help_func_delete], ["insert", $help_func_insert], ["join", $help_func_join], ["listgraft", $help_func_listgraft], ["listlen", $help_func_listlen], ["replace", $help_func_replace], ["setadd", $help_func_setadd], ["setremove", $help_func_setremove], ["sublist", $help_func_sublist], ["union", $help_func_union], ["listidx", $help_func_listidx], ["crypt", $help_func_crypt], ["explode", $help_func_explode], ["lowercase", $help_func_lowercase], ["match_begin", $help_func_match_begin], ["match_pattern", $help_func_match_pattern], ["match_regexp", $help_func_match_regexp], ["match_template", $help_func_match_template], ["pad", $help_func_pad], ["regexp", $help_func_regexp], ["strcmp", $help_func_strcmp], ["strfmt", $help_func_strfmt], ["strgraft", $help_func_strgraft], ["strlen", $help_func_strlen], ["strsed", $help_func_strsed], ["strsub", $help_func_strsub], ["substr", $help_func_substr], ["uppercase", $help_func_uppercase], ["match_crypted", $help_func_match_crypted], ["split", $help_func_split], ["stridx", $help_func_stridx], ["abs", $help_func_abs], ["max", $help_func_max], ["min", $help_func_min], ["random", $help_func_random]];
var $registry stripped_characters = "!#$%^&*()";
var $root trusted = [$help_node];
var $root inited = 1;
var $root managed = [$help_index_function];
var $root owned = [$help_index_function];
var $help_node nolist = 0;
var $help_index dirty = 325;


new object $help_index_objects: $help_index;

var $root manager = $help_index_objects;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847917435;
var $has_name name = ['prop, "Objects", "Objects"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[], #[]]>;
var $db database = #[["List Library", $help_obj_list], ["Trie", $help_obj_trie]];
var $registry stripped_characters = "!#%^&*()";
var $root trusted = [$help_node];
var $root inited = 1;
var $root managed = [$help_index_objects];
var $root owned = [$help_index_objects];
var $help_node nolist = 0;
var $help_index dirty = 1;


new object $help_core: $help_node;

var $root manager = $help_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848184185;
var $has_name name = ['prop, "Core Help Root", "Core Help Root"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[['this, $help_core]]]>;
var $root inited = 1;
var $root child_index = 6;
var $root managed = [$help_core];
var $help_node holder = 1;
var $help_node nolist = 0;


new object $help_sys_events: $help_core;

var $root manager = $help_sys_events;
var $help_node index = $help_index_subsystem;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 850790348;
var $has_name name = ['prop, "Events", "Events"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Events and Event Hooks allow objects to be notified of changes in their environment. They do this by selectively hooking into known events, such as movement and social interaction events. When the event occurs all objects which have hooked into it will be notified. ", <$format, ["p", [], [], 'do_p]>, "The following methods are defined on $event_handler. ", <$format, ["subj", [["level", "3"]], ["Event Hook Management"], 'do_subj]>, " ", <$format, ["table", [["cols", "35%,65%"]], [<$format, ["tr", [], [<$format, ["td", [], [".clear_event_hook(event)"], 'do_td]>, <$format, ["td", [], ["Unhook all objects from an event."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [".event_hooks()"], 'do_td]>, <$format, ["td", [], ["Return a list of all current event hooks."], 'do_td]>], 'do_tr]>], 'do_table]>, " ", <$format, ["subj", [["level", "3"]], ["Hooking Events"], 'do_subj]>, " ", <$format, ["table", [["cols", "35%,65%"]], [<$format, ["tr", [], [<$format, ["td", [], [".hook_into_event(event)"], 'do_td]>, <$format, ["td", [], ["Hook into the specified event."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [".unhook_from_event(event)"], 'do_td]>, <$format, ["td", [], ["Unhook from the specified event."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [".unhook_from_all()"], 'do_td]>, <$format, ["td", [], ["Unhook from all events on the object."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [".will_hook(event, object)"], 'do_td]>, <$format, ["td", [], ["Called by .hook_into_event() as a permissions check before adding an object to an event hook (pre-processing)."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [".did_hook(event, object)"], 'do_td]>, <$format, ["td", [], ["Called after an object is hooked into an event (post-processing)."], 'do_td]>], 'do_tr]>], 'do_table]>, " ", <$format, ["subj", [["level", "3"]], ["Sending Events"], 'do_subj]>, " ", <$format, ["table", [["cols", "35%,65%"]], [<$format, ["tr", [], [<$format, ["td", [], [".send_event(event, [args])"], 'do_td]>, <$format, ["td", [], ["Notify all hooked objects that the event has occurred."], 'do_td]>], 'do_tr]>], 'do_table]>, " ", <$format, ["subj", [["level", "3"]], ["Receiving Events"], 'do_subj]>, " ", <$format, ["table", [["cols", "45%,55%"]], [<$format, ["tr", [], [<$format, ["td", [], [".event_notify(event, obj, [args])"], 'do_td]>, <$format, ["td", [], ["Notification of the event caused by 'obj'."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [".event_hook_removed(event)"], 'do_td]>, <$format, ["td", [], ["Notification when an event hook definition is removed from an object (object is sender())."], 'do_td]>], 'do_tr]>], 'do_table]>, " ", <$format, ["subj", [["level", "3"]], ["Currently Known Events"], 'do_subj]>, " ", <$format, ["dl", [], [<$format, ["dt", [], ["$location events:"], 'do_dt]>, <$format, ["dd", [], [<$format, ["dl", [], [<$format, ["dt", [], ["'movement"], 'do_dt]>, <$format, ["dd", [], ["Occurs whenever an object moves into or from the location. Use is restricted to objects in the current environment. A single symbol is sent as an additional argument specifying 'arrive or 'leave."], 'do_dd]>, <$format, ["dt", [], ["'user_connect"], 'do_dt]>, <$format, ["dd", [], ["Occurs whenever a user logs in or out of the system and they are located in the room. Use is restricted to objects in the current environment. A single symbol is sent as an additional argument specifying 'login or 'logout."], 'do_dd]>], 'do_dl]>, " "], 'do_dd]>, <$format, ["dt", [], ["$body events:"], 'do_dt]>, <$format, ["dd", [], [<$format, ["dl", [], [<$format, ["dt", [], ["'social"], 'do_dt]>, <$format, ["dd", [], ["Occurs whenever social interaction is directed at the target body."], 'do_dd]>], 'do_dl]>, " "], 'do_dd]>], 'do_dl]>], #[['this, $help_sys_events]]]>;
var $root inited = 1;
var $help_node group = 1;
var $root managed = [$help_sys_events];
var $help_node nolist = 0;


new object $help_obj_list: $help_core;

var $root manager = $help_obj_list;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837714742;
var $has_name name = ['prop, "List Library", "List Library"];
var $help_node links = #[["Elements", $help_list_element], ["Formatting", $help_list_formatting], ["Maps", $help_list_maps], ["Sets", $help_list_sets], ["Others", $help_list_other]];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["link", [["node", "$help_list_element"]], ["Elements"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Element operations"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_list_formatting"]], ["Formatting"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["List formatting"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_list_maps"]], ["Maps"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Mapping and filtering"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_list_sets"]], ["Sets"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Set operations"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_list_other"]], ["Others"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Others"], 'do_dd]>], 'do_dl]>], #[['this, $help_obj_list]]]>;
var $root inited = 1;
var $root managed = [$help_obj_list];
var $root owned = [$help_obj_list];
var $root child_index = 5;
var $help_node index = $help_index_objects;
var $help_node nolist = 0;


new object $help_list_element: $help_obj_list;

var $root manager = $help_list_element;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 850833025;
var $has_name name = ['prop, "Element", "Element"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], [<$format, ["quote", [], ["length(list)"], 'do_quote]>, " ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Length of the list."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["replace(list, n, elt)"], 'do_quote]>, " ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Replace nth element with elt."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["delete(list, n)"], 'do_quote]>, " ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Deletes nth element from the list."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["insert(list,n,elt)"], 'do_quote]>, " ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["insert x at the nth place of the list."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["subrange(list,n,len)"], 'do_quote]>, " ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["sublist starting at l, with len elements."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["last(list)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Last element of the list"], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["msort(list[,keys])"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Sort the list by the keys list. Keys default to the list itself."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["chop(list[,count])"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Removes count elements from the tail of the list. Default is 1 element."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["swap(list, index1, index2)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Swaps the two elements of the list."], 'do_dd]>], 'do_dl]>], #[['this, $help_list_element]]]>;
var $root inited = 1;
var $help_node nolist = 0;
var $root managed = [$help_list_element];


new object $help_list_formatting: $help_obj_list;

var $root manager = $help_list_formatting;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 850833050;
var $has_name name = ['prop, "Formatting", "Formatting"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], [<$format, ["quote", [], ["join(list[, separator])"], 'do_quote]>, " ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Format the list by converting its elements to strings, and putting separator between them."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], [".to_english(list[,empty[,and[,sep]]])"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Convert the elements of the list to strings, put separator between them, except the last two elements, that will be separated with and. Defaults for the arguments are: empty = 'nothing', and = ' and ', sep = ', '."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["columnize(list, cols[, separator[, linelength]])"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Format the line in cols columns, adding the separators. Linelength defaults to 78."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["lcolumnize(list, [len, [sep]])"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Columnizes by detecting the maximal length of the list elements."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["vcolumnize(list, cols[, linelen])"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Columnizes in the stanard manner (consecutive elements are aligned vertically)."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["center_lines(list,width,[args])"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Calls $string.center on each line in the list, with extra args."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["prefix(list, prefix)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Prepends a prefix to each element of the list"], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["affix(l1, l2)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Appends l2 to l1, with adding the first element of l2 to the last element of l1."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["tabulate(list, headers, [colsizes, trim_cols, header_sep, len])"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Output the list as a table, with given headers. Colsizes, if 0, are automatically calculated."], 'do_dd]>], 'do_dl]>], #[['this, $help_list_formatting]]]>;
var $root inited = 1;
var $help_node nolist = 0;
var $root managed = [$help_list_formatting];


new object $help_list_maps: $help_obj_list;

var $root manager = $help_list_maps;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 850833055;
var $has_name name = ['prop, "Maps", "Maps"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], [<$format, ["quote", [], ["make(n[,elt])"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Makes a list of n copies of elt. Elt defaults to 0."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["mmap(list, method, args...)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Calls method on each element (with additional arguments, if specified), returns the results."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["mfilter(list, method, args...)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Similar to mmap, but returns the list of objects for which method returned true value."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["lmap(list, method, args...)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Calls sender().method on each element of the list, returns the results."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["omap(list, object, method, args...)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Calls object.method on each element."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["map_to_english(list, method, args...)"], 'do_quote]>], 'do_dt]>, <$format, ["dt", [], [<$format, ["quote", [], ["map_to_string(list, method, args...)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Shorthand for mmap followed with .to_english/.to_string."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["element_maxlength(list)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Finds the longest element (measuring by string representation)."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["nth_element_maxlength(list,n)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Same as list.slice(n).element_maxlength()."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["reverse(list)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Reverse the order of the elements of the list."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["compress(list)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Removes the repeated elements."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["slice(list, n)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Returns the list of nth elements from a list of lists. If n is a list, it will return a list of lists."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["numbered_text(text)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Returns the text with line numbers prepended."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["max(list)"], 'do_quote]>], 'do_dt]>, <$format, ["dt", [], [<$format, ["quote", [], ["min(list)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Returns minimal/maximal element of the list (0 if empty)."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["fold(list, object, method, args...)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Fold operation from the functional programming. For empty list, it returns 0, for a 1 element list, it returns the first element. Otherwise, it calls the method for the first two elements, then calls it with the result and the third element, etc. It returns the last result."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["valid_objects(list)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Removes invalid objects from the list"], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["grep(list,regexp)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["For each line that matches regexp, returns [linenumber, regexp match regions, the line text]."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["count(list, elem)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Counts the number of occurences of element in the list."], 'do_dd]>], 'do_dl]>], #[['this, $help_list_maps]]]>;
var $root inited = 1;
var $help_node nolist = 0;
var $root managed = [$help_list_maps];


new object $help_list_sets: $help_obj_list;

var $root manager = $help_list_sets;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 850833059;
var $has_name name = ['prop, "Sets", "Sets"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], [<$format, ["quote", [], ["setadd(list, elt)"], 'do_quote]>, " ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Adds an element to the list unless it's already contained in the list."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["setremove(list, elt)"], 'do_quote]>, " ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Removes the first occurence of the element from the list."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["union(list1,list2)"], 'do_quote]>, " ", <$format, ["i", [], ["native"], 'do_i]>], 'do_dt]>, <$format, ["dd", [], ["Union of the two lists. Use ", <$format, ["quote", [], ["big_list.fold($list,'union)"], 'do_quote]>, " to get a union of the family of lists."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["set_difference(list, l1, ...)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Removes the elements from l1, l2 etc from the list."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["intersection(l1, l2)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Returns the elements that occur on both lists. Use fold() for more lists."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["set_contains(l1, l2, ...)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Returns 1 if the first argument contains all the others."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["set_equal(l1, l2)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Returns 1 if the lists are equal as sets (that is, if l1 is contained in l2 and if l2 is contained in l1)."], 'do_dd]>], 'do_dl]>], #[['this, $help_list_sets]]]>;
var $root inited = 1;
var $help_node nolist = 0;
var $root managed = [$help_list_sets];


new object $help_list_other: $help_obj_list;

var $root manager = $help_list_other;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 850833064;
var $has_name name = ['prop, "Other", "Other"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], [<$format, ["quote", [], ["flatten(list)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["RaisE Gll the sublists to the toplevel."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["sum(list)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Returns the sum of the elements of the list."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["non_alphanumeric()"], 'do_quote]>], 'do_dt]>, <$format, ["dt", [], [<$format, ["quote", [], ["numbers()"], 'do_quote]>], 'do_dt]>, <$format, ["dt", [], [<$format, ["quote", [], ["alphabet"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Returns the lists of characters in each class."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["to_buffer([args])"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Turns a list of strings into buffer, inserting a newlist (by default) as a separator."], 'do_dd]>], 'do_dl]>, " ", <$format, ["subj", [["level", "3"]], ["Associative lists"], 'do_subj]>, "Associative lists are lists of key/value pairs. Use them only when dealing with very few elements (fewer than 5, for instance). For larger databases, memory advantage of the associative lists ceases to matter, and they are much slower than dictionaries. ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["quote", [], ["addkey(l, key, val)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Adds a key/value pair to the list, or modifies the value associated with existing key."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["delkey(l, key)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Removes the key/value pair if exists."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["getkey(l, key)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Returns the value associated with the key, or throws ~keynf."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], ["getkey_index(l, key)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Returns the index if the key, or throws."], 'do_dd]>], 'do_dl]>], #[['this, $help_list_other]]]>;
var $root inited = 1;
var $help_node nolist = 0;
var $root managed = [$help_list_other];


new object $help_sys_editor: $help_core;

var $root manager = $help_sys_editor;
var $root child_index = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 840585945;
var $has_name name = ['prop, "Editor", "Editor"];
var $help_node links = #[["Invoking", $help_node_editor_invoking], ["Commands", $help_node_editor_commands], ["Programming", $help_node_editor_programming]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The ColdCore Editor is an integrated system, giving the ability to to edit methods or other data through a builtin line editor or by using your own local editor through MCP. Local editing is controlled through the local-editor setting (it can be set to either ", <$format, ["tt", [], ["none"], 'do_tt]>, " or ", <$format, ["tt", [], ["mcp"], 'do_tt]>, ", such as: ", <$format, ["tt", [], ["@set local-editor=mcp"], 'do_tt]>, "). Each user may have multiple editor sessions. Any coldcore system can create editor session for a user.", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [["columned", 1]], [<$format, ["dt", [], [<$format, ["link", [["node", "$help_node_editor_invoking"]], ["Invoking"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Comamnds used to invoke the editor"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_node_editor_commands"]], ["Commands"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Editor commands"], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_node_editor_programming"]], ["Programming"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Editor: The Programmer's view"], 'do_dd]>], 'do_dl]>], #[['this, $help_sys_editor]]]>;
var $root inited = 1;
var $root managed = [$help_sys_editor];
var $root owned = [$help_sys_editor];
var $help_node index = $help_index_subsystem;
var $help_node nolist = 0;


new object $help_node_editor_invoking: $help_sys_editor;

var $root manager = $help_node_editor_invoking;
var $root managed = [$help_node_editor_invoking];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 840586820;
var $has_name name = ['prop, "Invoking", "Invoking"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["@edit"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["List all editor sessions."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["@edit %<x>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Resume background session, where <x> is the session to resume (as listed in the session list)"], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["@edit object.method"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Create a new session with the specified method."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["@edit object [+t?ype=method]"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Edit data on the object. Type specifies what data (typical values: prose, text, messages or help). Without +t, a reasonable default is chosen."], 'do_dd]>], 'do_dl]>], #[['this, $help_node_editor_invoking]]]>;
var $root inited = 1;
var $root owned = [$help_node_editor_invoking];
var $help_node nolist = 0;


new object $help_node_editor_commands: $help_sys_editor;

var $root manager = $help_node_editor_commands;
var $root managed = [$help_node_editor_commands];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 840586826;
var $has_name name = ['prop, "Commands", "Commands"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["a?fter [<text>] OR _<text>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Add <text> after current line. You may also use an underscore (_) as a shortcut character. If text does not exist you will be prompted for the input."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["ap?pend <text> OR ,<text>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Add <text> after current line. You may also use a comma (,) as a shortcut character."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["copy [<range>] [to] <line>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Copy <range> of text or current line to <line>."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["d?elete [<range>]"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Delete <range> or current line."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["done|quit"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Close editor without saving changes."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["fill <range> <line width>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Fill <range> of lines to fit within <line width> appropriately (either by expanding or joining)."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["help [<command>]"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Basic editor help."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["i?nsert [<text>] OR '<text>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Add <text> before current line. You may also use a single-quote (') as a shortcut character. If text does not exist you will be prompted for the input."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["list [<range>] [-n?umbers]"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["List <range> or all of edit buffer. The option -n?umbers may be used to not specify line numbers."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["line <line>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Change the current line to <line>. You can also use a period (.) as a shortcut character."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["move [<range>] [to] <line>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Move <range> or current line to <line>."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["save|comp?ile [as] [<ref>]"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Save document, if arguments are given will save alternate copy."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["s?ub|sed <old> <new> [<range>] [<options>]"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Search for <old> and replace it with <new> in <range> (defaulting to the current line). The character following the command is used as a seperator (a space in the example). This allows for the sed-like syntax: s/old/new/. The command 'sed' will use strsed() with regular expressions, the command 'sub' or 's' will use strsub() with literal matching. Options are any one of:", <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, "g Globally match and replace (do it multiple times)", <$format, ["p", [], [], 'do_p]>, "s Single match and replace (do it only on the first occurance)", <$format, ["p", [], [], 'do_p]>, "c Case matters when matching.", <$format, ["p", [], [], 'do_p]>, "i Case doesn't matter when matching.", <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, "Option defaults for sed are: si", <$format, ["p", [], [], 'do_p]>, "Option defaults for sub are: gi"], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["send|mail <mail-recipient>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Used to send current contents of editor to a mail recipient."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["store"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Store editor--do not save changes. Editor can be resumed with @reedit."], 'do_dd]>], 'do_dl]>], #[['this, $help_node_editor_commands]]]>;
var $root inited = 1;
var $root owned = [$help_node_editor_commands];
var $help_node nolist = 0;

public method .generate_body() {
    var helps, h, cmds, c, out, syn;
    
    (sender() == $editor_parser) || (> .perms(sender()) <);
    helps = $editor_parser.command_help();
    cmds = $editor_parser.commands();
    out = "{dl:";
    for c in ((cmds.keys()).sort()) {
        refresh();
        h = helps[cmds[c]];
        syn = strsed(h[1], "Syntax: *", "");
        if ((h[2]) == "")
            h = sublist(h, 3).join("{p}");
        else
            h = sublist(h, 2).join("{p}");
        syn = strsub(syn, "[", "\[");
        syn = strsub(syn, "]", "\]");
        out += ((("{dt:{subj level=3:{tt:" + syn) + "}}}{dd:") + h) + "}";
    }
    .set_body(out + "}");
    
    // $#Edited: 14 Feb 97 23:46 $brandon
};


new object $help_node_editor_programming: $help_sys_editor;

var $root manager = $help_node_editor_programming;
var $root managed = [$help_node_editor_programming];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 840586832;
var $has_name name = ['prop, "Programming", "Programming"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["subj", [["level", "3"]], ["Glosary"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], ["Server-side edit"], 'do_dt]>, <$format, ["dd", [], ["The editor mode in which @edit command throws the user into the line editor built into the server."], 'do_dd]>, <$format, ["dt", [], ["Local edit"], 'do_dt]>, <$format, ["dd", [], ["Editor mode in which @edit downloads the text to the user, returns the user to normal work, and processes the text upload as it arrives."], 'do_dd]>, <$format, ["dt", [], ["Callback"], 'do_dt]>, <$format, ["dd", [], [<$format, ["tt", [], ["save"], 'do_tt]>, " command in the server edit, or upload in the local edit, will call a function that knows how to deal with the text. The function (and its extra arguments) are passed to the editor when it's started. Callback function expects two arguments, ", <$format, ["tt", [], ["text"], 'do_tt]>, " and ", <$format, ["tt", [], ["client_data"], 'do_tt]>, ", the first is the text upload, and the other is a list passed to the editor when it was run."], 'do_dd]>], 'do_dl]>, <$format, ["subj", [["level", "3"]], ["Editor objects"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], ["$editor_reference"], 'do_dt]>, <$format, ["dd", [], ["A parent to ", <$format, ["tt", [], ["$user"], 'do_tt]>, ", containing the invocation commands, a list of background editors and the foreground editor."], 'do_dd]>, <$format, ["dt", [], ["$editor_parser"], 'do_dt]>, <$format, ["dd", [], ["Editor command parser. Added to the list of $user's parsers to switch the command context for server editting."], 'do_dd]>, <$format, ["dt", [], ["$editor_session"], 'do_dt]>, <$format, ["dd", [], ["This object is spawned for each individual session. It contains all the data for the session: callback method and arguments, modification flag, cursor position and (for server edit) the text itself. It also runs the editor commands (for server edit). For the local edit, it main purpose is keeping track of the callbacks."], 'do_dd]>, <$format, ["dt", [], ["$editable"], 'do_dt]>, <$format, ["dd", [], ["This is a generic parent that keeps track of the datatype that an object may hold (with @edit object +type=<something> command)"], 'do_dd]>], 'do_dl]>, <$format, ["subj", [["level", "3"]], ["Calling the editor"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "The editor is called by running ", <$format, ["tt", [], ["user.invoke_editor(callback_object, callback_method, initial_text, client_data)"], 'do_tt]>, ", where ", <$format, ["tt", [], ["callback_object"], 'do_tt]>, " and ", <$format, ["tt", [], ["callback_method"], 'do_tt]>, " specify the callback, ", <$format, ["tt", [], ["initial_text"], 'do_tt]>, " is the text to be edited, and ", <$format, ["tt", [], ["client_data"], 'do_tt]>, " will be passed to the callback as additional arguments.", <$format, ["p", [], [], 'do_p]>, <$format, ["subj", [["level", "3"]], ["Extending @edit types"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "To add a new editable type to an object, first make sure that the object has $editable among its ancestors. Then do ", <$format, ["tt", [], ["object.set_edit_type([ list of types ])"], 'do_tt]>, ". For each type, define object.edit_<type> method, and the callback for the method. You're done!"], #[['this, $help_node_editor_programming]]]>;
var $root inited = 1;
var $root owned = [$help_node_editor_programming];
var $help_node nolist = 0;


new object $help_sys_channels: $help_core;

var $root manager = $help_sys_channels;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 840768823;
var $has_name name = ['prop, "Channels", "Channels"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["Channels are a global way to communicate with other users. Commands available for using channels:", <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["@addcom <alias>=<channel>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Adds a channel alias to a channel <channel>. Provides a shortcut way of referring to a channel. For example, typing '@addcom pub=Public' will create a shortcut called 'pub' which refers to the [Public] channel."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["@delcom <alias>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["@delcom <alias> deletes your alias for the given channel."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["@channels"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Show all of the channel aliases and their channels you have defined (this list is only applicable to you)."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["<channel alias> <msg>"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Used to speak on a channel. If the channel [Public] has the alias 'pub', you can send a message to it with the command 'pub Hi!'. Similarly, emotes work as well with 'pub :waves'"], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["<channel alias> on"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Used to turn on a channel. Typing '<alias> on' will turn on the channel specified by <alias>, such as 'pub'. When a channel is turned on, you listen and receive messages from anyone chantting on that channel."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["<channel alias> off"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Used to leave a channel."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [<$format, ["tt", [], ["<channel alias> who"], 'do_tt]>], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Used to determine who is listening to a given channel. Typing '<alias> who' will provide a listing of users currently listening. For example, 'pub who' will list the users chatting or idling on the public channel, from the example above."], 'do_dd]>], 'do_dl]>], #[['this, $help_sys_channels]]]>;
var $root inited = 1;
var $root managed = [$help_sys_channels];
var $root owned = [$help_sys_channels];
var $help_node index = $help_index_subsystem;
var $help_node nolist = 0;


new object $help_obj_trie: $help_core;

var $root manager = $help_obj_trie;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 838774726;
var $has_name name = ['prop, "Trie", "Trie"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Trie is a datastructure that behaves like dictionary with string keys, except that it allows fast match_begin with all the keys. Also, key may be associated with a value list instead of a single value. Its memory overhead is about twice that of a dictionary, and all the operations are slower, except match_begin (which, unlike the dictionary's, does not have to loop through all the keys). Empty trie is represented as ", <$format, ["tt", [], ["<$trie,[0,\"\"]>"], 'do_tt]>, ".", <$format, ["p", [], [], 'do_p]>, <$format, ["subj", [["level", "3"]], ["Methods"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["quote", [], [".add(key, value[,value...])"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Associate a list of values with a key."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], [".del(key)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Remove the key from trie."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], [".match_exact(key)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Find an exact match to the key."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], [".match_begin(key)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Find an approximate match."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], [".keys()"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Get a list of the keys. This is very slow operation."], 'do_dd]>, <$format, ["dt", [], [<$format, ["quote", [], [".to_dict(), $dictionary.to_trie(dict)"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Conversions. The first one converts a trie with a single-element values into dictionary, reverse converts a dictionary with string keys to trie."], 'do_dd]>], 'do_dl]>], #[['this, $help_obj_trie]]]>;
var $root inited = 1;
var $root managed = [$help_obj_trie];
var $root owned = [$help_obj_trie];
var $help_node index = $help_index_objects;
var $help_node nolist = 0;


new object $help_cmds: $help_core;

var $root manager = $help_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847128224;
var $root owned = [$help_cmds];
var $has_name name = ['prop, "Commands", "Commands"];
var $root managed = [$help_cmds];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node is simply a place holder, and should not be linked in through an index or anything. If you see it, something has gone wrong."], #[['this, $help_cmds]]]>;
var $root inited = 1;
var $help_node group = 1;
var $help_node nolist = 1;
var $root child_index = 25;

public method .nolist() {
    arg @args;
    
    // all 'command' nodes are nolist
    return 1;
    
    // $#Edited: 10 Nov 96 13:25 $brandon
};

public method .top_of_help_heirarchy() {
    return definer() == this();
    
    // $#Edited: 11 Nov 96 22:41 $brandon
};


new object $help_cmd_say: $help_cmds;

var $root manager = $help_cmd_say;
var $root owned = [$help_cmd_say];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847043470;
var $has_name name = ['prop, "say", "say"];
var $root managed = [$help_cmd_say];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The interaction command ", <$format, ["tt", [], ["say"], 'do_tt]>, " is used to speak and talk to others. For convenience, the double-quote character may also be used as a shortcut. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> say Hi", <$format, ["br", [], [], 'do_br]>, "Brandon says, \"Hi\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["> \"whats up?", <$format, ["br", [], [], 'do_br]>, "Brandon says, \"whats up?\""], 'do_dfn]>], #[['this, $help_cmd_say]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;


new object $help_cmd_emote: $help_cmds;

var $root manager = $help_cmd_emote;
var $root owned = [$help_cmd_emote];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847043476;
var $has_name name = ['prop, "emote", "emote"];
var $root managed = [$help_cmd_emote];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The interaction command ", <$format, ["tt", [], ["emote"], 'do_tt]>, " is used for free-form actions. For convenience, the colon character may also be used as a shortcut. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> emote waves to everybody", <$format, ["br", [], [], 'do_br]>, "Brandon waves to everybody"], 'do_dfn]>, " ", <$format, ["dfn", [], ["> :jumps up and down", <$format, ["br", [], [], 'do_br]>, "Brandon jumps up and down"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "You can get rid of the space after your name, by doubling up the colon:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> ::'s head hurts", <$format, ["br", [], [], 'do_br]>, "Brandon's head hurts"], 'do_dfn]>], #[['this, $help_cmd_emote]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;


new object $help_cmd_tosay: $help_cmds;

var $root manager = $help_cmd_tosay;
var $root owned = [$help_cmd_tosay];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847043714;
var $has_name name = ['prop, "to say", "to say"];
var $root managed = [$help_cmd_tosay];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["to <target> say <anything>"], 'do_tt]>, <$format, ["np", [], [], 'do_np]>, "The interaction command ", <$format, ["tt", [], ["to"], 'do_tt]>, " is used to speak and talk to a specific person (<target>). For convenience, the single-quote character may be used as a shortcut. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> to Miro say Hi", <$format, ["br", [], [], 'do_br]>, "Brandon (to Miro) says, \"Hi\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["> 'Miro whats up?", <$format, ["br", [], [], 'do_br]>, "Brandon (to Miro) says, \"whats up?\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "As with any directed interaction command, you can double up the shortcut character to send to the last person you directed to. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> 'Miro say Hi", <$format, ["br", [], [], 'do_br]>, "Brandon (to Miro) says, \"Hi\"", <$format, ["br", [], [], 'do_br]>, "> ''how is the weather?", <$format, ["br", [], [], 'do_br]>, "Brandon (to Miro) asks, \"How is the weather?\""], 'do_dfn]>], #[['this, $help_cmd_tosay]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;


new object $help_cmd_whisper: $help_cmds;

var $root manager = $help_cmd_whisper;
var $root owned = [$help_cmd_whisper];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847043723;
var $has_name name = ['prop, "whisper", "whisper"];
var $root managed = [$help_cmd_whisper];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["whisper <anything> to <target>"], 'do_tt]>, <$format, ["np", [], [], 'do_np]>, "The interaction command ", <$format, ["tt", [], ["whisper"], 'do_tt]>, " is used to speak and talk privately to a specific person (<target>). Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> whisper the Red Man is in Tibet to Brian", <$format, ["br", [], [], 'do_br]>, "You whisper, \"the Red Man is in Tibet\" to Brian"], 'do_dfn]>], #[['this, $help_cmd_whisper]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;


new object $help_cmd_page: $help_cmds;

var $root manager = $help_cmd_page;
var $root owned = [$help_cmd_page];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847043729;
var $has_name name = ['prop, "@page", "@page"];
var $root managed = [$help_cmd_page];
var $help_node links = #[["say", $help_cmd_say], ["emote", $help_cmd_emote]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["@page <who>[,<who>..] with <anything>"], 'do_tt]>, <$format, ["np", [], [], 'do_np]>, "The non-VR interaction command ", <$format, ["tt", [], ["@page"], 'do_tt]>, " is used to interact with one or more people not in the room. For convenience, the dash character may also be used as a shortcut. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> @page Amy with dinner tonight?", <$format, ["br", [], [], 'do_br]>, "[to Amy] Brandon says, \"dinner tonight?\""], 'do_dfn]>, " ", <$format, ["dfn", [], ["> -Miro Hi", <$format, ["br", [], [], 'do_br]>, "[to Miro] Brandon says, \"Hi\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The people receiving the message see your location inside the square brackets, instead of who it is being directed to, such as [from The Pit] instead of [to Amy]. The default style of interaction is speach (similar to ", <$format, ["link", [["node", "$help_cmd_say"]], ["say"], 'do_link]>, "), you can also ", <$format, ["link", [["node", "$help_cmd_emote"]], ["emote"], 'do_link]>, " in page, by beginning your message with a colon:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> @page Brian with :waves", <$format, ["br", [], [], 'do_br]>, "[to Brian] Brandon waves"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "As with any directed interaction command, you can double up the shortcut character to send to the last person you directed to. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> -Brian :waves", <$format, ["br", [], [], 'do_br]>, "[to Brian] Brandon waves", <$format, ["br", [], [], 'do_br]>, "> --how goes it?", <$format, ["br", [], [], 'do_br]>, "[to Brian] Brandon says, \"how goes it?\""], 'do_dfn]>], #[['this, $help_cmd_page]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;


new object $help_cmd_think: $help_cmds;

var $root manager = $help_cmd_think;
var $root owned = [$help_cmd_think];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847043935;
var $has_name name = ['prop, "think", "think"];
var $root managed = [$help_cmd_think];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The interaction command ", <$format, ["tt", [], ["think"], 'do_tt]>, " is used to think something out loud. For convenience, the percent character may also be used as a shortcut. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> think oops", <$format, ["br", [], [], 'do_br]>, "Brandon . o O ( oops )"], 'do_dfn]>, " ", <$format, ["dfn", [], ["> %I think everybody can see my thoughts", <$format, ["br", [], [], 'do_br]>, "Brandon . o O ( I think everybody can see my thoughts )"], 'do_dfn]>], #[['this, $help_cmd_think]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;


new object $help_cmd_spoof: $help_cmds;

var $root manager = $help_cmd_spoof;
var $root owned = [$help_cmd_spoof];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847043939;
var $has_name name = ['prop, "spoof", "spoof"];
var $root managed = [$help_cmd_spoof];
var $help_node links = #[["emote", $help_cmd_emote]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The interaction command ", <$format, ["tt", [], ["spoof"], 'do_tt]>, " is used similar to ", <$format, ["link", [["node", "$help_cmd_emote"]], ["emote"], 'do_link]>, ", except your name does not start the line. This is usually used to format your actions in a different way, but can be used to 'spoof' actions from other players--which can be considered rude (be careful when using it so as to not offend anybody). If your name does not appear in the line, it will be appended for attribution. For convenience, the exclaimation point may also be used as a shortcut. Examples:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> spoof Miro slips and falls.", <$format, ["br", [], [], 'do_br]>, "Miro slips and falls. -- Brandon"], 'do_dfn]>, " ", <$format, ["dfn", [], ["> !The big beast pounces on Brandon, pummelling him silly", <$format, ["br", [], [], 'do_br]>, "The big beast pounces on Brandon, pummelling him silly"], 'do_dfn]>], #[['this, $help_cmd_spoof]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;


new object $help_cmd_paste: $help_cmds;

var $root manager = $help_cmd_paste;
var $root owned = [$help_cmd_paste];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847044098;
var $has_name name = ['prop, "@paste", "@paste"];
var $root managed = [$help_cmd_paste];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["@paste [to <target>]"], 'do_tt]>, <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, "The non-VR interaction command ", <$format, ["tt", [], ["@paste"], 'do_tt]>, " is used to display blocks of text either to the room or to a specific person (<target>). If no target is specified, it is displayed to the room. You will be prompted for the text. When you are finished typing in the text, type a period at the beginning of a line, followed bo no other characters. Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["quote", [], ["> @paste\nReceiving input. Enter \".\" to finish or \"@abort\" to abort.\n> USER     PID   %CPU %MEM   VSZ  RSS  COMMAND\n> brandon  10267  0.0 19.4  5800 5928  ./genesis\n> .\n-------------- Brandon (@paste's) ---------------\nUSER     PID   %CPU %MEM   VSZ  RSS  COMMAND\nbrandon  10267  0.0 19.4  5800 5928  ./genesis\n------------------- + Finis + -------------------\n2 lines of text pasted"], 'do_quote]>], 'do_dfn]>], #[['this, $help_cmd_paste]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;


new object $help_cmd_shortcuts: $help_cmds;

var $root manager = $help_cmd_shortcuts;
var $root owned = [$help_cmd_shortcuts];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847044102;
var $has_name name = ['prop, "Unnamed Interaction Shortcuts", "Unnamed Interaction Shortcuts"];
var $root managed = [$help_cmd_shortcuts];
var $help_node links = #[["say", $help_cmd_say]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "In addition to the standard interaction commands there are also a few which do not have names: ", <$format, ["dfn", [["ind", "4"], ["nobound", 1]], [<$format, ["table", [["cols", "10%,90%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], [<$format, ["tt", [], ["|"], 'do_tt]>], 'do_b]>], 'do_td]>, <$format, ["td", [], ["This is used to display one line of information, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> |test", <$format, ["br", [], [], 'do_br]>, "Brandon | test"], 'do_dfn]>], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["b", [], [<$format, ["tt", [], [",,"], 'do_tt]>], 'do_b]>], 'do_td]>, <$format, ["td", [], ["This is like ", <$format, ["link", [["node", "$help_cmd_say"]], ["say"], 'do_link]>, ", but it lets you put your own text before what you say, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> ,nods, That is correct", <$format, ["br", [], [], 'do_br]>, "Brandon nods, \"That is correct\""], 'do_dfn]>], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['this, $help_cmd_shortcuts]]]>;
var $root inited = 1;


new object $help_cmd_display: $help_cmds;

var $root manager = $help_cmd_display;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_name name = ['prop, "@display", "@display"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["Need to write."], #[['this, $help_cmd_display]]]>;
var $root managed = [$help_cmd_display];
var $root owned = [$help_cmd_display];
var $help_node index = $help_index_cmds;


new object $help_cmd_program: $help_cmds;

var $root manager = $help_cmd_program;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 838059477;
var $has_name name = ['prop, "@program", "@program"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["subj", [["level", "3"]], [<$format, ["quote", [], ["@program <objref: +w?arnings +e?dited=1 +a?ccess=1 +f?lags=1n   [with <any>]>"], 'do_quote]>], 'do_subj]>, "Set the code for a method.", <$format, ["br", [], [], 'do_br]>, <$format, ["dl", [], [<$format, ["dt", [], ["+warnings"], 'do_dt]>, <$format, ["dd", [], ["Do not warn about recursion."], 'do_dd]>, <$format, ["dt", [], ["+edited[=message]"], 'do_dt]>, <$format, ["dd", [], ["set or override the edited comment. (admin only)"], 'do_dd]>, <$format, ["dt", [], ["+access=permission"], 'do_dt]>, <$format, ["dd", [], ["Set the method access to one of public, protected, private, root or driver"], 'do_dd]>, <$format, ["dt", [], ["+flags=flags"], 'do_dt]>, <$format, ["dd", [], ["Set the flags to some of nooverride, locked, fork or native."], 'do_dd]>], 'do_dl]>, "Optionally, 'with' preposition causes it to read the code from the command line instead of prompting the user for it."], #[['this, $help_cmd_program]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_program];
var $root owned = [$help_cmd_program];
var $help_node index = $help_index_cmds;


new object $help_cmd_set: $help_cmds;

var $root manager = $help_cmd_set;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847776342;
var $has_name name = ['prop, "@set", "@set"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["@set [options] [<target>:][<name>[=<value>]]"], 'do_tt]>, <$format, ["p", [], [], 'do_p]>, <$format, ["p", [], [], 'do_p]>, "This command is used to display and change configurable settings on objects. If <target> is left unspecified it will default to you. To view all settings on an object do not specify a setting name or value, such as either of the following two:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set", <$format, ["br", [], [], 'do_br]>, "@set here:"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "The first example will show all settings on you. The second example will show all settings on ", <$format, ["i", [], ["here"], 'do_i]>, ". To change a setting include the setting name after the target followed by an equals sign and a value, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set here:realm=Taobh Thiar"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If the option ", <$format, ["tt", [], ["+definer"], 'do_tt]>, " is given, it will list all of the definers for each setting instance. If a value for definer is given it will only list instances of the settings defined by the given objref, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@set +definer=$place here:"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Which will only show the settings defined on ", <$format, ["tt", [], ["here"], 'do_tt]>, " and defined by ", <$format, ["tt", [], ["place"], 'do_tt]>, ". ", <$format, ["np", [], [], 'do_np]>, "If the option ", <$format, ["tt", [], ["+clear"], 'do_tt]>, " is given, it will ignore any value specified for the setting and will instead clear the value, reverting it to its original default."], #[['this, $help_cmd_set]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;
var $root managed = [$help_cmd_set];
var $root owned = [$help_cmd_set];


new object $help_cmd_addsetting: $help_cmds;

var $root manager = $help_cmd_addsetting;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847777538;
var $has_name name = ['prop, "@add-setting", "@add-setting"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dl", [], [<$format, ["dt", [], [<$format, ["quote", [], ["@add-setting <name> [<options>]"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["Adds a setting <name>. Valid Options:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["lh", [], ["type"], 'do_lh]>, <$format, ["li", [], ["A string that describes what type this setting should make. Default: 'string'."], 'do_li]>, <$format, ["lh", [], ["check"], 'do_lh]>, <$format, ["li", [], ["Method that verifies a given value is valid. Default: 'is_anything'."], 'do_li]>, <$format, ["lh", [], ["set"], 'do_lh]>, <$format, ["li", [], ["Method that stores the value. Default: 'set_direct_setting'."], 'do_li]>, <$format, ["lh", [], ["get"], 'do_lh]>, <$format, ["li", [], ["Method to retrieve the value. Default: 'get_direct_setting'."], 'do_li]>, <$format, ["lh", [], ["del"], 'do_lh]>, <$format, ["li", [], ["Method called if the setting is deleted. Default: 'del_direct_setting'."], 'do_li]>], 'do_ul]>], 'do_dd]>], 'do_dl]>, "When giving method names ", <$format, ["i", [], ["do not"], 'do_i]>, " use a ' or .", <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["quote", [], ["@set [<mask>] [on <object>]"], 'do_quote]>], 'do_dt]>, <$format, ["dd", [], ["If object is not given, assume this. Mask may be:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["lh", [], ["<name>"], 'do_lh]>, <$format, ["li", [], ["Show all settings matching name"], 'do_li]>, <$format, ["lh", [], ["[+|-]<name>"], 'do_lh]>, <$format, ["li", [], ["Set or unset a boolean"], 'do_li]>, <$format, ["lh", [], ["<name>=<value>"], 'do_lh]>, <$format, ["li", [], ["Set any thing"], 'do_li]>, <$format, ["lh", [], ["<name>+=<value>"], 'do_lh]>, <$format, ["li", [], ["Delete a value from a list"], 'do_li]>, <$format, ["lh", [], ["<name>-=<value>"], 'do_lh]>, <$format, ["li", [], ["Add a value to a list"], 'do_li]>], 'do_ul]>], 'do_dd]>], 'do_dl]>], #[['this, $help_cmd_addsetting]]]>;
var $root inited = 1;
var $help_node index = $help_index_cmds;
var $root managed = [$help_cmd_addsetting];
var $root owned = [$help_cmd_addsetting];


new object $help_cmd_adjust: $help_cmds;

var $root manager = $help_cmd_adjust;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119776;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@adjust", "@adjust"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, " ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@adjust|@promote <user> to <any>"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Used to change a user's class from/to any of the following: ", <$format, ["ul", [], [<$format, ["li", [], ["user"], 'do_li]>, <$format, ["li", [], ["builder"], 'do_li]>, <$format, ["li", [], ["programmer"], 'do_li]>, <$format, ["li", [], ["admin"], 'do_li]>], 'do_ul]>, " ", <$format, ["p", [], [], 'do_p]>, "Example: ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["@promote Bob to a programmer"], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "If the user was originally a guest it will create a password and email it to the user. It uses the email address they specified upon guest connect."], #[['this, $help_cmd_adjust]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_adjust];


new object $help_cmd_mojo: $help_cmds;

var $root manager = $help_cmd_mojo;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119784;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@mojo", "@mojo"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, " ", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@adjust|@promote <user> to <any>"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Used by an administrator to enable full system priveliges."], #[['this, $help_cmd_mojo]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_mojo];


new object $help_cmd_newpwd: $help_cmds;

var $root manager = $help_cmd_newpwd;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119794;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@new-password", "@new-password"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, " ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@new-password|@newpw?d <user>"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Used to generate a new random password for the specified user. The password is printed to the admin running the command, and is emailed to the user. Example: ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["@newpw Billy Bob"], 'do_dfn]>], #[['this, $help_cmd_newpwd]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_newpwd];


new object $help_cmd_rehashall: $help_cmds;

var $root manager = $help_cmd_rehashall;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119800;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@rehash-all", "@rehash-all"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, " ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["Syntax: @rehash-all [-purge]"], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Commands are cached for fast lookup. Because of this if a command is added to an object other than your object (such as $user), the global cache needs to be updated. This command will clear all caches and update them as needed. ", <$format, ["p", [], [], 'do_p]>, "If the +purge option is specified it will purge ALL caches in the database before rehashing. This does not happen by default."], #[['this, $help_cmd_rehashall]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_rehashall];


new object $help_cmd_backup: $help_cmds;

var $root manager = $help_cmd_backup;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119816;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@backup", "@backup"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, " ", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: @backup"], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Start an asyncrynous backup of the binary database."], #[['this, $help_cmd_backup]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_backup];


new object $help_cmd_shutdown: $help_cmds;

var $root manager = $help_cmd_shutdown;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119822;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@shutdown", "@shutdown"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, " ", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@shutdown [-t?ime=xx] [reason]"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Shutdown the server, the time defaults to five minutes, if left unspecified. The time specified is in minutes, so -time=10 would be ten minutes, not ten seconds. Example: ", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@shutdown -t=0 Upgrading Driver, Should be back online soon"], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Would shutdown immediately (zero minutes)."], #[['this, $help_cmd_shutdown]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_shutdown];


new object $help_cmd_tasks: $help_cmds;

var $root manager = $help_cmd_tasks;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119825;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@tasks", "@tasks"];
var $help_node links = #[["@kill", $help_cmd_kill]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, " ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@task?s [task [task [...]]]"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Briefly list all Database and Driver tasks, or list full details on the specified tasks (as with ", <$format, ["link", [["node", "$help_cmd_kill"]], ["@kill"], 'do_link]>, ") system tasks are directly specified by prefixing them with an asterisk). Examples: ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["@tasks"], 'do_dfn]>, " ", <$format, ["dfn", [], ["@tasks *10204"], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Note: does not show currently executing task."], #[['this, $help_cmd_tasks]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_tasks];


new object $help_cmd_kill: $help_cmds;

var $root manager = $help_cmd_kill;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119831;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@kill", "@kill"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, " ", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@del-t?ask|@kill [task [task [...]]]"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Kill the specified task. System tasks are directly specified by prefixing them with an asterisk. In general you should kill the related database task and let it kill the system task (if applicable). ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dfn", [], ["@kill *10204", <$format, ["br", [], [], 'do_br]>, "@kill 12 *1241"], 'do_dfn]>], #[['this, $help_cmd_kill]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_kill];


new object $help_cmd_addcmd: $help_cmds;

var $root manager = $help_cmd_addcmd;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848119837;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@add-command|@ac", "@add-command|@ac"];
var $help_node links = #[[" Enhanced Command Template", $help_commands_enhanced], ["Matching Conventions", $help_commands_matching]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, " ", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@add-c?ommand|@ac \"<Command Template>\" [to|for] <objref>"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Used to add a command. The method called if the command matches must be specified. The command template must be an ", <$format, ["link", [["node", "$help_commands_enhanced"]], [" Enhanced Command Template"], 'do_link]>, ". Arguments send to the method are always ordered the same, the first argument is always the command string, followed by subsequent arguments relative to how the command template would match using template matching (see ", <$format, ["link", [["node", "$help_commands_matching"]], ["Matching Conventions"], 'do_link]>, "). ", <$format, ["p", [], [], 'do_p]>, "For instance, the following enhanded command template: ", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["\"@get <any> from <this>\""], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Would evaluate to the following standard template ", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["\"@get * from *\""], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "From this point, you can simply evaluate the template matching to see how its results would be ordered: ", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [";match_template(\"@get something from nothing\", \"@get * from *\")", <$format, ["br", [], [], 'do_br]>, "=> [\"@get\", \"something\", \"from\", \"nothing\"]"], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Based off these results the arg definition for your method could be: ", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["arg cmdstr, cmd, arg1, prep, arg2;"], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "When a command is added it will not immediately begin working. Command caches must be updated first. There are three different situations that will arise when adding a command: ", <$format, ["p", [], [], 'do_p]>, " ", <$format, ["dl", [], [<$format, ["dt", [], ["Adding a local command to yourself"], 'do_dt]>, <$format, ["dd", [], [<$format, ["p", [], [], 'do_p]>, "This situation is the simplest to update. If you have added a command to yourself simply type ", <$format, ["link", [["node", "$help_cmd_rehash"]], ["@rehash"], 'do_link]>, ", and your local caches will be updated.", <$format, ["p", [], [], 'do_p]>], 'do_dd]>, <$format, ["dt", [], ["Adding a remote command to an object"], 'do_dt]>, <$format, ["dd", [], [<$format, ["p", [], [], 'do_p]>, "When adding a remote command to something you can rehash the remote caches by simply dropping the item and picking it back up.", <$format, ["p", [], [], 'do_p]>], 'do_dd]>, <$format, ["dt", [], ["Adding a local command to another object"], 'do_dt]>, <$format, ["dd", [], [<$format, ["p", [], [], 'do_p]>, "If you are adding a local command to an object other than yourself, you will have to rehash the entire system's caches. This is done with the command ", <$format, ["link", [["node", "$help_cmd_rehashall"]], ["@rehash-all"], 'do_link]>, ", which is an administrative command."], 'do_dd]>], 'do_dl]>], #[['this, $help_cmd_addcmd]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_addcmd];


new object $help_cmd_reap: $help_cmds;

var $root manager = $help_cmd_reap;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848426641;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@reap", "@reap"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["ADMIN COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@reap [options] [<user>]"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Used in reaping users. Can have various possible behaviours. If no user is specified, it will list all reap possibilities, where possibilities are considered after the user has not logged in for three months. This time can be changed with the ", <$format, ["tt", [], ["time"], 'do_tt]>, " option, which is given as an english explanation of the time, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> @reap +time=\"1 month\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If a user is given, it will enter an interactive user reaping system. At any time during the reaping process you can use @abort to cancel any further actions. ", <$format, ["np", [], [], 'do_np]>, "If a user is given, and the ", <$format, ["tt", [], ["mail"], 'do_tt]>, " option is given, it will mail a one week notice to the user instead of immediatly reaping them (if the ", <$format, ["tt", [], ["time"], 'do_tt]>, " option is also given, it will use that as the interval before reaping, instead of a week). Example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> @reap Bob +mail +time=\"5 days\""], 'do_dfn]>], #[['this, $help_cmd_reap]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_reap];


new object $help_cmd_core: $help_cmds;

var $root manager = $help_cmd_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848468664;
var $help_node index = $help_index_cmds;
var $has_name name = ['prop, "@core", "@core"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@core <object>"], 'do_tt]>], 'do_dfn]>, " ", <$format, ["p", [], [], 'do_p]>, "Setup the specified object as a core object. This is used primarily for core development. It adds the ", <$format, ["tt", [], ["'core"], 'do_tt]>, " flag to the object, sets the object as its own manager and writer and removes any additional ownership."], #[['this, $help_cmd_core]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_core];


new object $help_cmd_delcmd: $help_cmds;

var $root manager = $help_cmd_delcmd;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 854543905;
var $root managed = [$help_cmd_delcmd];
var $has_name name = ['prop, "@del-command|@dc", "@del-command|@dc"];
var $help_node links = #[["@add-command", $help_cmd_addcmd]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, <$format, ["b", [], ["PROGRAMMER COMMAND"], 'do_b]>, <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["Syntax: ", <$format, ["tt", [], ["@del-c?command|@dc \"<Command Template>\" [from] <objref>"], 'do_tt]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Reverses the effects of @add-command. The command template must be identical to the one with which the command was added. The rehashing issues discussed in ", <$format, ["link", [["node", "$help_cmd_addcmd"]], ["@add-command"], 'do_link]>, " apply here (in other words, you may have to do a few tricks to update command caches)."], #[['this, $help_cmd_delcmd]]]>;
var $root inited = 1;


new object $help_cmd_descendants: $help_cmds;

var $root manager = $help_cmd_descendants;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855119873;
var $has_name name = ['prop, "@descendants", "@descendants"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["dfn", [], ["Syntax: `", <$format, ["tt", [], ["@descend <object> [options]"], 'do_tt]>, "`"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Options can be: ", <$format, ["dfn", [["nobound", 1], [" ", 1], ["ind", "4"]], [<$format, ["table", [["cols", "20%,80%"]], [<$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+", <$format, ["i", [], ["N"], 'do_i]>], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Descend ", <$format, ["i", [], ["N"], 'do_i]>, " levels (zero or more)"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+a?ll"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Descend all levels"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+c?ore"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Only show core objects"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [<$format, ["tt", [], ["+r?edundant"], 'do_tt]>], 'do_td]>, <$format, ["td", [], ["Redundantly show objects in the heirarchy"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['this, $help_cmd_descendants]]]>;
var $root inited = 1;
var $root managed = [$help_cmd_descendants];


new object $help_cmd_describe: $help_cmds;

var $root manager = $help_cmd_describe;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856029245;
var $root managed = [$help_cmd_describe];
var $has_name name = ['prop, "@describe", "@describe"];
var $help_node links = #[["CML", $help_cml]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["@describe|@prose <what> [as <description>]"], 'do_tt]>, " ", <$format, ["np", [], [], 'do_np]>, "Set the description (prose) for an object. If nothing other than the target object is given on the command line, you will be prompted for the description. Otherwise it will take anything after the preposition ", <$format, ["i", [], ["as"], 'do_i]>, ", as the description. The description is not written in plaintext, but is in ", <$format, ["link", [["node", "$help_cml"]], ["CML"], 'do_link]>, "."], #[['this, $help_cmd_describe]]]>;
var $root inited = 1;


new object $help_cmd_new: $help_cmds;

var $root manager = $help_cmd_new;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856032830;
var $root managed = [$help_cmd_new];
var $has_name name = ['prop, "@new", "@new"];
var $help_node links = #[["@spawn", $help_cmd_spawn]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["@new <parent>[named <name>]"], 'do_tt]>, " ", <$format, ["np", [], [], 'do_np]>, "Create a new object with the given parent, and optionally set the name. This command is preferred when working with VR objects, as it will correctly handle both real and Frob instances. The alternative is ", <$format, ["link", [["node", "$help_cmd_spawn"]], ["@spawn"], 'do_link]>, " which will always create new objects."], #[['this, $help_cmd_new]]]>;
var $root inited = 1;


new object $help_cmd_wear: $help_cmds;

var $root manager = $help_cmd_wear;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856032839;
var $root managed = [$help_cmd_wear];
var $has_name name = ['prop, "wear|shed", "wear|shed"];
var $help_node links = #[["@new", $help_cmd_new]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["wear <article>"], 'do_tt]>, " OR ", <$format, ["tt", [], ["shed|remove <article>"], 'do_tt]>, " ", <$format, ["np", [], [], 'do_np]>, "Wear or remove an article of clothing. You must be holding (or wearing, as applicable) the article of clothing. The clothing must also be a $wearable_frob. You can create clothing with the ", <$format, ["link", [["node", "$help_cmd_new"]], ["@new"], 'do_link]>, " cmd. For example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@new $wearable_frob named Trenchcoat", <$format, ["br", [], [], 'do_br]>, "wear trenchcoat", <$format, ["br", [], [], 'do_br]>, "shed trenchcoat"], 'do_dfn]>], #[['this, $help_cmd_wear]]]>;
var $root inited = 1;


new object $help_cmd_spawn: $help_cmds;

var $root manager = $help_cmd_spawn;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856034653;
var $root managed = [$help_cmd_spawn];
var $has_name name = ['prop, "@spawn", "@spawn"];
var $help_node links = #[["@new", $help_cmd_new]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: ", <$format, ["tt", [], ["@spawn <parent>[named <name>]"], 'do_tt]>, " ", <$format, ["np", [], [], 'do_np]>, "Create a new object with the given parent, and optionally set the name. This command is generally used only by programmers, as it always creates a real object, and does not create a frob instance. In general the command ", <$format, ["link", [["node", "$help_cmd_new"]], ["@new"], 'do_link]>, " is used instead."], #[['this, $help_cmd_spawn]]]>;
var $root inited = 1;


new object $help_cmd_build: $help_cmds;

var $root manager = $help_cmd_build;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856038007;
var $root managed = [$help_cmd_build];
var $has_name name = ['prop, "@build", "@build"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[['this, $help_cmd_build]]]>;
var $root inited = 1;


new object $help_cmd_dig: $help_cmds;

var $root manager = $help_cmd_dig;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856038007;
var $root managed = [$help_cmd_dig];
var $has_name name = ['prop, "@dig", "@dig"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["This node isn't written yet"], #[['this, $help_cmd_dig]]]>;
var $root inited = 1;


new object $help_sys_message: $help_core, $help_cmds;

var $root manager = $help_sys_message;
var $help_node index = $help_index_subsystem;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856117169;
var $root managed = [$help_sys_message];
var $has_name name = ['prop, "Messages", "Messages"];
var $help_node links = #[["Setting Messages", $help_cmd_msg], ["Defining Messages", $help_cmd_defmsg], ["ColdC Message Interface", $help_msg_coldc]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The message system is used to group several different Ctext messages under a specific message type for single evaluation. A message is composed of a base and any number of branches. The branches define each specific variation on the message, such as with teleport messages--there is the actor's message, the source message and the destination message. This message's base is \"teleport\" with the branches of \"actor\", \"source\" and \"dest\". By default if no branch is specified, the \"general\" branch is used instead (so referencing a message with no branch, and with the \"general\" branch are equivalent).", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], [<$format, ["link", [["node", "$help_cmd_msg"]], ["Setting Messages"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_cmd_defmsg"]], ["Defining Messages"], 'do_link]>], 'do_li]>, <$format, ["li", [], [<$format, ["link", [["node", "$help_msg_coldc"]], ["ColdC Message Interface"], 'do_link]>], 'do_li]>], 'do_ul]>], #[['links, #[["Setting Messages", "$help_cmd_msg"], ["Defining Messages", "$help_cmd_defmsg"], ["ColdC Message Interface", "$help_msg_coldc"]]]]]>;
var $root inited = 1;
var $root child_index = 4;


new object $help_cmd_defmsg: $help_sys_message;

var $root manager = $help_cmd_defmsg;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856118984;
var $root managed = [$help_cmd_defmsg];
var $has_name name = ['prop, "@def-msg|@undef-msg", "@def-msg|@undef-msg"];
var $help_node links = #[["@msg", $help_cmd_msg], ["Messages", $help_sys_message]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: `", <$format, ["tt", [], ["@def-msg|@undef-msg <target>:<msg> [options]"], 'do_tt]>, "` ", <$format, ["np", [], [], 'do_np]>, "This command is used to define and undefine a message base. Because multiple branches for one base can exist, you cannot define the default values for the message with this command, use ", <$format, ["link", [["node", "$help_cmd_msg"]], ["@msg"], 'do_link]>, " for this instead, after the message is defined. More information on Messages can be found in the section ", <$format, ["link", [["node", "$help_sys_message"]], ["Messages"], 'do_link]>, ". Options can be: ", <$format, ["dfn", [["nobound", 1]], [<$format, ["table", [["cols", "25%,75%"]], [<$format, ["tr", [], [<$format, ["td", [], ["+b?ranches"], 'do_td]>, <$format, ["td", [], ["Define the branches, in a comma delimited list."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["+c?ompiler"], 'do_td]>, <$format, ["td", [], ["Define the compiler. Defaults to $compiler."], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["+e?valuator"], 'do_td]>, <$format, ["td", [], ["Define the evaluator. Defaults to $bs_eval."], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "An example of defining the message \"open\" with the branches \"actor\" and \"general\":", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@def-msg mybox:open +b=general,actor", <$format, ["br", [], [], 'do_br]>, "@msg mybox:open = General Message", <$format, ["br", [], [], 'do_br]>, "@msg mybox:open.actor = Actor's Message"], 'do_dfn]>], #[['this, $help_cmd_defmsg]]]>;
var $root inited = 1;


new object $help_msg_coldc: $help_sys_message;

var $root manager = $help_msg_coldc;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856117601;
var $root managed = [$help_msg_coldc];
var $has_name name = ['prop, "ColdC Interface", "ColdC Interface"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The message subsystem is contained on the $foundation object. It uses two object variables: ", <$format, ["dfn", [["ind", "4"], ["nobound", 1]], [<$format, ["table", [["cols", "25%,75%"]], [<$format, ["tr", [], [<$format, ["td", [], [",msgs"], 'do_td]>, <$format, ["td", [], ["Local instances of a defined message"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], [",defined_msgs"], 'do_td]>, <$format, ["td", [], ["Defined messages and attributes"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "And the following methods:", <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [".defined_msgs()"], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Returns the defined_msgs variable from the current object."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [".all_defined_msgs()"], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Returns all messages defined by the current object and all ancestors up to $foundation."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [".msgs()"], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Returns any local messages instances."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [".all_msgs()"], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Returns all messages and instances, local or default."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [".define_msg(name)"], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Define a new message."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [".undefine_msg(name)"], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Undefine a message (will clear any instances)."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [".get_msg(name, definer)"], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Get all branches (local or default) of the message."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [".set_msg(name, branch, definer, value)"], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Set the value of a branch of a message."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [".clear_msg(name, [branches])"], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Clear the local instance and branches of a message. If no branches are defined all branches are cleared."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [".get_msg_attr(name, attr)"], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Get the specified attribute for a message."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [".set_msg_attr(name, attr, value)"], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Set the specified attribute for a message."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [".msg_definer(name)"], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Determine the definer for a message."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [".get_default_msg(name)"], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Get the default branches for a message."], 'do_dd]>, <$format, ["dt", [], [<$format, ["subj", [["level", "3"]], [".eval_message(name, definer, vars)"], 'do_subj]>], 'do_dt]>, <$format, ["dd", [], ["Evaluate a message"], 'do_dd]>], 'do_dl]>], #[['this, $help_msg_coldc]]]>;
var $root inited = 1;


new object $help_cmd_msg: $help_sys_message;

var $root manager = $help_cmd_msg;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856117601;
var $root managed = [$help_cmd_msg];
var $has_name name = ['prop, "@msg", "@msg"];
var $help_node links = #[["CML", $help_cml]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: `", <$format, ["tt", [], ["@msg|@message [-clear] [<target>:][<msg>=<value>]"], 'do_tt]>, "` ", <$format, ["np", [], [], 'do_np]>, "You can view and set messages with this command. When no message is given (and only the target is specified) it will list all messages on the target object. If no target is specified, the target will default to the current object. If a message and value is specified, it will set the value as appropriate. The value is be written in ", <$format, ["link", [["node", "$help_cml"]], ["CML"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "If the message is undefined on an object, it will default to the value given on the defining object. To revert a message back to the default value use the -clear option, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@msg -clear teleport.actor"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Some examples of setting and viewing messages:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["> @msg", <$format, ["br", [], [], 'do_br]>, "-- Messages on Brandon ($brandon):", <$format, ["br", [], [], 'do_br]>, "teleport.actor = You teleport to [dest].", <$format, ["br", [], [], 'do_br]>, "teleport.dest = [actor] teleports here from [source].", <$format, ["br", [], [], 'do_br]>, "teleport.source = [actor] teleports to [dest]."], 'do_dfn]>, " ", <$format, ["dfn", [], ["> @msg north:invoke.actor=You walk up [exit].", <$format, ["br", [], [], 'do_br]>, "-- Message changed to:", <$format, ["br", [], [], 'do_br]>, "invoke.actor = You walk up [exit]."], 'do_dfn]>], #[['this, $help_cmd_msg]]]>;
var $root inited = 1;


new object $help_cmd_nh: $help_cmds;

var $root manager = $help_cmd_nh;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856455556;
var $root managed = [$help_cmd_nh];
var $has_name name = ['prop, "@nh|@new-help-node", "@nh|@new-help-node"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: `", <$format, ["tt", [], ["@nh [<node>] [options]"], 'do_tt]>, "` ", <$format, ["np", [], [], 'do_np]>, "The argument ", <$format, ["i", [], ["node"], 'do_i]>, " is the parent node to descend from, or if unspecified it will defualt to the current node. Options can be:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["+i?ndex=index", <$format, ["br", [], [], 'do_br]>, "+o?bjname=objname", <$format, ["br", [], [], 'do_br]>, "+n?ame=\"name of node\""], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "A seperate entry is made in the index for each branch in the name (seperated by the | character)."], #[['this, $help_cmd_nh]]]>;
var $root inited = 1;


new object $help_cmd_rename: $help_cmds;

var $root manager = $help_cmd_rename;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856649394;
var $root managed = [$help_cmd_rename];
var $has_name name = ['prop, "@rename", "@rename"];
var $help_node links = #[["Name templates", $help_app_names], ["Template Matching", $help_commands_matching], ["@add-name-template", $help_cmd_ant], ["@del-name-template", $help_cmd_dnt]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: `", <$format, ["tt", [], ["@rename <target> [to] \"<newname>\""], 'do_tt]>, "` ", <$format, ["np", [], [], 'do_np]>, "Used to change the ", <$format, ["i", [], ["target"], 'do_i]>, " object's name or object name. Quotes may be used, but are not required. ", <$format, ["link", [["node", "$help_app_names"]], ["Name templates"], 'do_link]>, " may also be specified with the new name, by seperating them from the name with commas, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@rename exit to Gilded Door, w?est, o?ut"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Keep in mind that the name is matched using the beginning of each word, where the templates are mached with ", <$format, ["link", [["node", "$help_commands_matching"]], ["Template Matching"], 'do_link]>, ". Name templates can also be changed with the commands ", <$format, ["link", [["node", "$help_cmd_ant"]], ["@add-name-template"], 'do_link]>, " and ", <$format, ["link", [["node", "$help_cmd_dnt"]], ["@del-name-template"], 'do_link]>, ". ", <$format, ["np", [], [], 'do_np]>, "The object name can also be changed, by specifying a valid object name as the new name, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@rename $thing_152 to $my_lamp"], 'do_dfn]>], #[['this, $help_cmd_rename]]]>;
var $root inited = 1;


new object $help_cmd_ant: $help_cmds;

var $root manager = $help_cmd_ant;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856650064;
var $root managed = [$help_cmd_ant];
var $has_name name = ['prop, "@ant|@add-name-template", "@ant|@add-name-template"];
var $help_node links = #[["Template Matching", $help_commands_matching], ["@rename", $help_cmd_rename], ["Names", $help_app_names]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: `", <$format, ["tt", [], ["@ant|@add-name-template <template> [to] <target>"], 'do_tt]>, "` ", <$format, ["np", [], [], 'do_np]>, "Add the given name template to the target object. The template uses ", <$format, ["link", [["node", "$help_commands_matching"]], ["Template Matching"], 'do_link]>, ". If the template is redundant and conflicts with the current name, an error will be returned and the template will not be added. ", <$format, ["np", [], [], 'do_np]>, "The command ", <$format, ["link", [["node", "$help_cmd_rename"]], ["@rename"], 'do_link]>, " may also be used to specify the name templates. The section ", <$format, ["link", [["node", "$help_app_names"]], ["Names"], 'do_link]>, " explains more about names and name templates."], #[['this, $help_cmd_ant]]]>;
var $root inited = 1;


new object $help_cmd_dnt: $help_cmds;

var $root manager = $help_cmd_dnt;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856650064;
var $root managed = [$help_cmd_dnt];
var $has_name name = ['prop, "@dnt|@del-name-template", "@dnt|@del-name-template"];
var $help_node links = #[["Names", $help_app_names]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: `", <$format, ["tt", [], ["@dnt|@del-name-template <template> [from] <target>"], 'do_tt]>, "` ", <$format, ["np", [], [], 'do_np]>, "Remove the given name template from the target object. The section ", <$format, ["link", [["node", "$help_app_names"]], ["Names"], 'do_link]>, " explains more about names and name templates."], #[['this, $help_cmd_dnt]]]>;
var $root inited = 1;


new object $help_cmd_remember: $help_cmds;

var $root manager = $help_cmd_remember;
var $help_node index = $help_index_cmds;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856651645;
var $root managed = [$help_cmd_remember];
var $has_name name = ['prop, "@remember", "@remember"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Syntax: `", <$format, ["tt", [], ["@remember <item> as <what>"], 'do_tt]>, "` ", <$format, ["np", [], [], 'do_np]>, "Using this command you can alias something which is either hard to type or hard to remember, so that later you can reference it with the new alias you set to it, rather than it's full name. Remembered items do not have to be in the environment for them to be matched. This is also useful, as you do not need to remember full object names. An example would be:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@remember $robot_1512 as fred"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "If you do this, you will be able to reference ", <$format, ["tt", [], ["$robot_1512"], 'do_tt]>, " as ", <$format, ["tt", [], ["fred"], 'do_tt]>, ", even if it is not in your environment. This can potentially cause conflicts, as anything remembered is given priority over anything in your environment."], #[['this, $help_cmd_remember]]]>;
var $root inited = 1;


new object $help_sys_word: $help_core;

var $root manager = $help_sys_word;
var $help_node index = $help_index_subsystem;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856384074;
var $root managed = [$help_sys_word];
var $has_name name = ['prop, "Word Generator", "Word Generator"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "This random word generator uses syllables and word patterns, and is inspired by a similar generator written by Ross Smith (Infact, the Lovecraftian dictionary came from his generator). ", <$format, ["np", [], [], 'do_np]>, "The generator uses different patterns to generate the word, where each pattern has a chance of being chosen. First is the number of syllables in a word. Once the syllables are chosen a syllable pattern is selected for each syllable. From the syllable pattern vowel or consanant patterns are chosen. It is possible to use two dictionaries for consanants, so as to have 'first' and 'last' consanant patterns. The syllable pattern must be composed of either V (vowel), C (consanant), or LC (last consanant) tokens seperated by dashes, such as:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["C-V-LC"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "Which would imply the syllable pattern of a Consanant-Vowel-Last Consanant. ", <$format, ["np", [], [], 'do_np]>, "The various patterns are defined by submitting a configuration to the word generator object (spawn $word for your own generator). This can be done with the simple evaluation command (which will prompt you for the configuration lines):", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [";$my_word.submit_chances(.read())"], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "You can also list the configuration with:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [";.tell($my_word.format_chances())"], 'do_dfn]>, " ", <$format, ["subj", [["level", "3"]], ["Configuration"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "The configuration takes one pattern and chance per line, with an optional comment character of \"#\" which is discarded. The pattern must begin with a directive designating the pattern. Directives can be any of: ", <$format, ["dfn", [["ind", "4"], ["nobound", 1]], [<$format, ["table", [["cols", "10%,90%"]], [<$format, ["tr", [], [<$format, ["td", [], ["S"], 'do_td]>, <$format, ["td", [], ["Number of Syllables"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["SP"], 'do_td]>, <$format, ["td", [], ["Syllable Patterns"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["C"], 'do_td]>, <$format, ["td", [], ["Consanants"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["LC"], 'do_td]>, <$format, ["td", [], ["Last Consanants"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["V"], 'do_td]>, <$format, ["td", [], ["Vowels"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>, <$format, ["p", [], [], 'do_p]>, "There is no limit to the amount of patterns submitted. A very simple configuration would be: ", <$format, ["dfn", [], [<$format, ["quote", [], ["\nS 2 3\nS 3 1\n\nSP V 2\nSP V-C 4\nSP C-V 2\n\nV a 10\nV e 10\nV i 10\n\nFC th 1\nFC b 4\nFC f 4\nFC qu 1\n\nLC bh 1\nLC d 4\nLC b 4"], 'do_quote]>], 'do_dfn]>], #[['this, $help_sys_word]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_weather_system: $help_core;

var $root manager = $help_weather_system;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856455167;
var $root managed = [$help_weather_system];
var $has_name name = ['prop, "Weather System", "Weather System"];
var $help_node links = #[["$climate (and descendants)", $help_sys_climate], ["$weather (and descendants)", $help_sys_weather], ["$weather_attributes", $help_sys_weather_attributes]];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "ColdCore uses elaborate weather system, allowing the administrators to set realistic weathers and climates, described in great detail. The system is based on several objects, each keeping track of a facet of the weather:", <$format, ["dl", [], [<$format, ["dt", [], ["$world"], 'do_dt]>, <$format, ["dd", [], ["$world keeps the weather cycle, and calls the updates on realms."], 'do_dd]>, <$format, ["dt", [], ["$realm (and descendants)"], 'do_dt]>, <$format, ["dd", [], ["Children of $realm keep track of the current weather and season, as well as of VR timezones."], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_sys_climate"]], ["$climate (and descendants)"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["$climate keeps the season names for each part of the year, and lists of weathers that may occur in that climate."], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_sys_weather"]], ["$weather (and descendants)"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["Weather objects contain weather descriptions, messages and attributes. Attributes are the most important, since they can be used to fork room descriptions to reflect conditions in the weather."], 'do_dd]>, <$format, ["dt", [], [<$format, ["link", [["node", "$help_sys_weather_attributes"]], ["$weather_attributes"], 'do_link]>], 'do_dt]>, <$format, ["dd", [], ["This object is a database of all the available weather attributes."], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "When changing the weather, the system will pay attention to differences between weather attributes (so it'll be unlikely that a storm will start a moment after the sun shining), seasonal ratings, and inter-realm dependancies. ", <$format, ["np", [], [], 'do_np]>, "Follow the links in the list above to read more about the system."], #[['this, $help_weather_system]]]>;
var $root trusted = [$help_node];
var $root inited = 1;
var $help_node nolist = 0;


new object $help_sys_climate: $help_weather_system;

var $root manager = $help_sys_climate;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856455152;
var $root managed = [$help_sys_climate];
var $has_name name = ['prop, "Climate", "Climate"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [["Climate is a container for multiple weathers with assigned probabilities. Climate holds the following information:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], ["A list of season names."], 'do_li]>, <$format, ["li", [], ["A list of daylengths assigned to each season. Daylength is given as an offset, meaning that with +2, you have an early sunrise and late sunset. This number is interpreted by $world_time."], 'do_li]>, <$format, ["li", [], ["A list of weathers, each with probabilities for every season. Probabilities are not percentages, instead, only their ratios really matter."], 'do_li]>], 'do_ul]>, <$format, ["p", [], [], 'do_p]>, <$format, ["subj", [["level", "3"]], ["Climate commands"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], ["@setup <this> seasons <any> daylengths <any>"], 'do_dt]>, <$format, ["dd", [], ["Erases all the data on a climate object, sets a new season list and daylength lists. Both arguments are list of items separated by space; they must be of the same length."], 'do_dd]>, <$format, ["dt", [], ["@list-climate <this>"], 'do_dt]>, <$format, ["dd", [], ["Shows the information on climate."], 'do_dd]>, <$format, ["dt", [], ["@add-weather <this> type <descendant of $weather> prob?abilities <any>"], 'do_dt]>, <$format, ["dd", [], ["Adds a weather object to $climate; the object must be already built. Probabilities is a ' '-separated list of integers, one element for each season."], 'do_dd]>, <$format, ["dt", [], ["@del-weather <this> type <descendant of $weather>"], 'do_dt]>, <$format, ["dd", [], ["Removes weather from the climate."], 'do_dd]>], 'do_dl]>], #[['this, $help_sys_climate]]]>;
var $root trusted = [$help_node];
var $root inited = 1;
var $help_node nolist = 0;


new object $help_sys_weather: $help_weather_system;

var $root manager = $help_sys_weather;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856455112;
var $root managed = [$help_sys_weather];
var $has_name name = ['prop, "Weather", "Weather"];
var $help_node links = #[["weather attributes", $help_sys_weather_attributes]];
var $help_node body = <$ctext_frob, [["Weather is a container for ", <$format, ["link", [["node", "$help_sys_weather_attributes"]], ["weather attributes"], 'do_link]>, ", description and invocation message. Make sure to follow these conventions when creating a weather object:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], ["name must be an adjective (example: nice, sunny, stormy)"], 'do_li]>, <$format, ["li", [], ["invoke message is printed each time $weather sets this weather to be current in a realm"], 'do_li]>, <$format, ["li", [], ["attributes *must* be set"], 'do_li]>], 'do_ul]>], #[['this, $help_sys_weather]]]>;
var $has_name templates = ["Generic Weather"];
var $root trusted = [$help_node];
var $root inited = 1;
var $help_node nolist = 0;


new object $help_sys_weather_attributes: $help_weather_system;

var $root manager = $help_sys_weather_attributes;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856455137;
var $root managed = [$help_sys_weather_attributes];
var $has_name name = ['prop, "Attributes", "Attributes"];
var $help_node links = #[["Generic Weather", $help_sys_weather]];
var $help_node body = <$ctext_frob, [["Weather attributes are general characteristics a weather might have, such as humidity, precipitation, and so on. They are usable as generators in room descs, allowing one to speak about 'rivulets of rain sliding down the ravine' only if it really is raining, or to say that 'it's terribly hot' only if it really is hot. In addition to that, one can add more complex 'extra' attributes. These are not set on the weather, but are calculated from the existing attributes; for example, you can use them as switchers for 'is it a hot, humid night'? cases. Note that you shouldn't fiddle with this object too much once you set its attributes for the first time, because otherwise you may need to reset the weathers objects.", <$format, ["p", [], [], 'do_p]>, <$format, ["subj", [["level", "3"]], ["Weather attribute commands"], 'do_subj]>, <$format, ["dl", [], [<$format, ["dt", [], ["@add-weather-attribute|awa <any> values <any> to <this>"], 'do_dt]>, <$format, ["dd", [], ["Adds a new weather attribute. Values is a list of descripting values separated by ';'. For example:", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], ["@awa precipitation values none;rain;heavy rain;snow to $weather_attributes"], 'do_dfn]>], 'do_dd]>, <$format, ["dt", [], ["@add-extra-attribute|@aea <any> values <any> to <this>"], 'do_dt]>, <$format, ["dd", [], ["Adds extra attribute. Unlike normal attribs, these don't need to be set on the weather objects."], 'do_dd]>, <$format, ["dt", [], ["@del-weather-attribute|dwa <any> from <this>"], 'do_dt]>, <$format, ["dd", [], ["Removes a weather attribute."], 'do_dd]>, <$format, ["dt", [], ["@list-weather-attributes|lwa <this>"], 'do_dt]>, <$format, ["dd", [], ["Lists the current setup."], 'do_dd]>], 'do_dl]>, <$format, ["subj", [["level", "3"]], ["Default attributes"], 'do_subj]>, <$format, ["p", [], [], 'do_p]>, "These attributes are set in the coldcore as-is. Modify them only if you are prepared to use @set weather:attributes on all descendants of ", <$format, ["link", [["node", "$help_sys_weather"]], ["Generic Weather"], 'do_link]>, ".", <$format, ["p", [], [], 'do_p]>, <$format, ["dfn", [], [<$format, ["table", [["cols", "30%,70%"]], [<$format, ["tr", [], [<$format, ["td", [], ["precipitation"], 'do_td]>, <$format, ["td", [], ["fine;drizzle;rain;shower;snow"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["humidity"], 'do_td]>, <$format, ["td", [], ["dry;fine;humid"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["temperature"], 'do_td]>, <$format, ["td", [], ["hot;warm;cold;freezing"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["visibility"], 'do_td]>, <$format, ["td", [], ["clear;hazy;murky"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["wind"], 'do_td]>, <$format, ["td", [], ["serene;windy;stormy"], 'do_td]>], 'do_tr]>, <$format, ["tr", [], [<$format, ["td", [], ["clouds"], 'do_td]>, <$format, ["td", [], ["clear;cloudy;overcast"], 'do_td]>], 'do_tr]>], 'do_table]>], 'do_dfn]>], #[['this, $help_sys_weather_attributes]]]>;
var $has_name templates = ["Weather Attributes"];
var $root trusted = [$help_node];
var $root inited = 1;
var $help_node nolist = 0;


new object $help_mutex: $help_core;

var $root manager = $help_mutex;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858089990;
var $root managed = [$help_mutex];
var $has_name name = ['prop, "Mutex", "Mutex"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "Mutex is 'Mutual Exclusion'. Its purpose is preventing concurrent tasks from interfering with each other. A task grabbing mutex lock will suspend until all other tasks release the incompatible locks. Each lock has class and list of values. Two locks are ", <$format, ["i", [], ["incompatible"], 'do_i]>, " if:", <$format, ["p", [], [], 'do_p]>, <$format, ["ul", [], [<$format, ["li", [], ["Their class have common descendant (classes themselves are considered descendants for the purpose of this definition)"], 'do_li]>, <$format, ["li", [], ["Their values have common elements."], 'do_li]>], 'do_ul]>, <$format, ["np", [], [], 'do_np]>, "Primary mutex class is $mutex (note that grabbing $mutex will cause all attempts to grab locks with similar values to suspend). Its descendants allow programmer to set up finer locks, which allow multiple tasks to deal with nondisjoint value lists concurrently. ", <$format, ["np", [], [], 'do_np]>, "$mutex has the following functions:", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], [".grab(@values)"], 'do_dt]>, <$format, ["dd", [], ["Grab the list of values on the called class."], 'do_dd]>, <$format, ["dt", [], [".release(@values)"], 'do_dt]>, <$format, ["dd", [], ["Release the list from the class."], 'do_dd]>, <$format, ["dt", [], [".release_all()"], 'do_dt]>, <$format, ["dd", [], ["Release all the locks held by the current class. Use this call from connection objects and such."], 'do_dd]>, <$format, ["dt", [], [".cleanup_dead_tasks()"], 'do_dt]>, <$format, ["dd", [], ["Remove the dead tasks from this class."], 'do_dd]>], 'do_dl]>], #[['this, $help_mutex]]]>;
var $root inited = 1;
var $help_node nolist = 0;


new object $help_heap: $help_core;

var $root manager = $help_heap;
var $help_node index = $help_index_core;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858400875;
var $has_name name = ['prop, "Heap", "Heap"];
var $help_node links = #[];
var $help_node body = <$ctext_frob, [[<$format, ["p", [], [], 'do_p]>, "The heap is an efficient implementation of the priority queue. It is currently used by $scheduler and $graph. When you use it only in assignment calls (", <$format, ["tt", [], ["list = $heap.method(args)"], 'do_tt]>, ", in other words), it will operate in the logarithmic time (very fast).", <$format, ["p", [], [], 'do_p]>, "Heap is a list with the property that ", <$format, ["i", [], ["i"], 'do_i]>, "-th element of the list has lower priority than either ", <$format, ["i", [], ["2*i"], 'do_i]>, "-th and ", <$format, ["i", [], ["2*i+1"], 'do_i]>, "-st element of the list. Obviously, the first element of the list will have the lowest priority.", <$format, ["p", [], [], 'do_p]>, <$format, ["dl", [], [<$format, ["dt", [], [<$format, ["tt", [], ["$heap.add(heap, element, priority_index)"], 'do_tt]>], 'do_dt]>, <$format, ["dd", [], ["Add a new element to the heap. In this implementation, heap is assumed to be list of lists, with priority_index determining the priority field of each element."], 'do_dd]>, <$format, ["dt", [], [<$format, ["tt", [], ["$heap.del(heap, index, priority_index)"], 'do_tt]>], 'do_dt]>, <$format, ["dd", [], ["Delete an element at index ", <$format, ["i", [], ["i"], 'do_i]>, " of the heap. if index is greater than length of the heap, the method will throw."], 'do_dd]>], 'do_dl]>, <$format, ["p", [], [], 'do_p]>, "Both methods assume that their first argument already is a heap."], #[['this, $help_heap]]]>;
var $root inited = 1;
var $root managed = [$help_heap];


new object $channel_db: $db;

var $root manager = $channel_db;
var $channel_db system_channels = ['Login, 'System, 'All];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 845244416;
var $root trusted = [$channel_ui];
var $db database = #[['public, ['Public, 1, 0, 0, #6, [#6], "Everyone can discuss anything any time, for any reason.", 0]], ['login, ['Login, 1, 0, 0, #6, [#6], "User log in and out notifications.", 0]], ['system, ['System, 1, 0, 0, #6, [#6], "System wide messages like backup notifications.", 0]]];
var $root inited = 1;
var $root managed = [$channel_db];

protected method .clean_db() {
    var x, d;
    
    d = #[];
    for x in (.database()) {
        pause();
        if ((x[2])[2])
            d = d.add(@x);
    }
    .set_database(d);
    
    // $#Edited: 02 Nov 96 17:43 $brad
};

public method .system_channels() {
    return system_channels;
    
    // $#Edited: 03 Nov 96 17:24 $brad
};

root method .core_channel_db() {
    .clean_db();
};


new object $mail_lib: $libraries, $mail_root;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $mail_lib mail_system = [$mail_message, $mail_list, $mail_ui, $mail_lib];
var $root manager = $mail_lib;
var $root owned = [$mail_lib];
var $root managed = [$mail_lib];

public method .mail_name() {
    arg obj;
    
    if (!(obj.has_ancestor($mail_list)))
        throw(~type, "Object is not a child of $mail_recipient");
    if (obj.has_ancestor($user))
        return (obj.name()).replace(" ", "-");
    return "*" + ((obj.name()).replace(" ", "-"));
};

public method .has_mail_perms() {
    arg @args;
    var obj;
    
    for obj in (args) {
        if ((!(obj in mail_system)) && (!($sys.is_system(obj))))
            return 0;
    }
};

public method .match_mail_recipient() {
    arg name;
    
    catch ~namenf {
        if ((name[1]) == "*")
            return (> $mail_db.search(name.subrange(2)) <);
        if (name == "me")
            return sender();
        return (> $user_db.search(name) <);
    } with {
        throw(~listnf, ("No mail recipient found by the name \"" + name) + "\".");
    }
};

public method .range_to_actual() {
    arg rng, current;
    var start, end, out, listm, m, x, list;
    
    list = current['list];
    listm = list.mail();
    if (type(rng[1]) == 'integer) {
        start = rng[1];
    } else {
        switch (rng[1]) {
            case 'end:
                if (type(rng[2]) != 'symbol)
                    throw(~range, "Backwards range.");
                start = ((current['list]).mail()).length();
            case 'start:
                start = 1;
            case 'current:
                start = (current['location]) in listm;
            case 'specific:
                out = [];
                for m in ((rng[2]).explode_english_list()) {
                    if ((!(x = toint(m))) || (x < 1)) {
                        sender().tell(("Ignoring list range element '" + m) + "'.");
                    } else {
                        catch ~range
                            out = setadd(out, (> listm[x] <));
                        with
                            sender().tell(((((("List range #" + x) + " is higher than the messages in ") + (list.mail_name())) + " (") + (listm.length())) + ")");
                    }
                }
                return out || throw(~range, "No elements in list range.");
        }
    }
    if (type(rng[2]) == 'integer) {
        end = rng[2];
    } else {
        switch (rng[2]) {
            case 'end:
                end = ((current['list]).mail()).length();
            case 'single:
                end = start;
            case 'start:
                throw(~range, "Backwards range.");
            case 'current:
                end = (current['location]) in ((current['list]).mail());
        }
    }
    if (start > end)
        throw(~range, "Backwards range.");
    out = [];
    for m in [start .. end] {
        catch ~range
            out = setadd(out, (> listm[m] <));
        with
            sender().tell(((((("List range #" + m) + " is higher than the messages in ") + (list.mail_name())) + " (") + (listm.length())) + ")");
    }
    return out || throw(~range, "No elements in list range.");
};


new object $user_parsers: $misc;

var $root child_index = 13;
var $root fertile = 1;
var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root manager = $user_parsers;
var $user_parsers priority = 0;
var $root owned = [$user_parsers];
var $root managed = [$user_parsers];

public method .parse() {
    arg user, str, next_parser, @other_parsers;
    
    // Minimum parser routine.
    return next_parser.parse(user, str, @other_parsers);
};

public method .priority() {
    return priority || 1000;
};

public method .set_priority() {
    arg new;
    
    (> .perms(sender(), 'manager) <);
    priority = new;
};


new object $null_parser: $user_parsers;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $null_parser;
var $root managed = [$null_parser];
var $root owned = [$null_parser];
var $user_parsers priority = 10000;

public method .parse() {
    arg user, str, @anything_else;
    var i;
    
    for i in [1 .. str.length()] {
        if ((str[i]) != " ")
            return ['failed];
    }
    return ['ok];
};


new object $command_aliases_parser: $user_parsers;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $command_aliases_parser;
var $root managed = [$command_aliases_parser];
var $root owned = [$command_aliases_parser];
var $user_parsers priority = 750;

public method .parse() {
    arg user, str, next_parser, @other_parsers;
    var alias, match, i, result, old;
    
    for alias in (user.command_aliases()) {
        match = str.match_pattern(alias[1]);
        if (match != 0) {
            old = str;
            str = "";
            for i in (alias[2]) {
                if (type(i) == 'integer)
                    str += match[i];
                else
                    str += i;
            }
        }
    }
    result = next_parser.parse(user, str, @other_parsers);
    if (old && ((result[1]) == 'failed))
        return ['error, ("Command converted to \"" + str) + "\" but not understood."];
    return result;
};


new object $command_parser: $user_parsers;

var $root manager = $command_parser;
var $root created_on = 796680318;
var $root inited = 1;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root managed = [$command_parser];
var $root owned = [$command_parser];
var $root child_index = 1;

public method .parse() {
    arg u, str, next_parser, @other_parsers;
    var l, cmd, c, p, obj;
    
    cmd = str.explode();
    if (cmd) {
        cmd = [str, cmd[1], ((cmd.subrange(2)).join()) || ""];
        p = [];
        if ((c = (| u.match_in_shortcut_cache(@cmd) |))) {
            if ((c[1]) == 'shortcut)
                return .shortcut(u, @c[2]);
            p = c[2];
        }
        if ((c = (| u.match_in_local_cache(@cmd) |))) {
            if ((c[1]) == 'local)
                return .local(u, @c[2]);
            p += c[2];
        }
        if ((c = (| u.match_in_remote_cache(@cmd) |))) {
            if ((c[1]) == 'remote)
                return .remote(u, @c[2]);
            p += c[2];
        }
        l = u.location();
        if ((c = (| l.match_in_local_cache(@cmd) |))) {
            if ((c[1]) == 'local)
                return .local(l, @c[2]);
            p += c[2];
        }
        if ((c = (| l.match_in_remote_cache(@cmd) |))) {
            if ((c[1]) == 'remote)
                return .remote(u, @c[2]);
            p += c[2];
        }
        if ((c = (| .grasp_for_remote_command(@cmd) |))) {
            if ((c[1]) == 'remote)
                return .remote(u, @c[2]);
            p += c[2];
        }
        for obj in ((| (u.location()).exits() |) || []) {
            if (obj.match_name(str))
                return ['command, obj, 'invoke];
        }
        if (p)
            return .partial(u, cmd, p);
    }
    return next_parser.parse(u, str, @other_parsers);
    
    // $#Edited: 03 Mar 97 21:47 $brad
    // $#Edited: 03 Mar 97 23:22 $user_brad
};

public method .partial() {
    arg user, args, templates;
    var part, line;
    
    for part in (templates)
        templates = templates.replace(part in templates, toliteral(part));
    if ((templates.length()) == 1)
        line = toliteral(args[2]) + " could match ";
    else if ((templates.length()) == 2)
        line = toliteral(args[2]) + " could match either ";
    else
        line = toliteral(args[2]) + " could match any of ";
    return ['error, (line + (templates.to_english("", " or "))) + "."];
    
    // $# Edited 18 Oct 1995 11:55 Lynx ($lynx)
};

public method .shortcut() {
    arg user, method, parsed;
    
    return ['command, user, method, @parsed];
};

public method .complete() {
    arg cmd, user, obj, match, info;
    var x, method, parsed;
    
    method = info[2];
    info = info[4];
    parsed = info.keys();
    for x in [1 .. match.length()] {
        if (x in parsed)
            match = match.replace(x, (> $command_lib.convert_arg((info[x])[1], match[x], user, ((info[x])[2]) ? (info[x])[2] : user, user) <));
    }
    return [user, method, (cmd.explode())[1], @match];
};

public method .grasp_for_remote_command() {
    arg str, cmd, args;
    var reg, obj, cdef, match, matched, info;
    
    reg = args.match_regexp("[$#][a-z_0-9][a-z_0-9]*");
    if (!reg)
        return 0;
    obj = (| $object_lib.to_dbref(args.subrange(@reg[1])) |);
    if (!obj)
        return 0;
    info = (| obj.get_command_info('remote, cmd) |);
    if (!info)
        return 0;
    matched = [];
    for cdef in (info) {
        match = args.match_template(cdef[2]);
        if (match != 0)
            matched += [[match.length(), obj, [str, cmd, @match], @cdef.subrange(3)]];
    }
    if (matched) {
        matched = matched.sort(matched.slice(1));
        return ['remote, matched];
    }
    return ['partial, [[str, cmd], info.slice(3)]];
    
    // $#Edited: 12 Aug 96 18:29 $jenner
};

public method .local() {
    arg user, @matches;
    var parsed, match;
    
    parsed = [];
    for match in (matches) {
        match = ._local(user, @match);
        if ((match[1]) == 'command)
            return match;
        parsed = [match[2]] + parsed;
    }
    return ['error, parsed.compress()];
};

public method .remote() {
    arg user, @matches;
    var parsed, match;
    
    parsed = [];
    for match in (matches) {
        match = ._remote(user, @match);
        if ((match[1]) == 'command)
            return match;
        parsed = [match[2]] + parsed;
    }
    return ['error, parsed.compress()];
};

public method .handle_error() {
    arg traceback;
    
    return (traceback[1])[2];
};

public method ._remote() {
    arg user, nmatch, definer, match, template, method, info;
    var x, value, that, cmd;
    
    cmd = match[2];
    catch any {
        for x in [1 .. nmatch] {
            if (dict_contains(info, x)) {
                if (((info[x])[1]) == 'this) {
                    that = (> user.match_environment(match[x + 2]) <);
                    if (!(that.is(definer)))
                        return ['error, ((("You cannot " + (match[2])) + " ") + (that.name())) + "."];
                } else {
                    value = (> .convert_arg(cmd, (info[x])[1], match[x + 2], user, ((info[x])[2]) || [definer], user) <);
                }
                match = match.replace(x + 2, value);
            }
        }
    } with {
        if (error() == ~syntax)
            return ['error, (((traceback()[1])[2]) + template) + "\""];
        return ['error, (traceback()[1])[2]];
    }
    if (!that)
        return ['error, "An error was encountered: no target object found."];
    return ['command, that, method, @match];
};

public method ._local() {
    arg user, nmatch, match, template, method, info;
    var x, cmd;
    
    cmd = match[2];
    catch any {
        for x in [1 .. nmatch] {
            if (dict_contains(info, x))
                match = match.replace(x + 2, (> .convert_arg(cmd, (info[x])[1], match[x + 2], user, (info[x])[2], user) <));
        }
    } with {
        if (error() == ~syntax)
            return ['error, (((traceback()[1])[2]) + template) + "\""];
        return ['error, (traceback()[1])[2]];
    }
    return ['command, user, method, @match];
};

public method .convert_arg() {
    arg cmd, type, str, me, argargs, target;
    var obj, args, anc, out, x, y, list;
    
    switch (type) {
        case 'list:
            out = [];
            if (!str)
                return [(> .convert_arg(cmd, argargs[1], "", me, argargs[2], target) <)];
    
            // or do the whole list
            if ("," in str)
                list = str.explode_english_list(",");
            else
                list = explode(str);
            for x in (list) {
                catch ~ambig {
                    out = out.setadd(.convert_arg(cmd, argargs[1], x, me, argargs[2], target));
                } with {
                    if ((| (traceback()[1])[3] |) && (!((argargs[1]) in ['user, 'user_opt]))) {
                        for y in ((traceback()[1])[3])
                            out = out.setadd((> .convert_arg(cmd, argargs[1], tostr(y), me, argargs[2], target) <));
                    } else {
                        rethrow(error());
                    }
                }
            }
            return out;
        case 'any:
            return str;
        case 'any_opt:
            args = $parse_lib.getopt(str, argargs);
            return args;
        case 'object:
            return (> me.match_environment(str) <);
        case 'object_opt:
            args = $parse_lib.getopt(str, argargs);
            if (!(args[1]))
                throw(~syntax, "No reference specified for command \"");
            obj = (> me.match_environment((args[1])[1]) <);
            return [obj, delete(args[1], 1), args[2]];
        case 'objref:
            return (> $parse_lib.ref(str, me) <);
        case 'objref_opt:
            args = $parse_lib.getopt(str, argargs);
            if (!(args[1]))
                throw(~syntax, "No reference specified for command \"");
            obj = (> $parse_lib.ref((args[1])[1], me) <);
            return [obj, delete(args[1], 1), args[2]];
        case 'user:
            if (!str)
                throw(~match, "No user specified.");
            if (str == "me")
                return me;
            return (| $user_db.search(str) |) || throw(~match, ("Unable to find user " + str) + ".");
        case 'user_opt:
            args = $parse_lib.getopt(str, argargs);
            if (!(args[1]))
                throw(~syntax, "Nobody specified for command \"");
            if (str == "me")
                return me;
            return [(> $user_db.search((args[1])[1]) <), args[2]];
        case 'number:
            return (> str.to_number() <);
        case 'number_opt:
            args = $parse_lib.getopt(str, argargs);
            if (!(args[1]))
                throw(~syntax, "No number specified for command \"");
            return [(> str.to_number() <), args[2]];
        case 'descendant:
            obj = (> me.match_environment(str) <);
            anc = argargs ? argargs[1] : user;
            if (!(obj.has_ancestor(anc)))
                throw(~parse, strfmt("You cannot %s %s because it is not %s!", cmd, obj.name(), anc.name()));
            return obj;
        case 'descendant_opt:
            args = $parse_lib.getopt(str, argargs);
            if (!(args[1]))
                throw(~syntax, "No descendant specified for command \"");
            obj = (> me.match_environment((args[1])[1]) <);
            anc = argargs ? argargs[1] : user;
            if (!(obj.has_ancestor(anc)))
                throw(~parse, strfmt("You cannot %s %s because it is not %s!", cmd, obj.name(), anc.name()));
            return [obj, args[2]];
        default:
            throw(~ack, ("Support for the type '" + type) + " is incomplete!");
    }
};


new object $editor_parser: $user_parsers;

var $root manager = $editor_parser;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root created_on = 820684599;
var $root inited = 1;
var $root managed = [$editor_parser];
var $root owned = [$editor_parser];
var $user_parsers priority = 250;
var $editor_parser commands = #[["ap?pend", 'append_cmd], ["a?fter", 'after_cmd], ["d?elete|e?rase", 'delete_cmd], ["done|quit", 'quit_cmd], ["f?ill|j?oin|w?rap", 'fill_cmd], ["h?elp", 'help_cmd], ["i?nsert", 'insert_cmd], ["line", 'line_cmd], ["l?ist|ls", 'list_cmd], ["m?ove|mv", 'move_cmd], ["save|comp?ile", 'save_cmd], ["store", 'store_cmd], ["sed|sub", 'subst_cmd], ["send|mail", 'send_cmd], ["c?opy|cp", 'copy_cmd]];
var $editor_parser command_help = #[['insert_cmd, ["Syntax: i?nsert [<text>] OR '<text>", "", "Add <text> before current line.  You may also use a single-quote (') as a shortcut character.  If text does not exist you will be prompted for the input."]], ['after_cmd, ["Syntax: a?fter [<text>] OR _<text>", "", "Add <text> after current line.  You may also use an underscore (_) as a shortcut character.  If text does not exist you will be prompted for the input."]], ['append_cmd, ["Syntax: ap?pend <text> OR ,<text>", "", "Add <text> after current line.  You may also use a comma (,) as a shortcut character."]], ['delete_cmd, ["Syntax: d?elete [<range>]", "", "Delete <range> or current line."]], ['copy_cmd, ["Syntax: copy [<range>] [to] <line>", "", "Copy <range> of text or current line to <line>."]], ['quit_cmd, ["Syntax: done|quit", "", "Close editor without saving changes."]], ['fill_cmd, ["Syntax: fill <range> <line width>", "", "Fill <range> of lines to fit within <line width> appropriately (either by expanding or joining)."]], ['help_cmd, ["Syntax: help [<command>]", "", "Basic editor help."]], ['line_cmd, ["Syntax: line <line>", "", "Change the current line to <line>.  You can also use a period (.) as a shortcut character."]], ['move_cmd, ["Syntax: move [<range>] [to] <line>", "", "Move <range> or current line to <line>."]], ['list_cmd, ["Syntax: list [<range>] [-n?umbers]", "", "List <range> or all of edit buffer.  The option -n?umbers may be used to not specify line numbers."]], ['subst_cmd, ["Syntax: s?ub|sed <old> <new> [<range>] [<options>]", "", "Search for <old> and replace it with <new> in <range> (defaulting to the current line).  The character following the command is used as a seperator (a space in the example).  This allows for the sed-like syntax: s/old/new/. The command 'sed' will use strsed() with regular expressions, the command 'sub' or 's' will use strsub() with literal matching.  Options are any one of:", "", "        g      Globally match and replace (do it multiple times)", "        s      Single match and replace (do it only on the first occurance)", "        c      Case matters when matching.", "        i      Case doesn't matter when matching.", "", "Option defaults for sed are: si", "Option defaults for sub are: gi"]], ['save_cmd, ["Syntax: save|comp?ile [as] [<ref>]", "", "Save document, if arguments are given will save alternate copy."]], ['store_cmd, ["Syntax: store", "", "Store editor--do not save changes.  Editor can be resumed with @reedit."]], ['send_cmd, ["Syntax: send|mail <mail-recipient>", "", "Used to send current contents of editor to a mail recipient."]]];
var $editor_parser shortcuts = #[["^'", 'insert_cmd], [",", 'append_cmd], ["_", 'after_cmd], [".", 'line_cmd]];

public method .parse() {
    arg u, str, next_parser, @other_parsers;
    var word, cmd, argstr, c, m;
    
    while (str && ((str[1]) == " "))
        str = str.subrange(2);
    if (!str)
        return next_parser.parse(u, str, @other_parsers);
    if ((str[1]) == ">")
        return next_parser.parse(u, str.subrange(2), @other_parsers);
    
    // special cased shortcuts
    for cmd in (shortcuts) {
        if ((str[1]) in (cmd[1]))
            return ['match, u.active_editor(), cmd[2], str[1], "", substr(str, 2)];
    }
    
    // handle standard commands
    // special case 'sub|sed/...'
    if ((word = regexp(str, "^(sed|sub|s)[^a-z]"))) {
        word = word[1];
        argstr = substr(str, strlen(word) + 1);
        return ['match, u.active_editor(), 'subst_cmd, word, "sed|sub", argstr];
    } else if ((word = (| str.word(1) |))) {
        if (" " in str)
            argstr = substr(str, (" " in str) + 1);
        else
            argstr = "";
        for cmd in (commands.keys()) {
            if ((m = match_template(word, cmd)))
                return ['match, u.active_editor(), commands[cmd], word, cmd, argstr];
        }
    }
    
    // didn't match, move on
    return next_parser.parse(u, str, @other_parsers);
};

public method .command_help() {
    return command_help;
    
    // $#Edited: 10 Dec 96 16:48 $brandon
};

public method .commands() {
    return commands;
    
    // $#Edited: 10 Dec 96 16:55 $brandon
};


new object $channel_parser: $user_parsers;

var $root manager = $channel_parser;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 838745026;
var $root inited = 1;
var $root managed = [$channel_parser];
var $root owned = [$channel_parser];
var $user_parsers priority = 5000;

public method .parse() {
    arg user, str, next_parser, @other_parsers;
    var cname, first_word, parse_list;
    
    str = str.trim();
    if (!str)
        return next_parser.parse(user, str, @other_parsers);
    parse_list = str.explode();
    first_word = parse_list[1];
    cname = user.channel_alias(first_word);
    if ((cname != "") && ((parse_list.length()) > 1))
        return ['command, user, 'broadcast, cname, str.subrange((first_word.length()) + 2)];
    return next_parser.parse(user, str, @other_parsers);
};


new object $eval_parser: $user_parsers;

var $root manager = $eval_parser;
var $root managed = [$eval_parser];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847137598;
var $user_parsers priority = 500;
var $root inited = 1;
var $root owned = [$eval_parser];

public method .parse() {
    arg u, str, next_parser, @other_parsers;
    var out, l, eval;
    
    if (("`" in str) && (!match_begin(str, ";"))) {
        str = strsub(str, "\`", "<#QUOTED-TICK#>");
        out = str.explode_delimited("`", "`");
        eval = out[2];
        str = "";
        for l in (out[1]) {
            if (type(l) == 'integer)
                str += (> .evaluate(u, eval[l]) <);
            else
                str += l;
        }
        str = strsub(str, "<#QUOTED-TICK#>", "`");
    }
    return next_parser.parse(u, str, @other_parsers);
};

public method .evaluate() {
    arg user, str;
    var ep, vars, v, reg, r;
    
    ep = user.eval_prefix();
    vars = (ep.keys()).join(", ");
    v = (ep.values()).join();
    if (match_begin(str, "var") && (reg = regexp(str, "var ([^;]+)"))) {
        str = strsed(str, "var ([^;]+);", "");
        str = ((((("var " + vars) + ", ") + (reg.join(","))) + ";") + v) + str;
    } else if ("return" in str) {
        str = ((("var " + vars) + ";") + v) + str;
    } else {
        str = strsed(str, " *;* *$", "");
        str = ((((("var " + vars) + ";") + v) + "return (> ") + str) + " <);";
    }
    r = (> user.evaluate(str, user, user) <);
    r = r[2];
    if ((r[1]) == 'errors)
        throw(~evalerr, "Eval error: " + (r[2]));
    return r[2];
    
    // $#Edited: 04 Nov 96 13:43 $brandon
};


new object $filters: $misc;

var $root child_index = 1;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root manager = $filters;
var $root owned = [$filters];
var $root managed = [$filters];

public method .compress() {
    arg input;
    var e, output;
    
    // only goes 1 element deep--sorry, anybody sending anything past that will
    // be shot.
    output = [];
    if (type(input) == 'list) {
        for e in (input) {
            if (type(e) == 'list)
                output += e;
            else
                output += [e];
        }
    } else {
        output = [input];
    }
    return output;
    
    // $#Edited: 30 Nov 96 21:22 $miro
};


new object $wrap_filter: $filters;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $wrap_filter;
var $root managed = [$wrap_filter];
var $root owned = [$wrap_filter];

public method .filter_text() {
    arg input;
    var len, output, e, line;
    
    return $string.wrap_line(input, sender().linelen());
};


new object $lock_parser: $misc;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root manager = $lock_parser;
var $lock_parser lock_types = [["inside", $inside_lock_frob], ["indirect", $indirect_lock_frob], ["owner", $owner_lock_frob], ["carry", $carry_lock_frob], ["parent", $parent_lock_frob]];
var $root owned = [$lock_parser];
var $root managed = [$lock_parser];

public method .parse() {
    arg s, env;
    var stack, lock, n, m, obj, type, i;
    
    stack = [];
    s = " " + s;
    s = strsed(s, "&([^&])", "&&%1", "g");
    s = strsed(s, "\|([^\|])", "||%1", "g");
    s = strsub(s, " or ", " || ");
    s = strsub(s, " and ", " && ");
    s = strsub(s, " not ", " !");
    while (1) {
        // Look for valid prefixes.
        while (1) {
            (s = s.trim()) || throw(~parse, "String ends unexpectedly.");
            if ((s[1]) == "(") {
                stack = ['open, @stack];
                s = s.subrange(2);
            } else if ((s[1]) == "!") {
                if (stack && ((stack[1]) == 'not))
                    stack = stack.subrange(2);
                else
                    stack = ['not, @stack];
                s = s.subrange(2);
            } else {
                break;
            }
        }
    
        // Look for an object name or tag
        m = regexp(s, "^([^)&|]+)(.*)");
        if (!m)
            throw(~parse, "Null object obj_name.");
        s = m[2];
        lock = (m[1]).trim();
        if (!lock)
            throw(~parse, "Null object obj_name.");
    
        // try and match it
        type = $object_lock_frob;
        for i in (lock_types) {
            if (lock.match_begin((i[1]) + ":")) {
                type = i[2];
                lock = lock.subrange(((i[1]).length()) + 2);
                break;
            }
        }
        if ((obj = (| env.match_environment(lock) |))) {
            lock = type.new_lock(obj);
        } else {
            switch (lock) {
                case "any", "true", "anybody", "yes":
                    lock = $true_lock_frob.new();
                case "none", "false", "nobody", "no":
                    lock = $false_lock_frob.new();
                default:
                    throw(~parse, ("Invalid lock tag \"" + lock) + "\"");
            }
        }
        stack = [lock, @stack];
    
        // Loop until no more reduction to be done.
        while (1) {
            // Process negations, ands, ors.
            while (1) {
                if ((stack.length()) < 2)
                    break;
                if ((stack[2]) == 'not)
                    stack = [$not_lock_frob.new_lock(stack[1]), @stack.subrange(3)];
                else if ((stack[2]) == 'and)
                    stack = [$and_lock_frob.new_lock(stack[1], stack[3]), @stack.subrange(4)];
                else if ((stack[2]) == 'or)
                    stack = [$or_lock_frob.new_lock(stack[1], stack[3]), @stack.subrange(4)];
                else
                    break;
            }
    
            // Close parens, if necessary; otherwise stop.
            if ((!s) || ((s[1]) != ")"))
                break;
            while (s && ((s[1]) == ")")) {
                if (((stack.length()) < 2) || ((stack[2]) != 'open))
                    throw(~parse, "Misplaced right parenthesis.");
                stack = [stack[1], @stack.subrange(3)];
                s = (s.subrange(2)).trim();
            }
        }
    
        // Are we done?
        if (!s) {
            if ((stack.length()) > 1)
                throw(~parse, "Unmatched left parentheses.");
            return stack[1];
        }
    
        // No, we're at a conjunction.
        if ((s[1]) == "&") {
            stack = ['and, @stack];
            s = s.subrange(3);
        } else if ((s[1]) == "|") {
            stack = ['or, @stack];
            s = s.subrange(3);
        } else {
            throw(~parse, "Illegal character following right parenthesis.");
        }
    }
};


new object $editor_session: $misc;

var $root manager = $editor_session;
var $root flags = ['methods, 'code, 'fertile, 'core, 'variables];
var $root created_on = 820684587;
var $root inited = 1;
var $root child_index = 1034;
var $editor_session finisher = 0;
var $editor_session sender = 0;
var $editor_session text = 0;
var $editor_session line = 0;
var $editor_session modified = 0;
var $editor_session client_data = 0;
var $editor_session finisher_object = 0;
var $root managed = [$editor_session];
var $root owned = [$editor_session];

public method .startup() {
    arg fin_object, finish_method, initial_text, cdata;
    
    (> .perms(sender()) <);
    if (type(initial_text) == 'string)
        initial_text = [initial_text];
    sender = sender();
    finisher = finish_method;
    finisher_object = fin_object;
    text = initial_text;
    line = 1;
    modified = 0;
    client_data = cdata;
    if ((| (sender().local_editor()) == 'mcp |)) {
        // Next time, when you have a clever idea about edit name, check
        // it for non-method editting sessions
        sender.tell([(("#$# edit name: " + (.session_name())) + " upload: @mcp-upload-session ") + (.name()), @text, "."]);
        text = 'mcp;
        sender.store_editor();
        return 0;
    } else {
        return 1;
    }
    
    // $#Edited: 29 Jan 97 06:46 $miro
};

public method .abort_cmd() {
    arg @args;
    
    (> .perms(caller(), 'command) <);
    sender.quit_editor();
    return "Aborted. Editor cleared.";
};

public method .insert_cmd() {
    arg cmd, tmpl, what;
    
    (> .perms(caller(), 'command) <);
    modified = 1;
    if (what || match_regexp(cmd, "^[^a-z]")) {
        text = insert(text, line, what);
        line++;
        return ("Line " + tostr(line - 1)) + " added.";
    } else {
        return .read_text(0, sender());
    }
};

public method .save_cmd() {
    arg cmd, tmpl, args;
    var err, m;
    
    (> .perms(caller(), $user, this()) <);
    if ((m = match_template(args, "as *")))
        return "Save as support is not yet completed.";
    if ((> (err = sender.do_save(finisher_object, finisher, text, client_data)) <) == 'clear) {
        sender.quit_editor();
        return "Done. Editor cleared.";
    }
    if (type(err) == 'list)
        return .compile_errors(@err);
    modified = 0;
    return "Save completed.";
};

public method .delete_cmd() {
    arg cmd, tmpl, what;
    var start, end, gone, foo, len;
    
    (> .perms(caller(), 'command) <);
    catch any
        start = ._parse_range(what);
    with
        return "Illegal range, can't delete.";
    [start, end] = start;
    len = end - start;
    gone = sublist(text, start, (end - start) || 1);
    text = sublist(text, 1, start - 1) + sublist(text, end + 1);
    modified = 1;
    line = start;
    return ((((((("Deleted " + ((end - start) + 1)) + " line") + ((end == start) ? "" : "s")) + " (\"") + ((gone[1]).chop(20))) + "\"), current line is ") + line) + ".";
};

public method .line_cmd() {
    arg cmd, tmpl, number;
    
    (> .perms(caller(), 'command) <);
    number = number.trim();
    number = (number == "$") ? text.length() : (number.to_number());
    if ((number < 1) || (number > ((text.length()) + 1)))
        return "Out if range.";
    else
        line = number;
    return ("Current line set to " + tostr(line)) + ".";
};

public method ._parse_range() {
    arg what, @allow;
    var start, end, range;
    
    if (what == "%")
        what = "1-$";
    what = strsub(what, "$", tostr(listlen(text)));
    what = strsub(what, ".", tostr(line));
    what = strsub(what, ",", "-");
    allow = allow ? 1 : 0;
    if (!what) {
        start = (end = line);
    } else {
        range = (> $parse_lib.range(what) <);
        start = range[1];
        if (start == 'specific)
            throw(~range, "Illegal range.");
        end = ((range[2]) == 'single) ? start : (range[2]);
    }
    if ((start < 1) || ((end > (listlen(text) + allow)) || (end < start)))
        throw(~range, "Illegal range.");
    return [start, end];
    
    // $#Edited: 20 Dec 96 23:12 $brandon
};

public method .help_cmd() {
    arg cmd, tmpl, what;
    var parse;
    
    what = what.trim();
    if (!what)
        return ["Editor commands (use 'help <cmd>' for detailed information):"] + (((($editor_parser.commands()).keys()).vcolumnize(3, (sender().linelen()) - 5)).prefix("    "));
    parse = $editor_parser.parse(sender(), what, $null_parser);
    if ((parse[1]) in ['ok, 'failed])
        return ("Unable to find editor command '" + what) + "'.";
    return ($editor_parser.command_help())[parse[3]];
};

public method .quit_cmd() {
    arg cmd, tmpl, @args;
    var ans;
    
    (> .perms(caller(), 'command) <);
    if (modified) {
        ans = sender.prompt("Discard changes? [yes] ");
        if (!(ans.is_boolean()))
            return "Ok.  Editor not cleared.";
    }
    sender.quit_editor();
    return "Done. Editor cleared.";
};

public method .fill_cmd() {
    arg cmd, tmpl, what;
    var start, end, width;
    
    (> .perms(caller(), 'command) <);
    what = what.explode();
    catch any
        start = ._parse_range(what[1]);
    with
        return "Illegal range, can't fill.";
    end = start[2];
    start = start[1];
    width = ((what.length()) > 1) ? (what[2]).to_number() : 75;
    text = ((text.subrange(1, start - 1)) + (((text.subrange(start, (end - start) + 1)).join(" ")).wrap_lines(width))) + (text.subrange(end + 1));
    modified = 1;
    line = start;
    return ("Fill completed. Current set to " + tostr(start)) + ".";
};

public method .subst_cmd() {
    arg cmd, tmpl, args;
    var start, end, opts, changed, sep, h, range;
    
    (> .perms(caller(), 'command) <);
    h = ($editor_parser.command_help())['subst_cmd];
    if (!args)
        return h;
    sep = args[1];
    args = substr(args, 2);
    args = explode(args, sep, 'keep_blanks);
    if ((!args) || (listlen(args) < 2))
        return h + ["", "! Invalid number of arguments."];
    if (text == [])
        return h + ["", "! There is no text to search and replace in."];
    if (listlen(args) > 2) {
        [opts, range] = (args[3]).regexp("([gsci]*)(.*)");
        if ((!range) && (listlen(args) > 3))
            range = args[3];
    } else {
        opts = "";
    }
    if (range) {
        catch any
            start = ._parse_range(range);
        with
            return h + ["", "! " + ((traceback()[1])[2])];
        [start, end] = start;
    } else {
        start = line;
        end = line;
    }
    if (cmd == "sed")
        changed = .sed(start, end, args[1], args[2], opts);
    else
        changed = .sub(start, end, args[1], args[2], opts);
    modified = changed;
    if (changed == 1)
        return changed + " line changed.";
    else if (changed > 1)
        return changed + " lines changed.";
    else
        return "No lines changed.";
    
    // $#Edited: 23 Dec 96 11:52 $brandon
};

public method .session_name() {
    // cruft this up at a later time
    switch (finisher) {
        case '_edit_method_callback:
            return ((("Method " + (client_data[1])) + ".") + (client_data[2])) + "()";
        case '_edit_messages_callback:
            return "Messages on " + (finisher_object.namef('ref));
        default:
            return "%l/%l".format(finisher_object.name(), finisher);
    }
    
    // $#Edited: 20 Feb 97 19:41 $miro
};

public method .is_resumable() {
    return type(text) != 'symbol;
};

public method .mcp_upload() {
    arg newtext;
    var err;
    
    (> .perms(sender()) <);
    if ((> (err = sender.do_save(finisher_object, finisher, newtext, client_data)) <) == 'clear) {
        sender.quit_editor();
        return "Done. Editor cleared.";
    }
    if (type(err) != 'list)
        modified = 0;
    return err ? err : "Save completed.";
};

public method .startup_sender(): nooverride {
    return sender;
};

public method .compile_errors() {
    arg @err;
    var m;
    
    if ((m = regexp(err[1], "Line ([0-9]+)"))) {
        line = toint(m[1]);
        return [.list_cmd("", "", m[1])] + err;
    }
    return err;
};

public method .list_cmd() {
    arg cmd, tmpl, rangestr;
    var start, end, out, i, j, k, l, lineno, rows;
    
    (> .perms(caller(), $user, definer()) <);
    if (text == [])
        return "There is no text.";
    rangestr = rangestr.trim();
    if (!rangestr) {
        l = text.length();
        rows = (sender().get_rows()) / 2;
        start = line - rows;
        end = line + rows;
        if (start < 1) {
            end = (end + 1) - start;
            if (end > l)
                end = l;
            start = 1;
        } else if (end > l) {
            start = (start - end) + l;
            end = l;
            if (start < 1)
                start = 1;
        }
        start = [start, end];
    } else {
        catch any
            start = ._parse_range(rangestr);
        with
            return "Illegal list range.";
    }
    end = start[2];
    start = start[1];
    out = [];
    j = start;
    for i in (text.subrange(start, (end - start) + 1)) {
        if (j == line)
            lineno = (("=>" + j).right(5)) + ": ";
        else
            lineno = (tostr(j).right(5)) + ": ";
        out += (lineno + i).wrap_lines(sender.linelen(), "         ");
        j++;
    }
    if (listlen(text) <= end) {
        if ((j == line) && (j == ((text.length()) + 1)))
            out += ["=>[End]"];
        else
            out += [" [End]"];
    }
    return out;
};

private method .read_text() {
    arg offset, sender;
    var newtext, start;
    
    if ((> (newtext = sender.read()) <)) {
        if (newtext == 'aborted)
            return;
        modified = 1;
        text = listgraft(text, line + offset, newtext);
        start = line + offset;
        line = (line + (newtext.length())) + offset;
        if (listlen(newtext) == 1)
            return ("Line " + start) + " added.";
        return ((("Lines " + start) + " to ") + (start + listlen(newtext))) + " added.";
    } else {
        return "Text unchanged.";
    }
};

public method .after_cmd() {
    arg cmd, tmpl, what;
    var offset;
    
    (> .perms(caller(), 'command) <);
    if (line > listlen(text))
        offset = line - listlen(text);
    if (what || match_regexp(cmd, "^[^a-z]")) {
        modified = 1;
        text = insert(text, (line + 1) - offset, what);
        line += 2 - offset;
        return ("Line " + (line - 1)) + " added.";
    } else {
        return .read_text(1 - offset, sender());
    }
};

public method .append_cmd() {
    arg cmd, tmpl, what;
    var offset;
    
    (> .perms(caller(), 'command) <);
    modified = 1;
    if (line > listlen(text)) {
        text += [what];
        return ("Line " + listlen(text)) + " added.";
    } else if (line == 1) {
        text = [line] + text;
        line = 2;
        return "Line 1 added.";
    } else {
        text = replace(text, line, (text[line]) + what);
        return ("Appended to line " + tostr(line)) + ".";
    }
};

public method .store_cmd() {
    arg cmd, tmpl, @args;
    
    (> .perms(caller(), 'command) <);
    return sender.store_editor();
};

public method .copy_cmd() {
    arg cmd, tmpl, args;
    var m, range, toline, copy, start, end;
    
    (> .perms(caller(), 'command) <);
    if ((m = match_template(args, "* to *")))
        [range, m, toline] = m;
    else if (listlen((m = explode(args))) > 1)
        [range, toline] = m;
    else
        toline = args;
    if (!toline)
        return "Copy to where?";
    toline = toint(toline);
    if ((toline < 1) || (toline > (listlen(text) + 1)))
        return ((("Line " + toline) + " is outside the possible range (1 .. ") + (listlen(text) + 1)) + ").";
    if (range) {
        if (!(range = (| ._parse_range(args, 'allow) |)))
            return "Illegal range, cannot copy.";
    } else if (line > listlen(text)) {
        return "Illegal range, cannot copy.";
    } else {
        range = [line, line];
    }
    [start, end] = range;
    copy = sublist(text, start, (end - start) + 1);
    text = listgraft(text, toline, copy);
    line = toline + listlen(copy);
    if (start == end)
        return ((("Line " + start) + " copied to line ") + toline) + ".";
    return ((((("Lines " + start) + " .. ") + end) + " copied to line ") + toline) + ".";
};

public method .move_cmd() {
    arg cmd, tmpl, args;
    var m, range, toline, move, start, end;
    
    (> .perms(caller(), 'command) <);
    if ((m = match_template(args, "* to *")))
        [range, m, toline] = m;
    else if (listlen((m = explode(args))) > 1)
        [range, toline] = m;
    else
        toline = args;
    if (!toline)
        return "Copy to where?";
    toline = (| ._parse_range(toline, 'allow) |);
    if ((!toline) || ((toline[1]) != (toline[2])))
        return "Invalid move destination reference.";
    toline = toline[1];
    if (range) {
        if (!(range = (| ._parse_range(args, 'allow) |)))
            return "Illegal range, cannot move.";
    } else if (line > listlen(text)) {
        return "Illegal range, cannot move.";
    } else {
        range = [line, line];
    }
    [start, end] = range;
    if ((toline == start) || ((toline == end) || ((toline > start) && (toline < end))))
        return "Source and destination lines conflict.";
    move = sublist(text, start, (end - start) + 1);
    if (toline > end) {
        text = listgraft(text, toline, move);
        text = sublist(text, 1, start - 1) + sublist(text, end + 1);
        line = toline;
    } else {
        text = sublist(text, 1, start - 1) + sublist(text, end + 1);
        text = listgraft(text, toline, move);
        line = toline + listlen(move);
    }
    if (start == end)
        return ((("Line " + start) + " moved to line ") + toline) + ".";
    return ((((("Lines " + start) + " .. ") + end) + " moved to line ") + toline) + ".";
};

public method .sed() {
    arg start, end, search, replace, opts;
    var x, line, changed;
    
    for x in [start .. end] {
        line = strsed(text[x], search, replace, opts);
        if (strcmp(line, text[x])) {
            text = replace(text, x, line);
            changed++;
        }
    }
    return changed;
};

public method .sub() {
    arg start, end, search, replace, opts;
    var x, line, changed, i;
    
    for x in [start .. end] {
        line = strsub(text[x], search, replace, opts);
        if (strcmp(line, text[x])) {
            text = replace(text, x, line);
            changed++;
        }
    }
    return changed;
};

public method .send_cmd() {
    arg cmd, tmpl, args;
    var err, m, list, recip, subj, mail;
    
    (> .perms(caller(), $user, this()) <);
    if ((m = match_template(args, "to *")))
        args = m[2];
    else
        args = args.trim('left);
    list = [];
    for recip in (args.explode_english_list()) {
        if (recip == "me") {
            list = setadd(list, sender());
        } else {
            catch ~listnf
                list = list.setadd((> $mail_lib.match_mail_recipient(recip) <));
            with
                sender().tell(("The recipient \"" + recip) + "\" is invalid.");
        }
    }
    if (!list)
        return "No recipients specified.";
    subj = sender().prompt("Subject: ");
    if (subj == "@abort")
        return "** Aborted mail send **";
    if (subj == 'engaged)
        return "** Already reading input - mail send aborted **";
    mail = $mail_message.new_mail();
    mail.set_subject(subj);
    mail.set_text(text);
    catch any
        mail.send(@list);
    with
        return (traceback()[1])[2];
    return "Mail sent.";
};

public method .cleanup_session() {
    (> .perms(sender()) <);
    if (type(text) == 'symbol)
        return 1;
    return !modified;
};


new object $weather_system: $misc;

var $root manager = $weather_system;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855309892;
var $root inited = 1;
var $root managed = [$weather_system];


new object $climate: $has_commands, $weather_system;

var $root manager = $climate;
var $root child_index = 3;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 839895133;
var $has_commands shortcuts = #[];
var $has_commands remote = #[["@list-climate", [["@list-climate", "*", "@list-climate <this>", 'show_cmd, #[[1, ['this, []]]]]]], ["@setup", [["@setup", "* seasons * daylengths *", "@setup <this> seasons <any> daylengths <any>", 'setup_cmd, #[[1, ['this, []]], [3, ['any, []]], [5, ['any, []]]]]]], ["@add-weather", [["@add-weather", "* type * prob?abilities *", "@add-weather <this> type <descendant of $weather> prob?abilities <any>", 'add_weather_cmd, #[[1, ['this, []]], [3, ['descendant, [$weather]]], [5, ['any, []]]]]]], ["@del-weather", [["@del-weather", "* type *", "@del-weather <this> type <descendant of $weather>", 'del_weather_cmd, #[[1, ['this, []]], [3, ['descendant, [$weather]]]]]]]];
var $has_commands local = #[];
var $root inited = 1;
var $climate seasons = 0;
var $climate weathers = 0;
var $root managed = [$climate];
var $root owned = [$climate];
var $climate daylengths = 0;
var $root help_node = $help_sys_climate;

public method .setup_cmd() {
    arg cmdstr, cmd, this, p, vals, p, dls;
    var s, line, attrs, att2, extras, ex2, i;
    
    (> .perms(sender()) <);
    seasons = vals.explode();
    daylengths = map i in (dls.explode()) to (toint(i));
    weathers = #[];
    return ("Seasons: " + (seasons.to_english())) + ". The weather list has been wiped.";
    
    // $#Edited: 08 Feb 97 21:36 $miro
};

public method .add_weather_cmd() {
    arg cmdstr, cmd, this, p1, weather, p2, probs;
    var i;
    
    (> .perms(sender()) <);
    probs = map i in (probs.explode()) to (toint(i));
    if ((probs.length()) != (seasons.length()))
        throw(~parse, "Wrong number of probabilities.");
    weathers = weathers.add(weather, probs);
    return ("Weather `" + (weather.name())) + "' added.";
    
    // $#Edited: 08 Feb 97 21:36 $miro
};

public method .del_weather_cmd() {
    arg cmdstr, cmd, this, p1, weather;
    var i;
    
    (> .perms(sender()) <);
    if (!(weathers.contains(weather)))
        return "That weather doesn't belong to this climate.";
    weathers = weathers.del(weather);
    return ("Weather `" + (weather.name())) + "' removed.";
    
    // $#Edited: 08 Feb 97 21:36 $miro
};

public method .show_cmd() {
    arg cmdstr, cmd, this;
    var out, x, i;
    
    return ((map i in (weathers) to ([(i[1]).name(), @i[2]]).transpose()).tabulate([["Weather type", "------------"], @map i in (seasons) to ([i, "".pad(i.length(), "-")])])) + ["---"];
    
    // $#Edited: 08 Feb 97 21:36 $miro
};

public method .advance() {
    arg current, season, dependancies;
    var dists, i, w, d, fuzz;
    
    fuzz = 10;
    dists = ._probabilities(current, season, fuzz);
    dists = dists.sort(dists.slice(2));
    for i in (dependancies) {
        d = (i[1]).get_setting("weather-time", $realm);
        dists += ((i[2]) * ((d[3])._probabilities(d[1], d[2], fuzz))) / 100;
    }
    w = random(10000);
    i = 1;
    d = 0;
    while ((i <= (dists.length())) && ((d += (dists[i])[2]) < w))
        i++;
    if (i > (dists.length()))
        i--;
    return (dists[i])[1];
};

public method ._probabilities() {
    arg from, season, fuzz;
    var i, j, attr, refattr, dists, sum, t;
    
    season = season in seasons;
    refattr = from.attributes();
    dists = map i in (weathers.keys()) to (refresh() && [i, (100 * ((weathers[i])[season])) / (fuzz + ((type((t = (| map j in [1 .. (attr = i.attributes()).length()] to (abs((attr[j]) - (refattr[j]))).sum() |))) == 'error) ? 1000000 : t))]);
    
    // normalize the list - the sum should be around 10,000
    sum = (dists.slice(2)).sum();
    return map i in (dists) to ([i[1], ((i[2]) * 10000) / sum]);
    
    // $#Edited: 07 Mar 97 15:28 $miro
};

public method .ctext_variables() {
    arg current, season;
    var vars;
    
    vars = #[["weather", current.name()], ["weather_desc", current.prose()], ["season", season]];
    vars = vars.union(current.attribute_vars());
    return vars;
    
    // $#Edited: 15 Feb 97 19:22 $miro
};

public method .daylength() {
    arg season;
    
    return daylengths[season in seasons];
    
    // $#Edited: 15 Feb 97 19:22 $miro
};

public method .match_weather() {
    arg weather_str;
    var i, out;
    
    if ((out = find i in (weathers.keys()) where ((i.name()) == weather_str)))
        return (weathers.keys())[out];
    if ((out = find i in (weathers.keys()) where (weather_str.match_begin(i.name()))))
        return (weathers.keys())[out];
    throw(~keynf, "No such weather in this climate.");
    
    // $#Edited: 19 Feb 97 03:39 $miro
};


new object $climate_taobh_thiar: $climate;

var $root manager = $climate_taobh_thiar;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 839896989;
var $climate seasons = ["spring", "summer", "fall", "winter"];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $root inited = 1;
var $climate daylengths = [0, 2, 0, -2];
var $climate weathers = #[[$weather_1, [50, 40, 20, 10]], [$weather_2, [30, 60, 10, 2]], [$weather_3, [10, 5, 10, 15]], [$weather_4, [0, 10, 0, 0]], [$weather_5, [30, 20, 60, 40]], [$weather_6, [10, 1, 10, 40]]];
var $root managed = [$climate_taobh_thiar];
var $root owned = [$climate_taobh_thiar];


new object $weather_attributes: $has_commands, $weather_system;

var $root manager = $weather_attributes;
var $weather_attributes attributes = #[["precipitation", ["fine", "drizzle", "rain", "shower", "snow"]], ["humidity", ["dry", "fine", "humid"]], ["temperature", ["hot", "warm", "cold", "freezing"]], ["visibility", ["clear", "hazy", "murky"]], ["clouds", ["clear", "cloudy", "overcast"]], ["wind", ["serene", "windy", "stormy"]]];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855309872;
var $has_commands shortcuts = #[];
var $has_commands remote = #[["@awa", [["@awa", "* values * to *", "@awa <any> values <any> to <this>", 'add_attrib_cmd, #[[1, ['any, []]], [3, ['any, []]], [5, ['this, []]]]]]], ["@dwa", [["@dwa", "* from *", "@dwa <any> from <this>", 'del_attrib_cmd, #[[1, ['any, []]], [3, ['this, []]]]]]], ["@lwa", [["@lwa", "*", "@lwa <this>", 'list_attribs_cmd, #[[1, ['this, []]]]]]], ["@aea", [["@aea", "* values * to *", "@aea <any> values <any> to <this>", 'add_extra_cmd, #[[1, ['any, []]], [3, ['any, []]], [5, ['this, []]]]]]], ["@add-weather-attribute", [["@add-weather-attribute", "* values * to *", "@add-weather-attribute <any> values <any> to <this>", 'add_attrib_cmd, #[[1, ['any, []]], [3, ['any, []]], [5, ['this, []]]]]]], ["@del-weather-attribute", [["@del-weather-attribute", "* from *", "@del-weather-attribute <any> from <this>", 'del_attrib_cmd, #[[1, ['any, []]], [3, ['this, []]]]]]], ["@list-weather-attributes", [["@list-weather-attributes", "*", "@list-weather-attributes <this>", 'list_attrib_cmd, #[[1, ['this, []]]]]]], ["@add-extra-attribute", [["@add-extra-attribute", "* values * to *", "@add-extra-attribute <any> values <any> to <this>", 'add_extra_cmd, #[[1, ['any, []]], [3, ['any, []]], [5, ['this, []]]]]]]];
var $has_commands local = #[];
var $root inited = 1;
var $weather_attributes extra_attributes = #[];
var $root help_node = $help_sys_weather_attributes;
var $root managed = [$weather_attributes];

public method .add_attrib_cmd() {
    arg cmdstr, cmd, name, p1, vals, p2, p3;
    
    (> .perms(sender()) <);
    vals = (vals.explode(";")).mmap('trim);
    attributes = (attributes || #[]).add(name, vals);
    return ("Defined attributes: " + ((attributes.keys()).to_english())) + ".";
    
    // $#Edited: 07 Feb 97 04:03 $miro
};

public method .list_attribs_cmd() {
    arg @who_cares;
    var i, a1, a2;
    
    a1 = attributes ? map i in (attributes) to ("@awa %l values %l to %l".format(i[1], (i[2]).join(";"), definer())) : [];
    a2 = extra_attributes ? map i in (extra_attributes) to ("@aea %l values %l to %l".format(i[1], (i[2]).join(";"), definer())) : [];
    return ["Weather attributes:", @a1, @a2, "---"];
    
    // $#Edited: 07 Feb 97 04:03 $miro
};

public method .add_extra_cmd() {
    arg cmdstr, cmd, name, p1, vals, p2, p3;
    
    (> .perms(sender()) <);
    vals = (vals.explode(";")).mmap('trim);
    extra_attributes = (extra_attributes || #[]).add(name, vals);
    return ("Defined extra attributes: " + ((extra_attributes.keys()).to_english())) + ".";
    
    // $#Edited: 07 Feb 97 04:03 $miro
};

public method .del_attrib_cmd() {
    arg cmdstr, cmd, name, @rest;
    
    (> .perms(sender()) <);
    if ((| attributes.contains(name) |)) {
        attributes = attributes.del(name);
        return ("Attribute " + name) + " deleted.";
    } else if ((| extra_attributes.contains(name) |)) {
        extra_attributes = extra_attributes.del(name);
        return ("Extra attribute " + name) + " deleted.";
    } else {
        return name + " not found.";
    }
    
    // $#Edited: 07 Feb 97 04:03 $miro
};

public method .alist_dict() {
    arg attrlist;
    var i, k, v;
    
    k = attributes.keys();
    v = attributes.values();
    return hash i in [1 .. attrlist.length()] to ([k[i], (v[i])[attrlist[i]]]);
    
    // $#Edited: 08 Feb 97 17:42 $miro
};

public method .parse_attribute_list() {
    arg attrlist;
    var i, alist, akeys, out, m, key, val;
    
    alist = (attrlist.explode(";")).mmap('trim);
    akeys = attributes.keys();
    if (!("=" in attrlist)) {
        if ((alist.length()) != (akeys.length()))
            throw(~parse, "Can't parse those weather attributes.");
        alist = ([akeys, alist].transpose()).mmap('join, "=");
    }
    out = #[];
    for i in (alist) {
        if (!(m = i.match_pattern("*=*")))
            throw(~parse, "Entry not of the form attribute=value.");
        key = ((m[1]) in akeys) || find i in [1 .. akeys.length()] where ((akeys[i]).match_begin(m[1]));
        if (!key)
            throw(~parse, "No such attribute.");
        if (!(val = (m[2]) in (attributes[akeys[key]])))
            throw(~parse, "Illegal value for %l:%l.".format(akeys[key], m[2]));
        out = out.add(akeys[key], val);
    }
    if (!(((out.keys()).length()) == (akeys.length())))
        throw(~parse, "Missing attributes.");
    return map i in (akeys) to (out[i]);
    
    // $#Edited: 08 Feb 97 17:42 $miro
};

public method .extra_attributes() {
    return extra_attributes;
    
    // $#Edited: 15 Feb 97 18:45 $miro
};


new object $weather: $described, $weather_system;

var $root manager = $weather;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855309306;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['uniq, "Generic Weather", "the Generic Weather"];
var $described prose = [];
var $root inited = 1;
var $root child_index = 6;
var $foundation defined_msgs = #[["invoke", #[['branches, ["general"]]]]];
var $foundation msgs = #[["invoke", #[["general", <$ctext_frob, [["The weather has changed to ", <$generator, ["weather", [], [], 'gen_weather]>, "."], #[['this, $weather]]]>]]]];
var $root help_node = $help_sys_weather;
var $root defined_settings = #[["attributes", #[['parse, ['parse_setting_attributes]], ['format, ['format_setting_attributes]]]]];
var $root managed = [$weather];

public method .attributes() {
    return .get_setting("attributes", $weather);
};

public method .attribute_vars() {
    var i, attr, extra, a;
    
    a = .attributes();
    attr = $weather_attributes.alist_dict(a);
    extra = hash i in ($weather_attributes.extra_attributes()) to ([i[1], (i[2])[(> .(tosym(i[1]))(a) <)]]);
    return attr.union(extra);
    
    // $#Edited: 15 Feb 97 19:22 $miro
};

public method .parse_setting_attributes() {
    arg value;
    
    if (type(value) == 'list)
        value = (value.join()).trim();
    return (> $weather_attributes.parse_attribute_list(value) <);
};

public method .format_setting_attributes() {
    arg value;
    var i;
    
    return map i in ($weather_attributes.alist_dict(value)) to (((i[1]) + "=") + (i[2])).join("; ");
};


new object $weather_1: $weather;

var $root manager = $weather_1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855447987;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "nice", "nice"];
var $described prose = <$ctext_frob, [["The weather is nice. The sun is shining and all that."], #[['this, $weather_1]]]>;
var $root inited = 1;
var $root settings = #[["attributes", [1, 2, 2, 1, 1, 1]]];
var $root managed = [$weather_1];


new object $weather_2: $weather;

var $root manager = $weather_2;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855462673;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "hot", "hot"];
var $described prose = [];
var $root inited = 1;
var $root settings = #[["attributes", [1, 1, 1, 2, 1, 1]]];
var $root managed = [$weather_2];


new object $weather_3: $weather;

var $root manager = $weather_3;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855462710;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "stormy", "stormy"];
var $described prose = [];
var $root inited = 1;
var $root settings = #[["attributes", [4, 3, 4, 3, 3, 3]]];
var $root managed = [$weather_3];


new object $weather_4: $weather;

var $root manager = $weather_4;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855462768;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "stormy", "stormy"];
var $described prose = [];
var $root inited = 1;
var $root settings = #[["attributes", [4, 3, 2, 3, 3, 3]]];
var $root managed = [$weather_4];


new object $weather_5: $weather;

var $root manager = $weather_5;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855463377;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "rainy", "rainy"];
var $described prose = [];
var $root inited = 1;
var $foundation msgs = #[["invoke", #[["general", <$ctext_frob, [["It starts to rain."], #[['this, $weather_5]]]>]]]];
var $root settings = #[["attributes", [3, 3, 3, 3, 3, 1]]];
var $root managed = [$weather_5];


new object $weather_6: $weather;

var $root manager = $weather_6;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 855463379;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[];
var $has_name name = ['prop, "snowy", "snowy"];
var $described prose = [];
var $root inited = 1;
var $root settings = #[["attributes", [5, 2, 4, 2, 3, 1]]];
var $root managed = [$weather_6];


new object $symbol: $libraries;

var $root manager = $symbol;
var $root created_on = 811822782;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root managed = [$symbol];
var $root owned = [$symbol];

public method .to_string() {
    arg sym;
    
    return tostr(sym);
};


new object $math: $libraries;

var $root manager = $math;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 845760297;
var $root inited = 1;
var $math pi = 3.14159;
var $math pi2 = 6.28318;
var $math origin_2d = [0.0, 0.0];
var $math origin_3d = [0.0, 0.0, 0.0];
var $math transmat_2d = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]];
var $math transmat_3d = [[1.0, 0.0, 0.0, 0.0], [0.0, 1.0, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0]];
var $root managed = [$math];
var $root owned = [$math];

public method .minor(): native;

public method .major(): native;

public method .add(): native;

public method .sub(): native;

public method .dot(): native;

public method .distance(): native;

public method .cross(): native;

public method .scale(): native;

public method .is_lower(): native;

public method .transpose(): native;

public method .polar_rectangular() {
    arg coords;
    
    return [(coords[1]) * cos(coords[2]), (coords[1]) * sin(coords[2])];
    
    // $#Edited: 24 Oct 96 14:03 $miro
};

public method .rectangular_polar() {
    arg coords;
    var a;
    
    a = atan2(coords[2], coords[1]);
    if (a < 0)
        a += pi2;
    return [.distance(coords, origin_2d), a];
    
    // $#Edited: 24 Oct 96 14:03 $miro
};

public method .pi() {
    return pi;
    
    // $#Edited: 24 Oct 96 14:03 $miro
};

public method .pi2() {
    return pi2;
    
    // $#Edited: 24 Oct 96 14:03 $miro
};

public method .deg_rad() {
    arg angle;
    
    return angle / 57.2958;
    
    // $#Edited: 24 Oct 96 14:03 $miro
};

public method .rad_deg() {
    arg angle;
    
    return angle * 57.2958;
    
    // $#Edited: 24 Oct 96 14:03 $miro
};

public method .matrix_add() {
    arg m1, m2;
    var i;
    
    return map i in [1 .. m1.length()] to (.add(m1[i], m2[i]));
    
    // $#Edited: 24 Oct 96 14:03 $miro
};

public method .matrix_sub() {
    arg m1, m2;
    var i;
    
    return map i in [1 .. m2.length()] to (.sub(m1[i], m2[i]));
};

public method .matrix_mul() {
    arg m1, m2;
    var x, y;
    
    m2 = .transpose(m2);
    return map x in (m1) to (map y in (m2) to (.dot(x, y)));
    
    // $#Edited: 24 Oct 96 14:03 $miro
};

public method .spherical_rectangular() {
    arg coords;
    var r, phi, theta, r1;
    
    r = coords[1];
    phi = coords[2];
    theta = coords[3];
    r1 = r * cos(theta);
    return [r1 * cos(phi), r1 * sin(phi), r * sin(theta)];
    
    // $#Edited: 24 Oct 96 14:03 $miro
};

public method .rectangular_spherical() {
    arg coords;
    var a, d;
    
    a = atan2(coords[2], coords[1]);
    if (a < 0)
        a += pi2;
    return [(d = .distance(coords, origin_3d)), a, atan2(coords[3], .distance(coords.subrange(1, 2), origin_2d))];
    
    // $#Edited: 24 Oct 96 14:04 $miro
};

public method .ident_mat() {
    arg n;
    var x, y;
    
    return map x in [1 .. n] to (map y in [1 .. n] to ((x == y) ? 1.0 : 0.0));
    
    // $#Edited: 24 Oct 96 14:04 $miro
};

public method .translation_mat() {
    arg vector;
    var x, y;
    
    if ((vector.length()) == 2)
        return transmat_2d + [vector + [1.0]];
    else
        return transmat_3d + [vector + [1.0]];
    
    // $#Edited: 24 Oct 96 14:04 $miro
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .rectangular_cylindrical() {
    arg coords;
    var a;
    
    a = atan2(coords[2], coords[1]);
    if (a < 0)
        a += pi2;
    return [.distance(coords, origin_2d), a, coords[3]];
    
    // $#Edited: 24 Oct 96 14:04 $miro
};

public method .cylindrical_rectangular() {
    arg coords;
    
    return [(coords[1]) * cos(coords[2]), (coords[1]) * sin(coords[2]), coords[3]];
    
    // $#Edited: 24 Oct 96 14:04 $miro
};

public method .matrix_scale() {
    arg s, m;
    var x;
    
    return map x in (m) to (.scale(s, x));
    
    // $#Edited: 24 Oct 96 14:04 $miro
};

public method .tensor() {
    arg v1, v2;
    var x, y;
    
    return map x in (v1) to (map y in (v2) to (x * y));
    
    // $#Edited: 24 Oct 96 14:04 $miro
};

public method .skew() {
    arg v;
    
    return [[0.0, v[3], -(v[2])], [-(v[3]), 0.0, v[1]], [v[2], -(v[1]), 0.0]];
    
    // $#Edited: 24 Oct 96 14:04 $miro
};

public method .rotation_mat_3d() {
    arg axis, angle;
    var s, c, m, tens;
    
    s = sin(angle);
    c = cos(angle);
    if (type(axis) == 'list) {
        axis = .scale(1.0 / (.distance(axis, origin_3d)), axis);
        tens = .tensor(axis, axis);
        m = .matrix_add(tens, .matrix_add(.matrix_scale(s, .skew(axis)), .matrix_scale(c, .matrix_sub(.ident_mat(3), tens))));
        return [[@m[1], 0.0], [@m[2], 0.0], [@m[3], 0.0], [0.0, 0.0, 0.0, 1.0]];
    } else {
        switch (axis) {
            case 'z:
                return [[c, s, 0.0, 0.0], [-s, c, 0.0, 0.0], [0.0, 0.0, 1.0, 0.0], [0.0, 0.0, 0.0, 1.0]];
            case 'y:
                return [[c, 0.0, -s, 0.0], [0.0, 1.0, 0.0, 0.0], [s, 0.0, c, 0.0], [0.0, 0.0, 0.0, 1.0]];
            case 'x:
                return [[1.0, 0.0, 0.0, 0.0], [0.0, c, s, 0.0], [0.0, -s, c, 0.0], [0.0, 0.0, 0.0, 1.0]];
        }
    }
    
    // $#Edited: 24 Oct 96 14:04 $miro
};

public method .transform_vect() {
    arg m, v;
    var x, outvect, flag;
    
    if ((m.length()) == ((v.length()) + 1)) {
        v += [1.0];
        flag = 1;
    }
    outvect = map x in (m) to (.dot(x, v));
    return flag ? outvect.subrange(1, (outvect.length()) - 1) : outvect;
    
    // $#Edited: 24 Oct 96 14:04 $miro
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .rotation_mat_2d() {
    arg angle;
    var s, c;
    
    s = sin(angle);
    c = cos(angle);
    return [[c, s, 0.0], [-s, c, 0.0], [0.0, 0.0, 1.0]];
    
    // $#Edited: 24 Oct 96 14:04 $miro
};

public method .scale_mat() {
    arg scale;
    
    if ((scale.length()) == 2)
        return [[scale[1], 0.0, 0.0], [0, scale[2], 0.0], [0.0, 0.0, 1.0]];
    else
        return [[scale[1], 0.0, 0.0, 0.0], [0.0, scale[2], 0.0, 0.0], [0.0, 0.0, scale[3], 0.0], [0.0, 0.0, 0.0, 1]];
    
    // $#Edited: 24 Oct 96 14:04 $miro
};

public method .runge() {
    arg x, y, h, f;
    var k1, k2, k3, k4, s;
    
    // returns the next timestep for differential equation y'=f(x,y)
    s = sender();
    k1 = s.f(x, y);
    k2 = s.f(x + (0.5 * h), .add(y, .scale(0.5 * h, k1)));
    k3 = s.f(x + (0.5 * h), .add(y, .scale(0.5 * h, k2)));
    k4 = s.f(x + h, .add(y, .scale(h, k3)));
    return .add(y, .scale(h / 6.0, .add(.add(k1, .scale(2.0, .add(k2, k3))), k4)));
    
    // $#Edited: 18 Dec 96 23:12 $miro
};


new object $english_lib: $libraries;

var $root manager = $english_lib;
var $english_lib alphabet = "abcdefghijklmnopqrstuvwxyz";
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847697242;
var $english_lib capitalize_exceptions = ["the", "a", "an", "and", "for", "but", "or", "nor", "of", "with", "using", "at", "to", "in", "into", "on", "onto", "upon", "out", "from", "over", "under", "through", "underneath", "beneath", "behind", "beside", "about", "as", "off"];
var $root inited = 1;
var $english_lib vowel_exceptions = "usu|uke|uvu|use|UPI|unit|univ|unic|uniq|unix|eur|uu|ubiq|union|one|once|uti|unif";
var $english_lib nonvowel_exceptions = "historic|ydu|honor|honest|habitual|heir|RPG";
var $english_lib noun_exceptions = #[["child", "children"], ["deer", "deer"], ["moose", "moose"], ["mouse", "mice"]];
var $english_lib letter_names = ["ay", "bee", "see", "dee", "ee", "eff", "jee", "aitch", "eye", "jay", "kay", "el", "em", "en", "oh", "pee", "queue", "ar", "es", "tee", "you", "vee", "double-you", "ex", "why", "zee"];
var $english_lib cardinal_directions = ["north", "northeast", "east", "southeast", "south", "southwest", "west", "northwest"];
var $english_lib verb_exceptions = #[["has", "have"], ["is", "are"], ["was", "were"], ["'s", "'ve"], ["can", "can"], ["collapses", "collapse"]];
var $english_lib cardinal_direction_opposites = ["south", "southwest", "west", "northwest", "northeast", "east", "southeast"];
var $english_lib selector_words = ["all", "everything", "everyone", "everybody"];
var $root managed = [$english_lib];

public method .titleize() {
    arg string;
    var words;
    
    words = string.explode();
    if ((words.length()) < 2) {
        if (words)
            return string.capitalize();
        else
            return string;
    }
    return [(words[1]).capitalize(), @(words.subrange(2, (words.length()) - 2)).lmap('capitalize), (words[words.length()]).capitalize()].join();
    
    // $#Edited: 11 Nov 96 00:27 $brian
};

public method .capitalize() {
    arg str;
    var m, word;
    
    // capitalize the first character of the first alphanumeric word found,
    // if it is not in the exceptions list.  Example:
    //
    //    $english_lib.capitalize(" @foo") => " @Foo"
    //
    if (!(m = match_regexp(str, "[a-z0-9]+")))
        return str;
    word = (regexp(str, "[a-z0-9]+")[1]).capitalize();
    anticipate_assignment();
    return strsed(str, "[a-z0-9]+", word);
};

public method ._noun_singular() {
    arg string;
    var k;
    
    anticipate_assignment();
    if ((k = string in (noun_exceptions.values())))
        return (noun_exceptions.keys())[k];
    return ._remove_s(string);
};

public method ._noun_plural() {
    arg string;
    var k;
    
    anticipate_assignment();
    string = strsed(string, "^(a|an) +", "");
    if ((k = (| noun_exceptions[string] |)))
        return k;
    return ._add_s(string);
};

public method .vowel_exception() {
    arg word;
    var prefix;
    
    return match_regexp(word, vowel_exceptions) ? 1 : 0;
};

public method .nonvowel_exception() {
    arg word;
    var prefix;
    
    return match_regexp(word, nonvowel_exceptions) ? 1 : 0;
};

public method .indef_article() {
    arg word;
    
    if ((((word[1]) in "aeiou") && (!(.vowel_exception(word)))) || (.nonvowel_exception(word)))
        return "an";
    else
        return "a";
};

public method .get_conjugation() {
    arg spec, @plural;
    var i, vb;
    
    i = "/" in (spec + "/");
    if (plural) {
        if (i < (spec.length()))
            vb = spec.subrange(i + 1);
        else
            vb = ._verb_plural(spec);
    } else if (i > 1) {
        vb = spec.subrange(1, i - 1);
    } else {
        vb = ._verb_singular(spec.subrange(2));
    }
    if (strcmp("a", (i == 1) ? spec[2] : spec) > 0)
        return vb.capitalize();
    else
        return vb;
};

public method .get_noun() {
    arg spec, @plural;
    var i, vb;
    
    i = "/" in (spec + "/");
    if (plural && (plural[1])) {
        if (i < (spec.length()))
            vb = spec.subrange(i + 1);
        else
            vb = ._noun_plural(spec);
    } else if (i > 1) {
        vb = spec.subrange(1, i - 1);
    } else {
        vb = ._noun_singular(spec.subrange(2));
    }
    
    // just pass to $string.capitalize()?
    if (strcmp("a", (i == 1) ? spec[2] : spec) > 0)
        return vb.capitalize();
    else
        return vb;
};

public method ._verb_singular() {
    arg string;
    var len, a;
    
    len = string.length();
    if ((len > 2) && match_regexp(string, "n't *$"))
        return (._verb_singular(string.subrange(1, len - 3))) + "n't";
    else if ((a = string in (verb_exceptions.values())))
        return (verb_excetions.keys())[a];
    return ._add_s(string, len);
};

public method ._verb_plural() {
    arg string;
    var len, a;
    
    len = string.length();
    if ((len > 2) && match_regexp(string, "n't *$"))
        return (._verb_plural(string.subrange(1, len - 3))) + "n't";
    else if ((a = (| verb_exceptions[string] |)))
        return a;
    return ._remove_s(string);
};

public method ._add_s() {
    arg str;
    var len;
    
    len = strlen(str);
    if (len < 2)
        return str + "s";
    if (((str[len]) == "y") && (!((str[len - 1]) in "aeiou")))
        return substr(str, 1, len - 1) + "ies";
    else if (((((str[len]) == "o") && (!((str[len - 1]) in "aeiouy"))) || ((str[len]) in "sx")) || ((len > 1) && ((substr(str, len - 1, 2) in "chsh") % 2)))
        return str + "es";
    else
        return str + "s";
};

public method ._remove_s() {
    arg str;
    var len;
    
    len = strlen(str);
    if ((len <= 3) || ((str[len]) != "s"))
        return str;
    else if ((str[len - 1]) != "e")
        return substr(str, 1, len - 1);
    else if (((((str[len - 2]) == "h") && ((str[len - 3]) in "cs")) || ((str[len - 2]) in "ox")) || (((str[len - 2]) == "s") && (!((str[len - 3]) in "aeiouy"))))
        return substr(str, 1, len - 2);
    else if ((str[len - 2]) == "i")
        return substr(str, 1, len - 3) + "y";
    else
        return substr(str, 1, len - 1);
};

public method .selector_words() {
    return selector_words;
};

public method .selector_word_default() {
    arg word, place;
    var tmp, item;
    
    if (word in ["everyone", "everybody"])
        return (place.contents()).mfilter('has_ancestor, $body);
    else
        return ((word in selector_words) && [get_var(tosym(word))]) || [];
};

public method .def_article() {
    arg string;
    
    // For completeness sake
    return "the";
};

public method .compress_names() {
    arg names, @args;
    var c, x, n, ret;
    
    if (names == (c = names.compress()))
        return names.to_english(@args);
    ret = [];
    for x in (c) {
        if ((n = names.count(x)) > 1)
            ret += [((n.to_english_text()) + " ") + (._noun_plural(x.strip_article()))];
        else
            ret += [x];
    }
    return ret.to_english(@args);
};


new object $time: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $time months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var $time days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var $root manager = $time;
var $root managed = [$time];
var $root owned = [$time];
var $time time_units = [[31536000, "year", "years", "yr", "yrs"], [2592000, "month", "months", "mo", "mos"], [604800, "week", "weeks", "wk", "wks"], [86400, "day", "days", "dy", "dys"], [3600, "hour", "hours", "hr", "hrs"], [60, "minute", "minutes", "min", "mins"], [1, "second", "seconds", "sec", "secs"]];

public method .format(): native;

public method .elapsed() {
    arg time, @flag;
    var str, t, p;
    
    // compares args[1] with time() and returns hh:mm elapsed
    // will eventually make flags do things like 'long etc.  For now its
    // just your own time, rather than time().
    [(flag ?= 'stopwatch)] = flag;
    str = "";
    switch (flag) {
        case 'long:
            return .to_english(time);
        default:
            if (time > 356400)
                p = 3;
            else
                p = 2;
            return strfmt("%2{0}r:%2{0}r:%2{0}r", time / 3600, (time % 3600) / 60, time % 60);
    }
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .dhms() {
    arg secs, @long;
    var ret_str, x;
    
    if (long)
        long = 1;
    if (secs > 86400) {
        x = secs / 86400;
        ret_str = x + (long ? " day" + ((x < 2) ? "" : "s") : "d");
    } else if (secs > 3600) {
        x = secs / 3600;
        ret_str = x + (long ? " hr" + ((x < 2) ? "" : "s") : "h");
    } else if (secs > 60) {
        x = secs / 60;
        ret_str = x + (long ? " min" + ((x < 2) ? "" : "s") : "m");
    } else {
        ret_str = secs + (long ? " sec" + ((secs < 2) ? "" : "s") : "s");
    }
    return ret_str;
};

public method .from_english() {
    arg string;
    
    return $world_time.from_english(string, time_units);
};

public method .to_english() {
    arg time, @reftime;
    var times, words, x, ctime, mnths, month, year, days, out, lt, rrk;
    
    // most of this was stolen from MOO (und ve are evil)
    if (time < 1)
        return "0 seconds";
    reftime = reftime || time();
    words = ["year", "month", "day", "hour", "minute", "second"];
    times = [];
    for x in ([60, 60, 24]) {
        times = [time % x, @times];
        time = time / x;
    }
    mnths = 0;
    lt = localtime(reftime);
    month = lt[6];
    if ((lt[7]) < 100)
        year = 1900 + (lt[7]);
    else
        year = lt[7];
    days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
    while (time >= (days + ((month == 2) && (((year % 4) == 0) && (!((year % 400) in [100, 200, 300])))))) {
        time -= days;
        mnths++;
        month++;
        if (month > 12) {
            year++;
            month = 1;
        }
    }
    times = [mnths / 12, mnths % 12, time, @times];
    out = [];
    for x in [1 .. 6] {
        if ((times[x]) > 0)
            out += [(((times[x]) + " ") + (words[x])) + (((times[x]) == 1) ? "" : "s")];
    }
    return out.to_english();
};


new object $world_time: $libraries;

var $root manager = $world_time;
var $world_time speedup = 1;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848446570;
var $world_time time_units = [[31536000, "year", "years", "yr", "yrs"], [2592000, "month", "months", "mo", "mos"], [604800, "week", "weeks", "wk", "wks"], [86400, "day", "days", "dy", "dys"], [3600, "hour", "hours", "hr", "hrs"], [60, "minute", "minutes", "min", "mins"], [1, "second", "seconds", "sec", "secs"]];
var $root inited = 1;
var $world_time zone_offset = 0;
var $world_time start_time = 0;
var $root managed = [$world_time];

public method .from_english() {
    arg string, @units;
    var words, len, nsec, n, i, entry, unit;
    
    [(units ?= time_units)] = units;
    words = string.explode();
    words = words.setremove_all(["and"]);
    len = words.length();
    if (len % 2)
        throw(~args, "Invalid time.");
    nsec = (n = 0);
    for i in [1 .. len] {
        if ((i % 2) == 1) {
            if ((words[i]).is_numeric())
                n = (words[i]).to_number();
            else if ((words[i]) in ["a", "an"])
                n = 1;
            else if ((words[i]) == "no")
                n = 0;
            else
                throw(~invarg, "Invalid time.");
        } else {
            unit = words[i];
            unit = unit.strip(",");
            nsec += (> (units[.parse_unit(unit, units)])[1] <) * n;
        }
    }
    return nsec;
    
    // $#Edited: 06 Mar 97 08:27 $miro
};

public method .local_time() {
    return (time() - start_time) * speedup;
    
    // $#Edited: 19 Nov 96 18:40 $miro
};

public method .daytime() {
    arg zone, dayscale;
    var t, t1, t2;
    
    t = (((.local_time()) / 3600) + zone) % 24;
    t1 = 6 - dayscale;
    t2 = 18 + dayscale;
    switch (t) {
        case 0 .. 2:
            return [t, 'night, 'night];
        case 3 .. t1 - 1:
            return [t, 'predawn, 'night];
        case t1:
            return [t, 'dawn, 'day];
        case t1 + 1 .. 11:
            return [t, 'morning, 'day];
        case 12:
            return [t, 'noon, 'day];
        case 13 .. t2 - 1:
            return [t, 'afternoon, 'day];
        case t2:
            return [t, 'sunset, 'day];
        case t2 + 1 .. 22:
            return [t, 'evening, 'night];
        case 23:
            return [t, 'night, 'night];
    }
    
    // $#Edited: 22 Dec 96 15:49 $miro
};

public method .time_units() {
    return time_units;
    
    // $#Edited: 19 Nov 96 18:50 $brandon
};

public method .parse_unit() {
    arg unit, @units;
    var i;
    
    [(units ?= time_units)] = units;
    return find i in [1 .. units.length()] where (unit in ((units[i]).subrange(2))) || throw(~invarg, "Invalid time.");
    
    // $#Edited: 06 Mar 97 08:27 $miro
};

public method .from_unit_list() {
    arg time, ulist;
    var t, s, i;
    
    s = [];
    for i in (ulist) {
        t = time / ((time_units[i])[1]);
        if (t)
            s += [((t + " ") + ((time_units[i])[2])) + (t ? "s" : "")];
        time = time % ((time_units[i])[1]);
    }
    return s.to_english();
    
    // $#Edited: 06 Mar 97 08:27 $miro
};


new object $graph: $libraries;

var $root manager = $graph;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848800783;
var $root inited = 1;
var $root managed = [$graph];

public method .breadth_search() {
    arg node, data, neighbors, is_dest;
    var d, i, j, path;
    
    d = #[[node, 'source]];
    i = 1;
    while ((i <= ((d.keys()).length())) && (!(node = (d.keys())[i++]).(is_dest)(data))) {
        refresh();
        for j in (node.(neighbors)())
            d = d.add(j, node);
    }
    if (i <= ((d.keys()).length())) {
        refresh();
        path = [node];
        while ((node = d[node]) != 'source)
            path += [node];
        return path;
    } else {
        return 0;
    }
    
    // $#Edited: 23 Nov 96 19:20 $miro
};

public method .topological_sort() {
    arg list, comparator;
    var i, j;
    
    i = list.length();
    while (i >= 1) {
        j = 2;
        while (j <= i) {
            if ((list[j - 1]).(comparator)(list[j]))
                list = list.swap(j - 1, j);
            refresh();
            j++;
        }
        i--;
    }
    return list;
    
    // $#Edited: 14 Mar 97 21:14 $user_bruce
};


new object $heap: $libraries;

var $root manager = $heap;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848818545;
var $root inited = 1;
var $root managed = [$heap];
var $root help_node = $help_heap;

public method .push() {
    arg heap, element, priority_ind;
    var i, j;
    
    i = listlen(heap) + 1;
    if (i == 1)
        return [element];
    anticipate_assignment();
    heap += [0];
    while ((i > 1) && ((element[priority_ind]) < ((heap[(j = i / 2)])[priority_ind])))
        heap = replace(heap, i, heap[(i = j)]);
    heap = heap.replace(i, element);
    return heap;
    
    // $#Edited: 14 Mar 97 21:33 $miro
};

public method .del() {
    arg heap, i, priority_ind;
    var j, len, min;
    
    len = listlen(heap);
    if (i > len)
        throw(~invarg, "Index %d out of bounds - can't delete".format(i));
    anticipate_assignment();
    while (i != len) {
        min = len;
        j = i * 2;
        if ((j < len) && (((heap[j])[priority_ind]) < ((heap[min])[priority_ind])))
            min = j;
        j++;
        if ((j < len) && (((heap[j])[priority_ind]) < ((heap[min])[priority_ind])))
            min = j;
        heap = replace(heap, i, heap[min]);
        i = min;
    }
    heap = heap.subrange(1, len - 1);
    return heap;
    
    // $#Edited: 14 Mar 97 21:33 $miro
};


new object $place_lib: $libraries;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $place_lib default_place = $place;
var $place_lib coordinate_shortcuts = #[["n?orth", [0, 0]], ["s?outh", [180, 0]], ["e?ast", [90, 0]], ["w?est", [270, 0]], ["ne|northeast", [45, 0]], ["se|southeast", [135, 0]], ["nw|northwest", [225, 0]], ["sw|southwest", [315, 0]], ["d?own", [-1, -90]], ["u?p", [-1, 90]]];
var $place_lib known_realms = [$realm_of_creation];
var $place_lib build_hints = #[[1, <$ctext_frob, [["This is the do-it-all system for building places. At any time you can enter \"@abort\" to abort building. To turn off these hints \"@set experienced\" in your regular command environment.", <$format, ["hr", [], [], 'do_hr]>], #[['this, $place_lib]]]>], [2, <$ctext_frob, [["The specified destination does not exist, therefore a new one will be created with the name you specified.", <$format, ["hr", [], [], 'do_hr]>], #[['this, $place_lib]]]>], [3, <$ctext_frob, [["Name aliases can be specified on the same line as the name. This is done by seperating them from the name with commas. Any number of aliases can be specified in this manner (such as \"Name, alias, alias, alias\"). Names types can be defined by appending ", <$format, ["tt", [], ["+type"], 'do_tt]>, ", where ", <$format, ["tt", [], ["type"], 'do_tt]>, " is one of ", <$format, ["tt", [], ["proper"], 'do_tt]>, ", ", <$format, ["tt", [], ["unique"], 'do_tt]>, " or ", <$format, ["tt", [], ["normal"], 'do_tt]>, ". Not specifying a type defaults to ", <$format, ["tt", [], ["normal"], 'do_tt]>, ".", <$format, ["hr", [], [], 'do_hr]>], #[['this, $place_lib]]]>], [4, <$ctext_frob, [["Realms are used to keep locations in relation with each other. To get a list of commonly known realms type ", <$format, ["tt", [], ["@realms"], 'do_tt]>, ".", <$format, ["hr", [], [], 'do_hr]>], #[['this, $place_lib]]]>], [5, <$ctext_frob, [["Coordinates are used to define a basic relation between locations by pointing in the direction each place is. They use the radial/azimuth system. More help on Coordinates can be found in help under ", <$format, ["tt", [], ["places"], 'do_tt]>, ". For now it may be easier to use a coordinate shorcut (such as ", <$format, ["tt", [], ["up"], 'do_tt]>, "). To get a list of coordinate shortcuts type ", <$format, ["tt", [], ["@shortcuts"], 'do_tt]>, " now. Note: coordinates are automatically inverted for return exits (so if you specify ", <$format, ["tt", [], ["down"], 'do_tt]>, " the return exit will use the coordinates of ", <$format, ["tt", [], ["up"], 'do_tt]>, ").", <$format, ["hr", [], [], 'do_hr]>], #[['this, $place_lib]]]>]];
var $root manager = $place_lib;
var $root managed = [$place_lib];
var $place_lib default_distance = 250;
var $root owned = [$place_lib];
var $place_lib opposite_directions = #[["n?orth", 2], ["s?outh", 1], ["e?ast", 4], ["w?est", 3], ["northeast|ne", 7], ["southeast|se", 8], ["southwest|sw", 5], ["northwest|nw", 6], ["up", 10], ["d?own", 9]];
var $place_lib default_exit = $exit_frob;

public method .is_place() {
    arg obj;
    
    if (!(obj.has_ancestor($place)))
        throw(~place, ("Object \"" + (obj.namef('ref))) + "\" is not a place.");
};

public method .coordinates() {
    arg str;
    var x;
    
    for x in (coordinate_shortcuts) {
        if (str.match_template(x[1]))
            return x[2];
    }
    throw(~coordnf, ("Unable to find coordinate shortcut for \"" + str) + "\".");
};

public method .coordinate_shortcuts() {
    return coordinate_shortcuts;
};

public method .valid_coordinates() {
    arg radial, azimuth;
    
    if ((radial > 360) || (radial < (-1)))
        throw(~invcoord, "Radial coordinate must be from -1 to 360 degrees.");
    if ((azimuth > 90) || (azimuth < (-90)))
        throw(~invcoord, "Azimuth coordinate must be from 90 to -90 degrees.");
};

public method .invert_coordinates() {
    arg radial, azimuth;
    
    radial += 180;
    if (radial > 360)
        radial = radial - 360;
    if (azimuth > 0)
        azimuth = -azimuth;
    else
        azimuth = abs(azimuth);
    return [radial, azimuth];
};

public method .known_realms() {
    return known_realms;
};

public method .match_realm() {
    arg str;
    var r;
    
    for r in ($realm.descendants()) {
        if (r.match_name(str))
            return r;
    }
    return (| $object_lib.to_dbref(str) |) || 0;
    
    // $#Edited: 15 Feb 97 19:53 $miro
};

public method .add_known_realm() {
    arg obj;
    
    (> .perms(sender()) <);
    known_realms += [obj];
};

public method .del_known_realm() {
    arg obj;
    
    (> .perms(sender()) <);
    known_realms = known_realms.setremove(obj);
};

public method .del_build_hint() {
    arg hint_key;
    
    (> .perms(sender()) <);
    build_hints = build_hints.add(hint_key);
};

public method .build_hint() {
    arg hint;
    
    return build_hints[hint];
};

public method .build_hints() {
    return build_hints;
};

public method .add_build_hint() {
    arg hint_key, hint_text;
    
    (> .perms(sender()) <);
    build_hints = build_hints.add(hint_key, hint_text);
};

public method .opposite_direction() {
    arg dir;
    var key, od;
    
    od = opposite_directions;
    for key in (od.keys()) {
        if (match_template(dir, key))
            return (od.keys())[od[key]];
    }
    return 0;
};

public method .set_default() {
    arg what, value;
    
    (> .perms(sender()) <);
    what = tosym("default_" + what);
    return (> get_var(what, value) <);
};

public method .get_default() {
    arg what;
    
    what = tosym("default_" + what);
    return (> get_var(what) <);
};


new object $data_lib: $libraries;

var $root manager = $data_lib;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 849996459;
var $root inited = 1;
var $root managed = [$data_lib];

public method .unparse_indent() {
    arg value;
    var s, i, len;
    
    refresh();
    switch (type(value)) {
        case 'list:
            if (!value)
                return ["[]"];
            s = map i in [1 .. (len = value.length())] to ((.unparse_indent(value[i])).affix((i < len) ? "," : "")).sum();
            if (((s.mmap('length)).sum()) < 60)
                return [("[" + (s.join())) + "]"];
            else
                return (["[", ""].affix(s.prefix("  "))).affix("]");
        case 'dictionary:
            s = map i in [1 .. (len = (value.keys()).length())] to ((.unparse_indent([(value.keys())[i], value[(value.keys())[i]]])).affix((i < len) ? "," : "")).sum();
            if (((s.mmap('length)).sum()) < 60)
                return [("#[" + (s.join())) + "]"];
            else
                return (["#[", ""].affix(s.prefix("  "))).affix(["]"]);
        case 'frob:
            return (((["<"].affix(class(value))).affix(",")).affix(.unparse_indent(value.value()))).affix(">");
        default:
            return [toliteral(value)];
    }
    
    // $#Edited: 07 Dec 96 15:18 $miro
};

public method .data_map() {
    arg val, method, options, @args;
    var i, args, object, class;
    
    object = (| options['object] |);
    switch (type(val)) {
        case 'list:
            if ((| options['list] |))
                return object ? object.(method)(val, @args) : val.(method)(@args);
            return map i in (val) to (refresh() && (.data_map(i, method, options, @args)));
        case 'dictionary:
            if ((| options['dictionary] |))
                return object ? object.(method)(val, @args) : val.(method)(@args);
            if ((| options['keys] |))
                return hash i in (val) to ([.data_map(i[1], method, options, @args), refresh() && (.data_map(i[2], method, options, @args))]);
            return hash i in (val) to ([i[1], refresh() && (.data_map(i[2], method, options, @args))]);
        case 'frob:
            if ((| (class = options['class]) |)) {
                if (class == class(val))
                    return object ? object.(method)(val, @args) : val.(method)(@args);
                else
                    return val;
            }
            return (<class(val), .data_map(val.value(), method, options, @args)>);
        default:
            if ((| options['all] |) || (| options[type(val)] |))
                return object ? object.(method)(val, @args) : val.(method)(@args);
            return val;
    }
    
    // $#Edited: 07 Dec 96 15:51 $miro
};

public method .is_valid_type() {
    arg type;
    
    return type in ['integer, 'float, 'string, 'buffer, 'symbol, 'list, 'objnum, 'dictionary, 'error, 'frob];
    
    // $#Edited: 19 Jan 97 15:14 $brandon
};


new object $utilities: $core;

var $root child_index = 17;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $root manager = $utilities;
var $root managed = [$utilities];
var $root owned = [$utilities];


new object $lag_watcher: $utilities;

var $root manager = $lag_watcher;
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $lag_watcher lags = [0, 0, 0, 0, 0];
var $lag_watcher last_time = 859065156;
var $root owned = [$lag_watcher];
var $root managed = [$lag_watcher];

public method .startup() {
    // Called by $sys.startup()
    (> .perms(sender(), 'manager) <);
    lags = [];
    last_time = time();
    $heart.add_heartbeat(14);
};

protected method .update() {
    arg lag;
    
    // Called by .pulse() every 15 minutes
    if (type(lags) != 'list)
        lags = [];
    while ((lags.length()) > 9)
        lags = lags.delete(1);
    lag = (lag > 15) ? lag - 15 : 0;
    lags += [lag];
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .lag_str() {
    return ("Current server lag is " + (.lag())) + " seconds.";
};

public method .lag() {
    var lag, total, weight, lag_i, lag_d;
    
    // the current lag floated
    total = 0;
    weight = 0;
    for lag in (lags) {
        ++weight;
        total += lag * weight;
    }
    lag_i = total / 55;
    lag_d = tostr(((total - (lag_i * 55)) * 10) / 55).subrange(1, 1);
    return (tostr(lag_i) + ".") + lag_d;
};

public method .verbose_lag_str() {
    // returns lag as a string with verbosity
    return [("Current server lag is " + (.lag())) + " seconds.", toliteral(lags)];
    
    // $#Edited: 12 Jun 96 20:00 $levi
};

public method .value() {
    var lag, total, weight, lag_i;
    
    // unparsed lag value
    total = 0;
    weight = 0;
    for lag in (lags) {
        ++weight;
        total += lag * weight;
    }
    lag_i = total / 55;
    return lag_i;
};

public method .pulse() {
    var lag;
    
    // Called by $heart every 15 seconds
    (> .perms(sender(), $heart) <);
    lag = time() - last_time;
    last_time = time();
    .update(lag);
};

public method .shutdown() {
    // Called by $sys.startup()
    (> .perms(sender(), 'manager) <);
    $heart.del_heartbeat();
    
    // $#Edited: 30 Oct 96 17:25 $miro
};


new object $heart: $utilities;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $heart heart_failures = [];
var $heart hearts = [[$lag_watcher, 859065170], [#131, 859065204]];
var $root manager = $heart;
var $root managed = [$heart];
var $root owned = [$heart];
var $heart info = #[[#131, [60, 859065144]], [$lag_watcher, [14, 859065156]]];

public method .pulse() {
    var heart, h, x, new;
    
    for heart in (hearts) {
        if ((heart[2]) > time())
            break;
        if (!valid(heart[1]))
            ._del_heartbeat(heart[1]);
        catch any
            (> (heart[1]).pulse() <);
        with
            (| ((heart[1]).manager()).tell_traceback(traceback()) |);
        ._add_heartbeat(heart[1], (info[heart[1]])[1]);
    }
};

public method .add_heartbeat() {
    arg @delay;
    
    [(delay ?= 60)] = delay;
    ._add_heartbeat(sender(), delay);
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .del_heartbeat() {
    if (!(._del_heartbeat(sender())))
        throw(~objnf, ("Sender (" + sender()) + ") does not have a heartbeat.");
};

public method .hearts() {
    return hearts;
    
    // $#Edited: 09 Nov 96 10:27 $brandon
};

private method ._add_heartbeat() {
    arg obj, delay;
    var when, h, values;
    
    // Only one heartbeat per object
    ._del_heartbeat(obj);
    when = delay + time();
    info = dict_add(info, obj, [delay, time()]);
    for h in [1 .. listlen(hearts)] {
        if (((hearts[h])[2]) >= when) {
            hearts = insert(hearts, h, [obj, when]);
            return;
        }
    }
    hearts += [[obj, when]];
};

private method ._del_heartbeat() {
    arg obj;
    var x, pos;
    
    if (info.contains(obj))
        info = info.del(obj);
    for x in [1 .. listlen(hearts)] {
        if (((hearts[x])[1]) == obj) {
            hearts = delete(hearts, x);
            return 1;
        }
    }
    return 0;
};


new object $scheduler: $utilities;

var $root created_on = 810294797;
var $root inited = 1;
var $root flags = ['methods, 'code, 'variables, 'core];
var $scheduler task_index = 10;
var $scheduler blocked_tasks = #[];
var $scheduler task_queue = [];
var $scheduler sub_schedulers = [$heart];
var $scheduler expected_lag = 0;
var $scheduler server_lag = 0;
var $root manager = $scheduler;
var $scheduler suspended_tasks = #[];
var $root managed = [$scheduler];
var $root owned = [$scheduler];

public method .sleep() {
    arg howlong;
    
    .add_task(howlong, 'resume_job, task_id());
    .suspend(this());
};

private method .remove_first_task() {
    // sender must be an agent, or admin.
    catch any {
        .del_from_task_queue(1);
    } with {
        // $sys.log(traceback());
    }
    if (!task_queue)
        task_index = 1;
    
    // $#Edited: 21 Nov 96 20:38 $miro
};

public method .task_queue() {
    // sender must be system, for now
    (> .perms(sender(), 'system) <);
    return task_queue;
    
    // $#Edited: 21 Nov 96 20:38 $miro
};

public method .del_task() {
    arg tid;
    var task, n;
    
    // sender must be system, for now.
    if (type(tid) != 'integer)
        throw(~type, "Task Identification must be an integer");
    for task in (task_queue) {
        n++;
        if ((task[1]) == tid) {
            ((sender() == (task[4])) && (caller() == (task[5]))) || (> .perms(sender(), 'system) <);
            .del_from_task_queue(n);
            return 1;
        }
    }
    throw(~tasknf, "No task found by that TID");
    
    // $#Edited: 21 Nov 96 20:38 $miro
};

public method .add_task() {
    arg time, method, @args;
    var task, i, j, tid, flags, x, y, task_time;
    
    if ((type(time) != 'integer) || ((type(method) != 'symbol) || (type(args) != 'list)))
        throw(~type, "Arguments are not an integer, symbol, and list.");
    if (time < 0)
        throw(~time, "Time is negative.");
    if (time > 31536000)
        throw(~time, "Try to schedule a task LESS than a year from now?");
    
    // get a new db task id
    ++task_index;
    tid = task_index;
    
    // flags can be set in a system only add_task, for now set them as 'system
    flags = ['system];
    task_time = time();
    task = [tid, time + task_time, task_time, sender(), caller(), method, flags, args];
    .add_to_task_queue(task);
    return tid;
    
    // $#Edited: 21 Nov 96 20:38 $miro
};

public method .pulse() {
    var task, sub, t;
    
    // called by $sys.heartbeat
    if (caller() != $sys)
        throw(~perm, "Sender is not system");
    t = time();
    while (task_queue && (t > ((task_queue[1])[2]))) {
        task = task_queue[1];
        catch any
            (> (task[5]).as_this_run(task[5], task[6], task[8]) <);
        with
            (| ((task[5]).manager()).tell_traceback(traceback()) |);
        .remove_first_task();
    }
    
    // call sub schedulers 
    for sub in (sub_schedulers)
        (| sub.pulse() |);
    
    // $#Edited: 21 Nov 96 20:38 $miro
};

public method .sys_add_task() {
    arg time, method, sender, caller, flags, @args;
    var task, i, j, tid, x, y, tmpq, task_time;
    
    // use `@info $scheduler' for more information. 
    // [tid, time, time(), sender(), caller(), method, flags, args]
    //
    if (!($sys.is_agent(sender())))
        throw(~perm, "Sender is not an agent or admin, use .add_task()");
    if ((type(time) != 'integer) || ((type(method) != 'symbol) || (type(args) != 'list)))
        throw(~type, "Arguments are not an integer, symbol, and list.");
    if (time < 1)
        throw(~time, "Time is negative.");
    if (time > 31536000)
        throw(~time, "Try to schedule a task LESS than a year from now?");
    if (!valid(sender))
        throw(~type, "The argument for sender is not a valid object");
    if (!valid(caller))
        throw(~type, "The argument for caller is not a valid object");
    if (type(flags) != 'list)
        throw(~type, "Send flags as a list of symbols");
    
    //
    ++task_index;
    tid = task_index;
    task_time = time();
    
    // flags can be set in a system only add_task, for now set them as 'system
    task = [tid, task_time + time, task_time, sender, caller, method, flags, args];
    .add_to_task_queue(task);
    return tid;
    
    // $#Edited: 21 Nov 96 20:38 $miro
};

public method .add_sub_scheduler() {
    arg object;
    
    if (!($sys.is_admin(sender())))
        throw(~perm, "Only admins may add sub schedulers.");
    if (type(object) != 'objnum)
        throw(~type, "Object must be a dbref.");
    sub_schedulers += [object];
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .del_sub_scheduler() {
    arg object;
    var pos, s;
    
    if (!($sys.is_admin(sender())))
        throw(~perm, "Only admins may delete sub schedulers.");
    if (type(object) != 'objnum)
        throw(~type, "Object must be a dbref.");
    pos = object in sub_schedulers;
    if (!pos)
        throw(~objnf, "Object not a sub scheduler.");
    s = [];
    if (pos > 1)
        s += [sub_schedulers.subrange(1, pos - 1)];
    if (s < (sub_schedulers.length()))
        s += [sub_schedulers.subrange(pos + 1)];
    sub_schedulers = s;
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .has_blocked_tasks() {
    arg ident;
    
    return blocked_tasks.contains(ident);
};

public method .block_task() {
    arg ident;
    var tasks;
    
    // I want to be atomic!
    // Add the task_id to the queue of blocked tasks for this identifier.
    if (blocked_tasks.contains(ident))
        tasks = (blocked_tasks[ident]) + [task_id()];
    else
        tasks = [task_id()];
    blocked_tasks = blocked_tasks.add(ident, tasks);
    
    // And go to sleep until we are woken.
    $sys.suspend();
};

public method .unblock_task() {
    arg ident;
    var tasks;
    
    // I want to be atomic!
    // The caller should have checked first, but we will fail silently.
    if (!(.has_blocked_tasks(ident)))
        return;
    
    // Get the blocked tasks queue for this identifier.
    tasks = blocked_tasks[ident];
    
    // If this is the last blocked task, then clear the queue, otherwise
    // just delete the task_id that we are resuming.
    if ((tasks.length()) == 1)
        blocked_tasks = blocked_tasks.del(ident);
    else
        blocked_tasks = blocked_tasks.add(ident, tasks.delete(1));
    
    // Wake it up and go.
    $sys.resume(tasks[1]);
};

protected method .resume_job() {
    arg tid;
    
    (> .resume(tid) <);
};

public method .suspend() {
    arg @objs;
    
    objs += [user()];
    suspended_tasks = dict_add(suspended_tasks, task_id(), objs);
    return (> suspend() <);
};

public method .resume() {
    arg task_id, @return_value;
    var objs;
    
    if ((objs = (| suspended_tasks[task_id] |))) {
        if ((!(sender() in objs)) && (!($sys.is_system(sender()))))
            throw(~perm, (sender() + " may not resume task ") + task_id);
        suspended_tasks = dict_del(suspended_tasks, task_id);
    }
    return (> resume(task_id, @return_value) <);
};

public method .cancel() {
    arg task_id;
    var objs;
    
    if ((objs = (| suspended_tasks[task_id] |))) {
        if ((!(sender() in objs)) && (!($sys.is_system(sender()))))
            throw(~perm, (sender() + " may not cancel task ") + task_id);
        suspended_tasks = dict_del(suspended_tasks, task_id);
    }
    return (> cancel(task_id) <);
};

public method .task_info() {
    arg @args;
    
    (> .perms(sender(), 'system) <);
    return (> task_info(@args) <);
    
    // $#Edited: 29 Oct 96 17:54 $brandon
};

public method .suspended_task() {
    arg task;
    
    return (> suspended_tasks[task] <);
    
    // $#Edited: 29 Oct 96 19:02 $brandon
};

private method .del_from_task_queue() {
    arg i;
    
    refresh();
    
    // this must *not* throw
    task_queue = $heap.del(task_queue, i, 2);
    
    // $#Edited: 14 Mar 97 21:33 $miro
};

private method .add_to_task_queue() {
    arg task;
    
    refresh();
    
    // We don't want to run out of tics
    task_queue = $heap.push(task_queue, task, 2);
    
    // $#Edited: 14 Mar 97 21:33 $miro
};

root method .core_scheduler() {
    task_queue = [];
};


new object $file: $utilities;

var $root manager = $file;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 843324817;
var $root inited = 1;
var $root managed = [$file];
var $root owned = [$file];

public method .fstat() {
    arg @path;
    
    if (!path)
        throw(~perm, "Perm.");
    return (> fstat(@path) <);
    
    // $#Edited: 30 Oct 96 12:19 $brandon
};

public method .files() {
    arg path;
    
    return (> files(path) <);
    
    // $#Edited: 30 Oct 96 12:19 $brandon
};


new object $compiler: $utilities;

var $root manager = $compiler;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837583518;
var $root inited = 1;
var $root managed = [$compiler];
var $root owned = [$compiler];
var $compiler glue_table = ["p", "br", "ul", "ol", "dl", "table", "switch", "case", "range", "default"];

public method .parse_string_new() {
    arg vars, tokens;
    var mode, out, word, token, i, tmp, ret;
    
    if (!tokens)
        return [[], vars];
    mode = ['spaces, 'plain];
    i = 1;
    out = [];
    word = "";
    while (i <= (tokens.length())) {
        refresh();
        token = tokens[i++];
        switch (mode[1]) {
            case 'spaces:
                if (token != " ") {
                    i--;
                    mode = mode.subrange(2);
                }
            case 'plain:
                if (!(token in ["{", "["])) {
                    if (token == " ") {
                        // No scatter because .check can throw
                        if ((| (ret = ._check_glue(tokens, i)) |)) {
                            i = ret[1];
                            mode = [ret[2], @mode];
                            if (word)
                                out += [word];
                            word = "";
                            continue;
                        }
                    }
                    word += token.sed("\\\(.)", "%1", "g");
                } else {
                    if (word)
                        out += [word];
                    word = "";
                    mode = ['spaces, (token == "{") ? 'fmtname : 'genname, @mode];
                }
            case 'fmtname, 'genname:
                if (((mode[1]) == 'fmtname) && (token == "quote")) {
                    mode = mode.subrange(2);
                    out += [$format.new_tag("quote", [], [tokens[i++]])];
                    i++;
                } else {
                    if (token in glue_table)
                        mode = [mode[1], 'spaces, @mode.subrange(2)];
                    mode = ['spaces, 'flags, #[], token, @mode];
                }
            case 'flags:
                if (token in ["}", "]"]) {
                    ret = ._make_tag(token, mode[4], vars, mode[3], mode[2], []);
                    vars = ret[2];
                    out += [ret[1]];
                    mode = mode.subrange(5);
                } else if (token == "=") {
                    throw(~parse, "Value flag with no key.");
                } else if (token == ":") {
                    mode = ['spaces, 'args, out, mode[2], @mode.subrange(3)];
                    out = [];
                } else if ((| (tokens[i]) == "=" |)) {
                    mode = ['flagvalue, token, @mode];
                    i++;
                } else {
                    mode = mode.replace(2, (mode[2]).add(token, 1));
                }
            case 'flagvalue:
                if (token in ["}", "]", ":"]) {
                    mode = mode.subrange(3);
                    i--;
                } else if (token == " ") {
                    mode = mode.subrange(3);
                } else if (!(token in ["[", "{"])) {
                    mode = ['spaces, @(mode.subrange(3)).replace(2, (mode[4]).add(mode[2], token.sed("\\\(.)", "%1", "g")))];
                } else {
                    if (word)
                        out += [word];
                    word = "";
                    mode = ['spaces, (token == "{") ? 'fmtname : 'genname, 'flagset, @mode.subrange(2)];
                }
            case 'flagset:
                i--;
                mode = ['spaces, @(mode.subrange(3)).replace(2, (mode[4]).add(mode[2], out[out.length()]))];
                out = out.subrange(1, (out.length()) - 1);
            case 'args:
                if (token in ["}", "]"]) {
                    if (word) {
                        out += [word];
                        word = "";
                    }
                    ret = ._make_tag(token, mode[5], vars, mode[4], mode[3], out);
                    vars = ret[2];
                    out = (mode[2]) + [ret[1]];
                    mode = mode.subrange(6);
                } else if (token in ["{", "["]) {
                    if (word)
                        out += [word];
                    word = "";
                    mode = ['spaces, (token == "{") ? 'fmtname : 'genname, @mode];
                } else {
                    if (token == " ") {
                        if ((| (ret = ._check_glue(tokens, i)) |)) {
                            i = ret[1];
                            mode = [ret[2], @mode];
                            if (word)
                                out += [word];
                            word = "";
                            continue;
                        }
                    }
                    word += token.sed("\\\(.)", "%1", "g");
                }
        }
    }
    if (word)
        out += [word];
    while ((mode[1]) == 'spaces)
        mode = mode.subrange(2);
    if (mode != ['plain])
        throw(~parse, "Unclosed tag.");
    return [out, vars];
    
    // $#Edited: 14 Feb 97 02:29 $miro
};

public method .tokenize() {
    arg text;
    var word, out, escaped, token, i, pre_count, open_form, str;
    
    // break text into a list of tokens.
    if (type(text) == 'string)
        text = [text];
    out = [];
    word = "";
    escaped = 0;
    
    // pre_count is 0, except inside pre, when it counts the {}'s
    pre_count = 0;
    open_form = 0;
    for str in (text) {
        str = str.explode(" ", 1);
        for token in (str) {
            refresh();
            if ((!token) && (!pre_count))
                continue;
            while ((i = token.match_regexp("[][{}=\:]"))) {
                refresh();
                i = (i[1])[1];
                if (escaped) {
                    escaped = 0;
                    word = (word + "\\") + (token.subrange(1, i));
                } else if (pre_count) {
                    if ((token[i]) == "{") {
                        pre_count++;
                        word += token.subrange(1, i);
                    } else if ((token[i]) == "}") {
                        pre_count--;
                        if (pre_count) {
                            word += token.subrange(1, i);
                        } else {
                            word += token.subrange(1, i - 1);
                            out = word ? out + [word, token[i]] : (out + [token[i]]);
                            word = "";
                        }
                    } else {
                        word += token.subrange(1, i);
                    }
                } else {
                    word += token.subrange(1, i - 1);
                    open_form = (token[i]) == "{";
                    if ((token[i]) == "\\") {
                        escaped = 1;
                    } else {
                        out = word ? out + [word, token[i]] : (out + [token[i]]);
                        word = "";
                    }
                }
                token = token.subrange(i + 1);
            }
            if (open_form && (token == "quote")) {
                pre_count = 1;
                open_form = 0;
                out += [token];
                token = "";
                continue;
            }
            word += token;
            if (escaped || pre_count) {
                escaped = 0;
                word += " ";
            } else {
                out = word ? out + [word, " "] : (out + [" "]);
                word = "";
            }
        }
        if (pre_count)
            word = word ? (word.subrange(1, (word.length()) - 1)) + "\n" : "\n";
    }
    if (word)
        out += [word];
    if (out) {
        if ((out.last()) == " ")
            out = out.subrange(1, (out.length()) - 1);
        else
            out = out.replace(out.length(), (out.last()).subrange(((out.last()).length()) - 1));
    }
    return out;
};

public method ._make_tag() {
    arg token, mode, vars, name, flags, args;
    var method, class;
    
    if (mode == 'fmtname) {
        if (token != "}")
            throw(~parse, "Extra ']' encountered.");
        method = tosym("do_" + (name.strip()));
        class = $format;
    }
    if (mode == 'genname) {
        if (token != "]")
            throw(~parse, "Extra '}' encountered.");
        method = tosym("gen_" + (name.strip()));
        class = $generator;
    }
    catch ~methodnf
        return .(method)(vars, flags, args);
    with
        return [class.new_tag(name, flags, args), vars];
};

public method .compile_cml() {
    arg text;
    var vars, ret;
    
    vars = #[];
    (> (ret = .parse_string_new(vars, .tokenize(text))) <);
    return $ctext_frob.new_with(ret[1], ret[2]);
};

public method .do_link() {
    arg vars, flags, args;
    var links, item, node;
    
    if (listlen(args) == 0)
        throw(~parse, "{link} requires an argument of the link name.");
    links = (| vars['links] |) || #[];
    for item in (flags) {
        if ((type(item) == 'list) && ((item[1]) == "node")) {
            node = item[2];
            break;
        }
    }
    if (!node)
        throw(~parse, "No node for {link}.");
    if (((args.length()) != 1) || (type(args[1]) != 'string))
        throw(~parse, "{link} argument must be a string");
    links = links.add(args[1], node);
    return [$format.new_tag("link", flags, args), vars.add('links, links)];
};

public method .do_detail() {
    arg vars, flags, args;
    var dets, item, name;
    
    dets = (| vars['details] |) || #[];
    for item in (flags) {
        if ((type(item) == 'list) && ((item[1]) == "name")) {
            name = item[2];
            break;
        }
    }
    if (!name)
        throw(~parse, "No name for {detail}.");
    dets = dets.add(name, args);
    return [$format.new_tag("detail", flags, []), vars.add('details, dets)];
    
    // $#Edited: 30 Oct 96 23:38 $miro
};

public method ._kill_spaces() {
    arg list;
    var i;
    
    return filter i in (list) where (i != " ");
    
    // $#Edited: 02 Nov 96 19:38 $miro
};

public method .do_table() {
    arg vars, flags, args;
    
    return [$format.new_tag("table", flags, ._kill_spaces(args)), vars];
    
    // $#Edited: 02 Nov 96 19:39 $miro
};

public method .do_tr() {
    arg vars, flags, args;
    
    return [$format.new_tag("tr", flags, ._kill_spaces(args)), vars];
    
    // $#Edited: 02 Nov 96 19:39 $miro
};

public method .do_ul() {
    arg vars, flags, args;
    
    return [$format.new_tag("ul", flags, ._kill_spaces(args)), vars];
    
    // $#Edited: 02 Nov 96 19:40 $miro
};

public method .do_dl() {
    arg vars, flags, args;
    
    return [$format.new_tag("dl", flags, ._kill_spaces(args)), vars];
    
    // $#Edited: 02 Nov 96 19:41 $miro
};

public method .do_ol() {
    arg vars, flags, args;
    
    return [$format.new_tag("ol", flags, ._kill_spaces(args)), vars];
};

public method ._check_glue() {
    arg tokens, i;
    var j, bracket;
    
    // WARNING: This method can throw (it should be called with (| |)'s)
    while ((tokens[i]) == " ")
        i++;
    if ((bracket = tokens[i++]) in ["{", "["]) {
        while ((tokens[i]) == " ")
            i++;
        j = i;
        if ((tokens[i]) in glue_table)
            return [j, (bracket == "{") ? 'fmtname : 'genname];
    }
    return 0;
    
    // $#Edited: 22 Jan 97 21:05 $miro
    // $#Edited: 22 Jan 97 21:40 $miro
};

public method .gen_switch() {
    arg vars, flags, args;
    var current, d, tag, i, m, r;
    
    if (listlen(args) == 0)
        throw(~parse, "[switch] requires arguments.");
    if (!(| flags["value"] |))
        throw(~parse, "Value flag missing.");
    d = #[];
    r = [];
    tag = (current = 0);
    
    // The last default is a dummy - it forces the parser to flush current
    for i in (args + [$generator.new_tag("default", [], [])]) {
        if ((type(i) == 'frob) && ((class(i) == $generator) && ((i.name()) in ["case", "default", "range"]))) {
            if (tag != 0) {
                if (type(tag) == 'list)
                    r += [[@tag.subrange(2), current]];
                else
                    d = d.add(tag, current);
            }
            current = [];
            switch (i.name()) {
                case "case":
                    if ((((i.args()).length()) != 1) || (type((tag = (i.args())[1])) != 'string))
                        throw(~parse, "[case:...] takes only a single string as an argument.");
                case "range":
                    if ((((i.args()).length()) != 1) || (!(| ((m = ((i.args())[1]).match_pattern("*..*")).length()) == 2 |)))
                        throw(~parse, "range tag should look like [range:lower..upper].");
                    tag = ['range, @m];
                case "default":
                    tag = 'default;
            }
        } else {
            if (tag == 0)
                throw(~parse, "Expression before [case]");
            current += [i];
        }
    }
    if (r)
        d = d.add('ranges, r);
    return [$generator.new_tag("switch", flags, d), vars];
    
    // $#Edited: 22 Jan 97 16:37 $miro
};

public method .glue_table() {
    return glue_table;
    
    // $#Edited: 22 Jan 97 15:32 $miro
};

public method .do_action() {
    arg vars, flags, args;
    var actions, item, link, scheme, i;
    
    if (listlen(args) == 0)
        throw(~parse, "{action} requires an argument of the name.");
    if (!dict_contains(flags, "cmd"))
        throw(~parse, "no cmd flag for {action}");
    
    // nix everything else
    flags = #[["cmd", flags["cmd"]]];
    return [$format.new_tag("link", flags, args), vars];
};


new object $evaluator: $utilities;

var $root manager = $evaluator;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837583637;
var $root child_index = 3;
var $root inited = 1;
var $root managed = [$evaluator];
var $root owned = [$evaluator];

public method .eval_formatter() {
    arg form, vars;
    var flags, text, key;
    
    form = form.eval_flags(vars);
    catch ~methodnf {
        return .(form[4])(vars, form[2], form[3]);
    } with {
        [text, vars] = ._eval_ctext(form[3], vars);
        form = (<$format, [form[1], form[2], text, form[4]]>);
        return [[form], vars];
    }
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method ._eval_ctext() {
    arg data, vars;
    var out, uflags, token;
    
    out = [];
    if (type(data) != 'list)
        data = [data];
    for token in (data) {
        if (type(token) == 'frob) {
            switch (class(token)) {
                case $generator:
                    [token, vars] = .eval_generator(token, vars);
                    out += token;
                case $format:
                    [token, vars] = .eval_formatter(token, vars);
                    out += token;
                default:
                    out += [token];
            }
        } else {
            out += [token];
        }
    }
    return [out, vars];
    
    // $#Edited: 29 Nov 96 16:27 $miro
    // $#Edited: 29 Nov 96 16:59 $miro
};

public method .eval_generator() {
    arg gen, vars;
    var flags, key, value, name;
    
    gen = gen.eval_flags(vars);
    catch ~methodnf {
        return .(gen[4])(vars, gen[2], gen[3]);
    } with {
        catch ~keynf
            return [[vars[gen[1]]], vars];
        with
            return [[(">>ERROR: Unknown generator [" + (gen[1])) + "].<<"], vars];
    }
    
    // $#Edited: 29 Nov 96 16:24 $miro
};

public method .init() {
    return #[];
    
    // $#Edited: 16 Jul 96 08:43 $kahuna
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:07 $jenner
};


new object $bs_eval: $evaluator;

var $root manager = $bs_eval;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837583704;
var $root inited = 1;
var $root child_index = 3;
var $root managed = [$bs_eval];
var $root owned = [$bs_eval];

public method .gen_servername() {
    arg vars, flags, args;
    
    return [[$motd.server_name()], vars];
    
    // $#Edited: 16 Jul 96 08:12 $kahuna
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:08 $jenner
};

public method .gen_set() {
    arg vars, flags, args;
    var text, name;
    
    name = flags.getkey("var");
    [text, vars] = ._eval_ctext(args[1], vars);
    return [[""], vars.add(name, text[1])];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .gen_name() {
    arg vars, flags, args;
    var out, name, sep, type;
    
    [args, vars] = ._eval_ctext(args, vars);
    out = [];
    type = (| tosym(flags.getkey("type")) |) || 'name;
    if (!args)
        return [[(vars['this]).namef(type)], vars];
    sep = (| flags.getkey("separator") |) || " ";
    for name in (args) {
        switch (type(name)) {
            case 'objnum:
                name = name.namef(type);
            case 'string:
                catch ~objnf
                    name = ((vars['this]).match_environment(name)).namef(type);
                with
                    name = name;
        }
        out += [name];
    }
    return [._separate_list(sep, out), vars];
    
    // $#Edited: 16 Jul 96 08:12 $kahuna
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:08 $jenner
    // $#Edited: 29 Nov 96 16:22 $miro
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method ._separate_list() {
    arg sep, l;
    
    if (sep == "none")
        return l;
    if (sep == "english")
        return [l.to_english()];
    return [l.join(sep)];
    
    // $#Edited: 16 Jul 96 08:12 $kahuna
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:08 $jenner
    // $#Edited: 18 Jul 96 14:56 $levi
};

public method .gen_english() {
    arg vars, flags, args;
    var sep, empty, and, text;
    
    sep = ((| flags.getkey("separator") |) || ",") + " ";
    empty = (| flags.getkey("empty") |) || "nothing";
    and = (| flags.getkey("and") |) || " and ";
    [text, vars] = ._eval_ctext(args, vars);
    return [[text.to_english(empty, and, sep)], vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .gen_def() {
    arg vars, flags, args;
    var name, val;
    
    name = flags.getkey("var");
    val = args[1];
    return [[""], vars.add(name, val)];
    
    // $#Edited: 29 Nov 96 17:14 $miro
};

public method .gen_foreach() {
    arg vars, flags, args;
    var v, list, body, out, item, sep, text;
    
    v = (| flags.getkey("var") |) || "iterator";
    list = flags.getkey("list");
    sep = (| flags.getkey("separator") |) || " ";
    out = [];
    for item in (list) {
        vars = vars.add(v, item);
        [text, vars] = ._eval_ctext(args, vars);
        if ((vars['time]) == 'post)
            out = out.affix(text);
        else
            out += [text];
    }
    if ((vars['time]) == 'pre)
        out = ._separate_list(sep, out);
    return [out, vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .gen_time() {
    arg vars, flags, args;
    var a, word;
    
    [args, vars] = ._eval_ctext(args, vars);
    if (!args)
        return [tostr(time()), vars];
    return [[$time.format(args[1])], vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .gen_vars() {
    arg vars, flags, args;
    var out, v, sep;
    
    out = [];
    sep = (| flags.getkey("separator") |) || " ";
    for v in (vars.keys()) {
        if (type(v) == 'string)
            out += [v];
    }
    return [._separate_list(sep, out), vars];
    
    // $#Edited: 16 Jul 96 08:12 $kahuna
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 00:08 $jenner
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .gen_pro() {
    arg vars, flags, args;
    var out, type, obj, key, objstr;
    
    if ((| (objstr = flags.getkey("obj")) |)) {
        while (type(objstr) == 'list)
            objstr = objstr[1];
        if (type(objstr) == 'string) {
            catch ~objnf, ~namenf
                obj = (vars['this]).match_environment(objstr);
            with
                return [[(">>ERROR: Invalid object '" + objstr) + "'.<<"], vars];
        } else {
            obj = objstr;
        }
    } else {
        obj = vars['this];
    }
    out = [];
    if ((args.length()) == 0)
        return [[">>ERROR: Must specify pronoun type.<<"], vars];
    type = (args[1]).to_symbol();
    catch ~keynf
        out = (> [(obj.gender()).pronoun(type)] <);
    with
        return [[(">>ERROR: Invalid pronoun type '" + (args[1])) + "'.<<"], vars];
    return [out, vars];
    
    // $#Edited: 24 Jul 96 19:55 $jenner
    // $#Edited: 29 Nov 96 17:14 $miro
};

public method .gen_join() {
    arg vars, flags, args;
    var v, sep;
    
    sep = (| flags.getkey("separator") |) || " ";
    [args, vars] = ._eval_ctext(args, vars);
    return [._separate_list(sep, args), vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .gen_columnize() {
    arg vars, flags, args;
    var v, cols;
    
    cols = (| flags.getkey("cols") |) || "*";
    [args, vars] = ._eval_ctext(args, vars);
    return [[(cols == "*") ? args.lcolumnize() : (args.columnize(toint(cols)))], vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .gen_servname() {
    arg vars, flags, args;
    
    return [[$motd.server_name()], vars];
};

public method .gen_switch() {
    arg vars, flags, args;
    var v, i, num, n, done;
    
    v = flags.getkey("value");
    if (type(v) == 'list)
        v = v.join("");
    if (args.contains(v))
        return ._eval_ctext(args[v], vars);
    if (args.contains('ranges)) {
        if ((num = v.is_numeric()))
            ;
        n = toint(v);
        done = 0;
        for i in (args['ranges]) {
            if ((| num && (((i[1]).is_numeric()) && ((i[2]).is_numeric())) |)) {
                if ((n >= toint(i[1])) && (n <= toint(i[2])))
                    done = 1;
            } else if ((| (v >= (i[1])) && (v <= (i[2])) |)) {
                done = 1;
            }
            if (done)
                return ._eval_ctext(i[3], vars);
        }
    }
    if (args.contains('default))
        return ._eval_ctext(args['default], vars);
    return [((vars['time]) == 'pre) ? [""] : "", vars];
    
    // $#Edited: 22 Jan 97 16:37 $miro
};


new object $place_desc_evaluator: $bs_eval;

var $root manager = $place_desc_evaluator;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 845665471;
var $root inited = 1;
var $root managed = [$place_desc_evaluator];
var $root owned = [$place_desc_evaluator];


new object $realm_base_eval: $bs_eval;

var $root manager = $realm_base_eval;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 847528368;
var $root inited = 1;
var $root managed = [$realm_base_eval];

public method .gen_hour() {
    arg vars, flags, args;
    var v, i, len, n;
    
    v = vars['daytime];
    return [((vars['time]) == 'post) ? tostr(v[1]) : [tostr(v[1])], vars];
    
    // $#Edited: 22 Dec 96 15:49 $miro
};

public method .gen_light() {
    arg vars, flags, args;
    var v, i, len, n;
    
    v = vars['daytime];
    return [((vars['time]) == 'post) ? v[2] : [v[2]], vars];
    
    // $#Edited: 22 Dec 96 15:49 $miro
};

public method .gen_daynight() {
    arg vars, flags, args;
    var v, i, len, n;
    
    v = vars['daytime];
    return [((vars['time]) == 'post) ? v[3] : [v[3]], vars];
    
    // $#Edited: 22 Dec 96 15:49 $miro
};


new object $formatter: $evaluator;

var $root manager = $formatter;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837583776;
var $root child_index = 2;
var $root inited = 1;
var $root managed = [$formatter];
var $root owned = [$formatter];

public method .eval_generator() {
    arg gen, vars;
    
    return (vars['evaluator]).eval_generator(gen, vars);
    
    // $#Edited: 29 Nov 96 16:28 $miro
};

public method ._eval_ctext() {
    arg data, vars;
    var out, uflags, token;
    
    out = "";
    if (type(data) != 'list)
        data = [data];
    for token in (data) {
        refresh();
        switch (type(token)) {
            case 'frob:
                switch (class(token)) {
                    case $generator:
                        [token, vars] = ((| vars['evaluator] |) || $bs_eval).eval_generator(token, vars);
                        if (type(token) == 'string) {
                            out += token;
                        } else {
                            [token, vars] = ._eval_ctext(token, vars);
                            out += token;
                        }
                    case $format:
                        [token, vars] = .eval_formatter(token, vars);
                        out += token;
                }
            case 'string:
                out += token;
            case 'list:
                [token, vars] = ._eval_ctext(token, vars);
                out += token;
            default:
                out += token;
        }
    }
    return [out, vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .eval_formatter() {
    arg form, vars;
    var flags, i, text;
    
    form = form.eval_flags(vars);
    catch ~methodnf {
        return .(form[4])(vars, form[2], form[3]);
    } with {
        [text, vars] = ._eval_ctext(form[3], vars);
        if ((vars['time]) == 'post)
            return [text, vars];
        form = (<$format, [form[1], form[2], text, form[4]]>);
        return [[form], vars];
    }
    
    // $#Edited: 23 Jan 97 20:49 $miro
};


new object $text_format: $formatter;

var $root manager = $text_format;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837583858;
var $root inited = 1;
var $root managed = [$text_format];
var $root owned = [$text_format];
var $root child_index = 1;

public method .init() {
    return #[['header, ""], ['width, 78]];
    
    // $#Edited: 17 Jul 96 04:00 $kahuna
    // $#Edited: 17 Jul 96 00:11 $jenner
};

public method .do_ul() {
    arg vars, flags, args;
    var out, token, old, last, depth;
    
    if (dict_contains(vars, 'list_type)) {
        old = vars['list_type];
        if (old == 'ordinal)
            last = vars['list_last];
        else
            last = -1;
        vars = dict_add(vars, 'list_depth, (vars['list_depth]) + 1);
    } else {
        vars = dict_add(vars, 'list_depth, 1);
    }
    vars = dict_add(vars, 'list_type, 'plain);
    [args, vars] = ._eval_ctext(args, vars);
    if (old) {
        vars = dict_add(vars, 'list_type, old);
        if ((old == 'ordinal) && (last != (-1)))
            vars = dict_add(vars, 'list_last, last);
        vars = dict_add(vars, 'list_depth, (vars['list_depth]) - 1);
    } else {
        vars = dict_del(vars, 'list_type);
        vars = dict_del(vars, 'list_depth);
    }
    return [args, vars];
};

public method .do_th() {
    arg vars, flags, args;
    var tblinfo, rinfo, col, cols, rows, w, n, max;
    
    rows = (| toint(flags.getkey("rowspan")) |) || 1;
    cols = (| toint(flags.getkey("colspan")) |) || 1;
    rinfo = vars['rinfo];
    tblinfo = vars['table_info];
    col = (tblinfo[2]) + 1;
    n = [];
    max = listlen(tblinfo[1]);
    while (rinfo[col]) {
        col++;
        n += [[0, (tblinfo[1])[col], []]];
    }
    w = ((tblinfo[1]).subrange(col, cols)).sum();
    tblinfo = tblinfo.replace(2, (col + cols) - 1);
    vars = (vars.add('table_info, tblinfo)).add('header, "");
    [args, vars] = .eval_indented(args, vars, 0, w);
    return [(n + [[rows, w, args.explode("\n", 1)]]) + ($list.make(cols - 1, [rows, 0, []])), vars];
    
    // $#Copied 23 Jan 97 11:03 from $text_format.do_td() by $brandon
};

public method .do_dl() {
    arg vars, flags, args;
    var out, token, c, cm;
    
    c = (| vars['columned] |) || 0;
    cm = (| flags.getkey("columned") |) || 0;
    vars = vars.add('columned, cm);
    [args, vars] = ._eval_ctext(args, vars);
    if (c)
        vars = vars.add('columned, c);
    else if (vars.contains('columned))
        vars = vars.del('columned);
    return [args + "\n", vars];
};

public method .do_anchor() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args[1], vars);
    return [("/" + args) + "/", vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_p() {
    arg vars, flags, args;
    
    return ["\n", vars];
};

public method .do_em() {
    arg vars, flags, args;
    var out, a;
    
    return ._eval_ctext(args, vars);
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_br() {
    arg vars, flags, args;
    
    return ["\n", vars];
    
    // $#Edited: 17 Jul 96 00:05 $kahuna
    // $#Edited: 17 Jul 96 04:00 $kahuna
    // $#Edited: 17 Jul 96 00:11 $jenner
};

public method .do_link() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args[1], vars);
    return [("[" + args) + "]", vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_web() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [((((args + "<") + (flags.getkey("name"))) + ":") + (flags.getkey("src"))) + ">", vars];
    
    // $#Edited: 29 Nov 96 16:39 $miro
};

public method .do_hr() {
    arg vars, flags, args;
    
    return [pad("\n", vars['width], "-") + "\n", vars];
};

public method .do_tt() {
    arg vars, flags, args;
    var out, a;
    
    return ._eval_ctext(args, vars);
};

public method .do_action() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args[1], vars);
    (vars['receiver]).register_action(args, flags.getkey("cmd"));
    return [("[" + args) + "]", vars];
};

public method .do_subj() {
    arg vars, flags, args;
    var out, word, l, len;
    
    [out, vars] = ._eval_ctext(args, vars);
    len = vars['width];
    switch (toint((| flags.getkey("level") |) || "4")) {
        case 1:
            out = ((("\n\n" + out) + "\n") + ("".pad(strlen(out), "="))) + "\n";
        case 2:
            out = ((("\n\n" + out) + "\n") + ("".pad(strlen(out), "-"))) + "\n";
        default:
            out = ("\n" + out) + "\n";
    }
    return [out, vars];
};

public method .do_dd() {
    arg vars, flags, args;
    
    return .eval_indented(args, vars, 4);
    
    // $#Edited: 29 Nov 96 16:44 $miro
};

public method .do_b() {
    arg vars, flags, args;
    var out, a;
    
    return ._eval_ctext(args, vars);
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_i() {
    arg vars, flags, args;
    var out, a;
    
    return ._eval_ctext(args, vars);
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_dt() {
    arg vars, flags, args;
    
    vars = vars.add('header, "");
    [args, vars] = ._eval_ctext(args, vars);
    if ((| vars['columned] |))
        return ["\n  ", vars.add('header, pad("  " + args, 25))];
    else
        return [("\n  " + args) + "\n", vars.add('header, "")];
};

public method .do_li() {
    arg vars, flags, args;
    var line, type, num, depth, oheader;
    
    type = (| vars['list_type] |) || 'plain;
    depth = (| vars['list_depth] |) || 1;
    oheader = (| vars['header] |);
    if (type == 'plain) {
        if (depth % 2)
            vars = dict_add(vars, 'header, "* ");
        else
            vars = dict_add(vars, 'header, "+ ");
    } else {
        num = (vars['list_last]) + 1;
        vars = dict_add(vars, 'header, num + ") ");
        vars = dict_add(vars, 'list_last, num);
    }
    depth *= 2;
    [args, vars] = .eval_indented(args, vars, depth);
    if (oheader == ~keynf)
        vars = dict_del(vars, 'header);
    else
        vars = dict_add(vars, 'header, oheader);
    return ["\n" + args, vars];
};

public method .do_lh() {
    arg vars, flags, args;
    var line, oheader;
    
    oheader = (| vars['header] |);
    vars = dict_add(vars, 'header, "");
    [args, vars] = .eval_indented(args, vars, 2);
    if (oheader == ~keynf)
        vars = dict_del(vars, 'header);
    else
        vars = dict_add(vars, 'header, oheader);
    return [args + "\n", vars];
    
    // $#Edited: 22 Jan 97 22:12 $miro
};

public method .do_quote() {
    arg vars, flags, args;
    
    return [args[1], vars];
    
    // $#Edited: 17 Jul 96 01:20 $kahuna
    // $#Edited: 17 Jul 96 00:11 $jenner
};

public method .do_table() {
    arg vars, flags, args;
    var tblinfo, i, ntbinfo, info, width, l, lr, lc, inds, ind, cwidth;
    
    tblinfo = (| vars['table_info] |) || 0;
    width = vars['width];
    if (!(| (ntbinfo = flags.getkey("cols")) |))
        throw(~flags, "Need column information.");
    ind = (| abs(toint(flags.getkey("ind"))) |) || 0;
    info = [];
    cwidth = width - ind;
    if ("%" in ntbinfo) {
        for i in (ntbinfo.explode(","))
            info += [toint(cwidth * (toint(i) / 100.0))];
    } else {
        for i in (ntbinfo.explode(","))
            info += [toint(i)];
    }
    vars = #[['table_info, [info, 0]], ['rinfo, $list.make(info.length(), 0)], ['rcont, $list.make(info.length(), [])]].union(vars);
    [args, vars] = ._eval_ctext(args, vars);
    vars = tblinfo ? vars.add('table_info, tblinfo) : (vars.del('table_info));
    vars = vars.add('width, width);
    return ["\n" + args, vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_tr() {
    arg vars, flags, args;
    var tblinfo, rinfo, i, l, len, s, j, col, rcont, done;
    
    tblinfo = vars['table_info];
    tblinfo = tblinfo.replace(2, 0);
    rinfo = vars['rinfo];
    rcont = vars['rcont];
    vars = vars.add('table_info, tblinfo);
    l = [];
    col = 1;
    for i in (args) {
        if (type(i) != 'frob)
            throw(~table, "Only {td} tags permitted in rows");
        switch (i.method()) {
            case 'do_td:
                [i, vars] = .do_td(vars, i.ctext_flags(), i.args());
            case 'do_th:
                [i, vars] = .do_th(vars, i.ctext_flags(), i.args());
            default:
                throw(~table, "Only {td} tags permitted in rows");
        }
        l += i;
        for j in (i) {
            rcont = rcont.replace(col, (rcont[col]) + (j[3]));
            col++;
        }
    }
    l += $list.make((rcont.length()) - (l.length()), [0, 0, []]);
    s = "";
    i = 1;
    done = 0;
    rinfo = map j in [1 .. rinfo.length()] to (((rinfo[j]) - 1) + ((l[j])[1]));
    while (!done) {
        done = 1;
        for j in [1 .. rcont.length()] {
            s += ((| (rcont[j])[i] |) || "").pad((l[j])[2]);
            done = done && ((rinfo[j]) || (i >= listlen(rcont[j])));
        }
        i++;
        s += "\n";
    }
    for j in [1 .. rinfo.length()]
        rcont = rcont.replace(j, (| (rcont[j]).subrange(i) |) || []);
    vars = (vars.add('rinfo, rinfo)).add('rcont, rcont);
    return [s, vars];
    
    // $#Edited: 29 Nov 96 17:13 $miro
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .do_td() {
    arg vars, flags, args;
    var tblinfo, rinfo, col, cols, rows, w, n, max;
    
    rows = (| toint(flags.getkey("rowspan")) |) || 1;
    cols = (| toint(flags.getkey("colspan")) |) || 1;
    rinfo = vars['rinfo];
    tblinfo = vars['table_info];
    col = (tblinfo[2]) + 1;
    n = [];
    max = listlen(tblinfo[1]);
    while (rinfo[col]) {
        col++;
        n += [[0, (tblinfo[1])[col], []]];
    }
    w = ((tblinfo[1]).subrange(col, cols)).sum();
    tblinfo = tblinfo.replace(2, (col + cols) - 1);
    vars = (vars.add('table_info, tblinfo)).add('header, "");
    [args, vars] = .eval_indented(args, vars, 0, w);
    return [(n + [[rows, w, args.explode("\n", 1)]]) + ($list.make(cols - 1, [rows, 0, []])), vars];
};

public method .rewrap_lines() {
    arg vars, str, prefix;
    var s, p, n, firstline;
    
    s = [];
    n = (vars['width]) + (prefix.length());
    for str in (str.explode("\n", 1))
        s += str.wrap_lines(n, prefix, 1);
    return s.join("\n");
};

public method .eval_indented() {
    arg args, vars, i, @w;
    var width, indent;
    
    width = vars['width];
    vars = vars.add('width, (| w[1] |) || (width - i));
    [args, vars] = ._eval_ctext(args, vars);
    return [.rewrap_lines(vars, (vars['header]) + args, pad("", i)), vars.add('width, width)];
    
    // $#Edited: 29 Nov 96 16:44 $miro
};

public method .do_dfn() {
    arg vars, flags, args;
    var ind, nobound;
    
    ind = toint((| flags.getkey("ind") |) || 8);
    nobound = (| flags.getkey("nobound") |);
    vars = vars.add('header, "");
    [args, vars] = .eval_indented(args, vars, ind);
    if (nobound)
        return ["\n" + args, vars];
    return [("\n" + args) + "\n", vars];
};

public method .do_detail() {
    arg vars, flags, args;
    
    return [("[" + (flags.getkey("name"))) + "]", vars];
    
    // $#Edited: 29 Nov 96 17:14 $miro
};

public method .do_img() {
    arg vars, flags, args;
    var alt;
    
    return ["", vars];
};

public method .format() {
    arg data, vars;
    var str, len, line, out;
    
    str = (> (._eval_ctext(data, vars))[1] <);
    if ((strlen(str) < 2) || (substr(str, strlen(str) - 1) != "\n"))
        str += "\n";
    return str_to_buf(str);
};

public method .do_ol() {
    arg vars, flags, args;
    var out, token, old, last, depth;
    
    if (dict_contains(vars, 'list_type)) {
        old = vars['list_type];
        if (old == 'ordinal)
            last = vars['list_last];
        else
            last = -1;
        vars = dict_add(vars, 'list_depth, (vars['list_depth]) + 1);
    } else {
        vars = dict_add(vars, 'list_depth, 1);
    }
    vars = dict_add(vars, 'list_type, 'ordinal);
    vars = dict_add(vars, 'list_last, 0);
    [args, vars] = ._eval_ctext(args, vars);
    if (old) {
        vars = dict_add(vars, 'list_type, old);
        if ((old == 'ordinal) && (last != (-1)))
            vars = dict_add(vars, 'list_last, last);
        vars = dict_add(vars, 'list_depth, (vars['list_depth]) - 1);
    } else {
        vars = dict_del(vars, 'list_type);
        if (dict_contains(vars, 'list_last))
            vars = dict_del(vars, 'list_last);
        vars = dict_del(vars, 'list_depth);
    }
    return [args, vars];
};

public method .do_np() {
    arg vars, flags, args;
    
    return ["\n\n", vars];
};


new object $wrapped_text_format: $text_format;

var $root manager = $wrapped_text_format;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 848777209;
var $root inited = 1;
var $root managed = [$wrapped_text_format];
var $root child_index = 1;

public method .format() {
    arg data, vars;
    var str, len, line, out;
    
    str = (> (._eval_ctext(data, vars))[1] <);
    if ((strlen(str) < 2) || (substr(str, strlen(str) - 1) != "\n"))
        str += "\n";
    
    // ugly and inneficient--use a client people
    len = (vars['receiver]).linelen();
    out = "";
    for line in (explode(str, "\n"))
        out += (line.wrap_line(len, " ")) + "\n";
    return str_to_buf(out);
};


new object $plaintext_format: $wrapped_text_format;

var $root manager = $plaintext_format;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858615622;
var $root inited = 1;
var $root managed = [$plaintext_format];

public method .do_link() {
    arg vars, flags, args;
    
    return ._eval_ctext(args[1], vars);
};

public method .format() {
    arg data, vars;
    var str, len, line, out;
    
    str = (> (._eval_ctext(data, vars))[1] <);
    if ((strlen(str) < 2) || (substr(str, strlen(str) - 1) != "\n"))
        str += "\n";
    
    // ugly and inneficient--use a client people
    len = (vars['receiver]).linelen();
    out = "";
    for line in (explode(str, "\n", 1))
        out += (line.wrap_line(len, "")) + "\n";
    return str_to_buf(out);
};


new object $html_format: $formatter;

var $root manager = $html_format;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837902808;
var $root inited = 1;
var $root managed = [$html_format];
var $root owned = [$html_format];

public method .do_hr() {
    arg vars, flags, args;
    
    return ["\n<hr>\n", vars];
    
    // $#Edited: 20 Jul 96 12:28 $kahuna
    // $#Edited: 20 Jul 96 16:46 $jenner
};

public method .do_ul() {
    arg vars, flags, args;
    var out, header, line, token;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [("\n<ul>\n" + args) + "\n</ul>\n", vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_th() {
    arg vars, flags, args;
    var f, n, c, width;
    
    c = vars['table_col];
    vars = vars.add('table_col, c + 1);
    width = (| (vars['table_cols])[c] |);
    f = "";
    if ((n = (| flags.getkey("rowspan") |)))
        f += " rowspan=" + n;
    if ((n = (| flags.getkey("colspan") |)))
        f += " colspan=" + n;
    if (width)
        f += (" width=\"" + width) + "\"";
    [args, vars] = ._eval_ctext(args, vars);
    return [((("\n<th align=left valign=top" + f) + ">") + args) + "</td>", vars];
};

public method .do_dl() {
    arg vars, flags, args;
    var out, token, c, cm;
    
    c = (| vars['columned] |);
    cm = (| flags.getkey("columned") |) || 0;
    vars = vars.add('columned, cm);
    [args, vars] = ._eval_ctext(args, vars);
    if (c)
        vars = vars.add('columned, c);
    else if (vars.contains('columned))
        vars = vars.del('columned);
    if (cm)
        return [("\n<blockquote><table cols=2 border=0>\n" + args) + "\n</table></blockquote>\n", vars];
    return [("\n<dl>\n" + args) + "\n</dl>\n", vars];
};

public method .do_anchor() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext([args[1]], vars);
    return [[("/" + (args[1])) + "/"], vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_p() {
    arg vars, flags, args;
    
    return ["\n<p>\n", vars];
    
    // $#Edited: 20 Jul 96 12:28 $kahuna
    // $#Edited: 20 Jul 96 16:46 $jenner
};

public method .do_em() {
    arg vars, flags, args;
    var out, a;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [("<em>" + args) + "</em>", vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_br() {
    arg vars, flags, args;
    
    return ["\n<br>", vars];
    
    // $#Edited: 20 Jul 96 12:28 $kahuna
    // $#Edited: 20 Jul 96 16:46 $jenner
};

public method .do_link() {
    arg vars, flags, args;
    var node;
    
    [args, vars] = ._eval_ctext([args[1]], vars);
    node = (| flags.getkey("node") |);
    if (node)
        return [((("<a href=\"/bin/help?node=" + node) + "\">") + args) + "</a>", vars];
    return ["&gt;&gt;ERROR: Invalid node&lt;&lt;", vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_web() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext([args[1]], vars);
    return [((((args + "<a href=\"") + (flags.getkey("src"))) + "\">") + (flags.getkey("name"))) + "</a>", vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_tt() {
    arg vars, flags, args;
    var out, a;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [("<tt>" + args) + "</tt>", vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_action() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args[1], vars);
    (| (vars['receiver]).register_action(args, vars['this], flags.getkey("token")) |);
    return [("\\" + args) + "\\", vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_subj() {
    arg vars, flags, args;
    var out, word, l;
    
    [args, vars] = ._eval_ctext(args, vars);
    l = (| flags.getkey("level") |) || "4";
    return [((((("<h" + l) + ">") + args) + "</h") + l) + ">\n", vars];
};

public method .do_dd() {
    arg vars, flags, args;
    var c;
    
    c = (| vars['columned] |);
    [args, vars] = ._eval_ctext(args, vars);
    if (c)
        return [("<td>" + args) + "</td></tr>", vars];
    return ["<dd>" + args, vars];
};

public method .do_b() {
    arg vars, flags, args;
    var out, a;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [("<b>" + args) + "</b>", vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_i() {
    arg vars, flags, args;
    var out, a;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [("<i>" + args) + "</i>", vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_dt() {
    arg vars, flags, args;
    var term, c;
    
    c = (| vars['columned] |);
    [args, vars] = ._eval_ctext(args, vars);
    if (c)
        return [("\n<tr><td>" + args) + "</td>", vars];
    return ["\n<dt>" + args, vars];
};

public method .do_li() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return ["\n<li>" + args, vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_lh() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return ["\n<lh>" + args, vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_tr() {
    arg vars, flags, args;
    
    vars = vars.add('table_col, 1);
    [args, vars] = ._eval_ctext(args, vars);
    return [("\n<tr>" + args) + "</tr>", vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_td() {
    arg vars, flags, args;
    var f, n, c, width;
    
    c = vars['table_col];
    vars = vars.add('table_col, c + 1);
    width = (| (vars['table_cols])[c] |);
    f = "";
    if ((n = (| flags.getkey("rowspan") |)))
        f += " rowspan=" + n;
    if ((n = (| flags.getkey("colspan") |)))
        f += " colspan=" + n;
    if (width)
        f += (" width=\"" + width) + "\"";
    [args, vars] = ._eval_ctext(args, vars);
    return [((("\n<td valign=top" + f) + ">") + args) + "</td>", vars];
};

public method .do_table() {
    arg vars, flags, args;
    var cols, tcs, tc;
    
    tcs = (| vars['table_cols] |);
    tc = (| vars['table_col] |);
    if ((cols = (| flags.getkey("cols") |)) && ("%" in cols))
        vars = vars.add('table_cols, cols.explode(","));
    [args, vars] = ._eval_ctext(args, vars);
    vars = tcs ? vars.add('table_cols, tcs) : (vars.del('table_cols));
    vars = tc ? vars.add('table_col, tc) : (vars.del('table_col));
    return [("\n<table border=0>" + args) + "\n</table>\n", vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_dfn() {
    arg vars, flags, args;
    var out, a;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [("\n<blockquote>" + args) + "</blockquote>", vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_quote() {
    arg vars, flags, args;
    
    return [("<pre>" + ((((args[1]).replace("&", "&amp;")).replace("<", "&lt;")).replace(">", "&gt;"))) + "</pre>", vars];
    
    // $#Edited: 01 Aug 96 21:59 $jenner
};

public method .do_detail() {
    arg vars, flags, args;
    var det;
    
    det = flags.getkey("name");
    return [((((("<a href=\"/bin/describe?target=" + ((vars['this]).objname())) + "&detail=") + ($http.encode(det))) + "\">") + det) + "</a></b>", vars];
};

public method .do_img() {
    arg vars, flags, args;
    var src, html, alt;
    
    src = flags.getkey("src");
    alt = (| ("alt=\"" + (flags.getkey("alt"))) + "\"" |) || "";
    return [((("<img src=\"" + src) + "\" align=left hspace=10 ") + alt) + ">", vars];
};

public method ._eval_ctext() {
    arg data, vars;
    var out, uflags, token;
    
    out = "";
    if (type(data) != 'list)
        data = [data];
    for token in (data) {
        refresh();
        switch (type(token)) {
            case 'frob:
                switch (class(token)) {
                    case $generator:
                        [token, vars] = ((| vars['evaluator] |) || $bs_eval).eval_generator(token, vars);
                        if (type(token) == 'string) {
                            out += token;
                        } else {
                            [token, vars] = ._eval_ctext(token, vars);
                            out += token;
                        }
                    case $format:
                        [token, vars] = .eval_formatter(token, vars);
                        out += token;
                }
            case 'string:
                out += token.to_html();
            case 'list:
                [token, vars] = ._eval_ctext(token, vars);
                out += token;
            default:
                out += token;
        }
    }
    return [out, vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .format() {
    arg data, vars;
    var str, len, line, out;
    
    str = (> (._eval_ctext(data, vars))[1] <);
    if ((strlen(str) < 2) || (substr(str, strlen(str) - 1) != "\n"))
        str += "\n";
    return str_to_buf(str + "\n");
};

public method .do_ol() {
    arg vars, flags, args;
    var out, header, line, token;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [("\n<ol>\n" + args) + "\n</ol>\n", vars];
};

public method .do_np() {
    arg vars, flags, args;
    
    return ["\n<p>\n", vars];
};

public method .eval_formatter() {
    arg form, vars;
    var flags, i, text;
    
    form = form.eval_flags(vars);
    catch ~methodnf {
        return .(form[4])(vars, form[2], form[3]);
    } with {
        [text, vars] = ._eval_ctext(form[3], vars);
        if ((vars['time]) == 'post)
            return ["<%l%l>%l</%l>".format(form[1], map i in (form[2]) to ((((" " + (i[1])) + "=\"") + (i[2])) + "\"").join(""), text, form[1]), vars];
        form = (<$format, [form[1], form[2], text, form[4]]>);
        return [[form], vars];
    }
    
    // $#Edited: 23 Jan 97 20:49 $miro
    // $#Copied 29 Jan 97 00:55 from $formatter.eval_formatter() by $miro
};


new object $uncompiler: $evaluator;

var $root manager = $uncompiler;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 837583986;
var $root inited = 1;
var $root managed = [$uncompiler];
var $root owned = [$uncompiler];

public method .quote() {
    arg s;
    
    return s.sed("([][{}\])", "\%1", "g");
    
    // $#Edited: 21 Nov 96 18:41 $miro
};

public method .eval_generator() {
    arg gen, vars;
    var out, flags, key, value, text;
    
    catch ~methodnf {
        return .(gen.method())(vars, gen.ctext_flags(), gen.args());
    } with {
        out = ["[" + (gen.name())];
        flags = gen.ctext_flags();
        for key in (flags) {
            if ((key[2]) == 1) {
                out = out.affix(" " + (key[1]));
            } else {
                [text, vars] = (> ._eval_ctext([key[2]], vars, 1) <);
                out = (out.affix((" " + (key[1])) + "=")).affix(text);
            }
        }
        if (gen.args()) {
            out = out.affix(":");
            for key in (gen.args()) {
                [text, vars] = (> ._eval_ctext([key], vars) <);
                out = out.affix(text);
            }
        }
        return [out.affix("]"), vars];
    }
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method ._eval_ctext() {
    arg data, vars, @quote_all;
    var out, uflags, token, prev, next, t;
    
    out = [];
    if (type(data) != 'list)
        data = [data];
    prev = 0;
    token = 0;
    for next in (data + [0]) {
        t = token;
        switch (type(token)) {
            case 'integer:
            case 'frob:
                if (class(token) == $generator) {
                    [token, vars] = (> .eval_generator(token, vars) <);
                    out = out.affix(token);
                } else if (class(token) == $format) {
                    [token, vars] = (> .eval_formatter(token, vars) <);
                    out = out.affix(token);
                }
            case 'string:
                token = quote_all ? .quote_all(token) : (.quote(token));
                token = ._spaces(token, prev, 'prev);
                token = ._spaces(token, next, 'next);
                out = out.affix(token);
            default:
                out = out.affix(toliteral(token));
        }
        prev = t;
        token = next;
    }
    return [out, vars];
    
    // $#Edited: 22 Jan 97 15:32 $miro
};

public method .eval_formatter() {
    arg gen, vars;
    var out, flags, key, value, text;
    
    catch ~methodnf {
        return .(gen.method())(vars, gen.ctext_flags(), gen.args());
    } with {
        out = ["{" + (gen.name())];
        flags = gen.ctext_flags();
        for key in (flags) {
            if ((key[2]) == 1) {
                out = out.affix(" " + (key[1]));
            } else {
                [text, vars] = ._eval_ctext(key[2], vars, 1);
                out = (out.affix((" " + (key[1])) + "=")).affix(text);
            }
        }
        if (gen.args()) {
            out = out.affix(":");
            for key in (gen.args()) {
                [text, vars] = ._eval_ctext([key], vars);
                out = out.affix(text);
            }
        }
        out = out.affix("}");
        return [out, vars];
    }
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .quote_all() {
    arg s;
    
    return s.sed("([][{}\:= ])", "\%1", "g");
    
    // $#Edited: 21 Nov 96 18:40 $miro
};

public method .do_quote() {
    arg vars, flags, args;
    
    return [(["{quote "].affix((args[1]).explode("\n", 1))).affix("}"), vars];
    
    // $#Edited: 02 Aug 96 18:01 $jenner
};

public method .do_detail() {
    arg vars, flags, args;
    
    return .eval_formatter((<$format, ["detail", flags, (| (vars['details])[flags.getkey("name")] |) || ["UNKNOWN"], 'DO_NOT_CALL_THIS]>), vars);
    
    // $#Edited: 30 Oct 96 23:38 $miro
    // $#Edited: 29 Nov 96 16:29 $miro
};

public method .do_p() {
    arg vars, flags, args;
    
    return [["", "{p}"], vars];
};

public method .do_dl() {
    arg vars, flags, args;
    var dl, token;
    
    if ((| flags.getkey("columned") |))
        dl = "{dl columned:";
    else
        dl = "{dl:";
    [args, vars] = ._eval_ctext(args, vars);
    return [((["", dl].affix(args.prefix("  "))).affix("}")) + [""], vars];
    
    // $#Edited: 29 Nov 96 16:31 $miro
};

public method .do_dt() {
    arg vars, flags, args;
    var dl, token;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [(["", "{dt: "].affix(args)).affix("}"), vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_dd() {
    arg vars, flags, args;
    var token;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [(["", "{dd: "].affix(args)).affix("}"), vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_dfn() {
    arg vars, flags, args;
    var nobound, ind, dfn;
    
    ind = (| flags.getkey("ind") |) || 8;
    nobound = (| flags.getkey("nobound") |);
    dfn = "{dfn";
    if (nobound)
        dfn += " nobound";
    if (ind && (ind != 8))
        dfn += " ind=" + ind;
    [args, vars] = ._eval_ctext(args, vars);
    if (nobound)
        return [(["", ("    " + dfn) + ":"].affix(args)).affix(["}"]), vars];
    return [(["", "", ("    " + dfn) + ":"].affix(args)).affix(["}"]), vars];
};

public method .do_subj() {
    arg vars, flags, args;
    var out, word, l;
    
    [args, vars] = ._eval_ctext(args, vars);
    l = toint((| flags.getkey("level") |) || "4");
    return [(["", "", ("{subj level=" + l) + ":"].affix(args)).affix(["}"]), vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_ul() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [((["", "{ul:"].affix(args.prefix("  "))).affix("}")) + [""], vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_li() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [(["", "{li:"].affix(args)).affix("}"), vars];
    
    // $#Edited: 29 Nov 96 16:22 $miro
};

public method .do_td() {
    arg vars, flags, args;
    var opts, value;
    
    if ((value = (| toint(flags.getkey("rowspan")) |)))
        opts = " rowspan=" + value;
    else
        opts = "";
    if ((value = (| toint(flags.getkey("colspan")) |)))
        opts += " colspan=" + value;
    [args, vars] = ._eval_ctext(args, vars);
    return [(["", ("  {td" + opts) + ":"].affix(args)).affix("}"), vars];
};

public method .do_tr() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [(["", "{tr:"].affix(args)).affix("}"), vars];
};

public method .do_lh() {
    arg vars, flags, args;
    
    [args, vars] = ._eval_ctext(args, vars);
    return [(["", "{lh:"].affix(args)).affix("}"), vars];
};

public method .gen_switch() {
    arg vars, flags, args;
    var i, j, out, def, ret, val, l, lower, upper, val;
    
    def = [""];
    [val, vars] = ._eval_ctext(flags.getkey("value"), vars);
    out = [""];
    for i in (args) {
        [ret, vars] = ._eval_ctext(i[2], vars);
        if ((i[1]) == 'default) {
            def = ["", "[default]", ""].affix(ret.prefix("  "));
        } else if ((i[1]) == 'ranges) {
            for j in (i[2]) {
                [lower, upper, ret] = j;
                [ret, vars] = ._eval_ctext(ret, vars);
                out = (out.affix(["", ((("[range:" + lower) + "..") + upper) + "]", ""])).affix(ret.prefix("  "));
            }
        } else {
            out = (out.affix(["", ("[case:" + (i[1])) + "]", ""])).affix(ret.prefix("  "));
        }
    }
    return [(((["", "[switch value="].affix(val)).affix(":")).affix((out.affix(def)).prefix("  "))).affix(["]", ""]), vars];
    
    // $#Edited: 22 Jan 97 16:37 $miro
};

public method ._spaces() {
    arg token, other, dir;
    var m, i;
    
    if ((type(other) == 'frob) && ((other.name()) in ($compiler.glue_table()))) {
        if (dir == 'prev) {
            m = ((token.regexp("^ *"))[1]).length();
            return ("".pad(m * 2, "\ ")) + (token.subrange(m + 1));
        } else {
            m = ((token.regexp(" *$"))[1]).length();
            return (token.subrange(1, (token.length()) - m)) + ("".pad(m * 2, "\ "));
        }
    }
    return token;
    
    // $#Edited: 22 Jan 97 21:24 $miro
    // $#Edited: 22 Jan 97 21:41 $miro
};

public method .do_th() {
    arg vars, flags, args;
    var opts, value;
    
    if ((value = (| toint(flags.getkey("rowspan")) |)))
        opts = " rowspan=" + value;
    else
        opts = "";
    if ((value = (| toint(flags.getkey("colspan")) |)))
        opts += " colspan=" + value;
    [args, vars] = ._eval_ctext(args, vars);
    return [(["", ("  {th" + opts) + ":"].affix(args)).affix("}"), vars];
};

public method .do_np() {
    arg vars, flags, args;
    
    return [["", "", "{np}"], vars];
};

public method .do_br() {
    arg vars, flags, args;
    
    return [["", "{br}"], vars];
    
    // $#Edited: 23 Jan 97 15:40 $brandon
};


new object $housekeeper: $utilities;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $root manager = $housekeeper;
var $root owned = [$housekeeper];
var $root managed = [$housekeeper];

public method .did_disconnect() {
    var task_queue, task;
    
    if (caller() != $user)
        throw(~perm, "Permission denied");
    
    // because of guests
    if (valid(sender()))
        $scheduler.add_task(300, 'move_user_home, sender());
};

public method .move_user_home() {
    arg who;
    var home, curloc;
    
    if (who.connected())
        return;
    (| who.cleanup_sessions() |);
    curloc = who.location();
    home = who.home();
    if (curloc == home)
        return;
    (| who.move_to(home) |) || (> who.move_to($body_cave) <);
    curloc.did_housekeep(who);
};


new object $word: $utilities;

var $root manager = $word;
var $word syllables = #[[2, 3], [3, 4]];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856377068;
var $root inited = 1;
var $word syllable_pat = #[[["V"], 2], [["V", "LC"], 6], [["C", "V"], 8]];
var $word firstcons = #[["th", 1], ["b", 5], ["f", 9], ["qu", 10]];
var $word vowels = #[["a", 10], ["e", 20], ["i", 30]];
var $root help_node = $help_sys_word;
var $root child_index = 2;
var $word lastcons = #[["bh", 1], ["d", 5], ["b", 9]];
var $root managed = [$word];

public method .set_chances() {
    arg what, value;
    var out, last, v, chance;
    
    (> .perms(sender()) <);
    
    // chances are received as a #[["what", chance]] dict
    // which is converted where the chance is a cumulative range of the total
    out = #[];
    for v in (value) {
        chance = v[2];
        out = dict_add(out, v[1], chance + last);
        last += chance;
    }
    set_var(what, out);
    return get_var(what);
    
    // $#Edited: 19 Feb 97 11:53 $brandon
};

public method .vowels() {
    return vowels;
};

public method .lastcons() {
    return lastcons;
};

public method .firstcons() {
    return firstcons;
};

public method .syllables() {
    return syllables;
};

public method .syllable_pat() {
    return syllable_pat;
};

public method .pick_value() {
    arg name;
    var top, pick, v, last;
    
    top = dict_values(get_var(name)).last();
    pick = random(top);
    for v in (get_var(name)) {
        if ((v[2]) > pick) {
            if (!last)
                return v[1];
            return last;
        }
        last = v[1];
    }
    return last;
};

public method .generate() {
    var x, y, out, pat, p;
    
    out = "";
    for x in [1 .. .pick_value('syllables)] {
        pat = .pick_value('syllable_pat);
        for p in (pat) {
            switch (p) {
                case "V":
                    out += .pick_value('vowels);
                case "C":
                    out += .pick_value('firstcons);
                case "LC":
                    out += .pick_value('lastcons);
                default:
                    throw(~invpat, "Invalid syllable pattern: " + pat);
            }
        }
    }
    return out.capitalize();
};

public method .submit_chances() {
    arg lines;
    var line, linec, s, sp, v, fc, lc, val, chance, vsp, part;
    
    s = (sp = (v = (fc = (lc = #[]))));
    for line in (lines) {
        linec++;
        if (match_regexp(line, " *#"))
            continue;
        line = line.explode_quoted();
        if (!line)
            continue;
        if (listlen(line) != 3)
            throw(~bad, (("Line " + linec) + ": Invalid config: ") + (line.join()));
        chance = toint(line[3]);
        if (!chance)
            throw(~bad, ("Line " + linec) + ": Chance must be one or more.");
        switch (line[1]) {
            case "S":
                val = toint(line[2]);
                if (!val)
                    throw(~bad, ("Line " + linec) + ": Syllables must be one or more.");
                s = s.add(val, chance);
            case "SP":
                val = line[2];
                val = explode(uppercase(strsed(val, "[^CVL-]+", "")), "-");
                if (filter part in (val) where (!(part in ["C", "V", "LC"])))
                    throw(~bad, ("Line " + linec) + ": Invalid syllable pattern");
                sp = sp.add(val, chance);
            case "C":
                if (!(line[2]))
                    throw(~bad, ("Line " + linec) + ": Invalid consanant");
                fc = fc.add(line[2], chance);
            case "LC":
                if (!(line[2]))
                    throw(~bad, ("Line " + linec) + ": Invalid consanant");
                lc = lc.add(line[2], chance);
            case "V":
                if (!(line[2]))
                    throw(~bad, ("Line " + linec) + ": Invalid vowel");
                v = v.add(line[2], chance);
            default:
                throw(~bad, (("Line " + linec) + ": Invalid directive: ") + (line[1]));
        }
        refresh();
    }
    .set_chances('syllables, s);
    .set_chances('syllable_pat, sp);
    .set_chances('firstcons, fc);
    .set_chances('lastcons, lc);
    .set_chances('vowels, v);
};

public method .format_chances() {
    return ((((((((.format_dict(syllables, "S")) + [""]) + (.format_dict(syllable_pat, "SP"))) + [""]) + (.format_dict(vowels, "V"))) + [""]) + (.format_dict(firstcons, "C"))) + [""]) + (.format_dict(lastcons, "LC"));
};

public method .format_dict() {
    arg dict, cmd;
    var out, v, last, num;
    
    out = [];
    for v in (dict) {
        num = (v[2]) - last;
        last = v[2];
        if ((type(v[1]) == 'string) && (" " in (v[1])))
            out += [(((cmd + " \"") + (v[1])) + "\" ") + num];
        if (type(v[1]) == 'list)
            out += [(((cmd + " ") + ((v[1]).join("-"))) + " ") + num];
        else
            out += [(((cmd + " ") + (v[1])) + " ") + num];
    }
    return out;
};


new object $lovecraft_word: $word;

var $root manager = $lovecraft_word;
var $word vowels = #[["a", 580], ["aa", 598], ["ae", 600], ["ah", 611], ["ai", 643], ["au", 657], ["aw", 658], ["ay", 660], ["e", 847], ["ea", 848], ["ee", 857], ["eh", 860], ["ei", 872], ["eu", 874], ["i", 1110], ["ie", 1113], ["ih", 1114], ["ii", 1115], ["o", 1423], ["oh", 1424], ["oi", 1432], ["oo", 1447], ["ou", 1473], ["ow", 1475], ["oy", 1476], ["u", 1590], ["uh", 1591], ["uu", 1594], ["y", 1638], ["ya", 1651], ["ye", 1652], ["yeh", 1653], ["yi", 1657], ["yo", 1667], ["yoh", 1668], ["yu", 1674]];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856378321;
var $root inited = 1;
var $word lastcons = #[["b", 20], ["bn", 21], ["c", 42], ["ch", 48], ["d", 74], ["f", 79], ["g", 107], ["gh", 110], ["gn", 111], ["j", 112], ["k", 133], ["l", 214], ["lf", 215], ["ll", 216], ["lp", 217], ["lt", 219], ["lth", 220], ["m", 278], ["mb", 279], ["mh", 280], ["mr", 281], ["ms", 283], ["n", 434], ["nd", 437], ["ng", 449], ["ngh", 451], ["nn", 452], ["ns", 453], ["nt", 457], ["nth", 458], ["p", 464], ["ph", 469], ["ps", 471], ["q", 473], ["qh", 474], ["r", 608], ["rc", 609], ["rd", 611], ["rg", 613], ["rgh", 614], ["rh", 616], ["rn", 619], ["rp", 620], ["rph", 621], ["rrh", 622], ["rt", 623], ["rth", 628], ["s", 730], ["sh", 734], ["sht", 735], ["sk", 739], ["st", 742], ["t", 767], ["th", 820], ["tl", 821], ["v", 823], ["x", 830], ["z", 842]];
var $word firstcons = #[["b", 58], ["bh", 59], ["bhl", 60], ["br", 63], ["c", 117], ["ch", 137], ["chth", 138], ["cl", 141], ["cr", 145], ["cth", 148], ["d", 218], ["dh", 221], ["djh", 223], ["dl", 224], ["dr", 227], ["dw", 229], ["dz", 230], ["f", 245], ["fr", 247], ["g", 297], ["gh", 308], ["ghl", 309], ["gl", 310], ["gn", 314], ["gr", 316], ["h", 360], ["hl", 361], ["hs", 362], ["j", 370], ["k", 404], ["kh", 406], ["kl", 408], ["kr", 409], ["kth", 410], ["l", 557], ["ll", 558], ["m", 669], ["mh", 670], ["ml", 671], ["mm", 672], ["mn", 673], ["mth", 674], ["n", 781], ["ngr", 782], ["nh", 783], ["nl", 785], ["p", 819], ["ph", 838], ["phl", 839], ["phr", 840], ["pn", 844], ["pr", 846], ["ps", 847], ["pt", 848], ["qu", 864], ["r", 977], ["rh", 980], ["rl", 982], ["rr", 983], ["s", 1048], ["sf", 1049], ["sh", 1065], ["sk", 1066], ["sn", 1068], ["sng", 1069], ["st", 1070], ["str", 1072], ["t", 1143], ["th", 1199], ["thr", 1202], ["tl", 1203], ["tn", 1204], ["tr", 1207], ["ts", 1211], ["tsch", 1212], ["v", 1254], ["vhl", 1255], ["vl", 1256], ["vr", 1257], ["w", 1266], ["x", 1275], ["z", 1318], ["zh", 1323], ["zk", 1324]];
var $word syllable_pat = #[[["V"], 1], [["V", "LC"], 2], [["C", "V"], 6], [["C", "V", "LC"], 10]];
var $word syllables = #[[1, 3], [2, 8], [3, 13], [4, 16], [5, 17]];
var $root managed = [$lovecraft_word];


new object $password: $word;

var $root manager = $password;
var $word syllables = #[[3, 1], [4, 2]];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 856543004;
var $root inited = 1;
var $word syllable_pat = #[[["V"], 2], [["V", "C"], 7], [["C", "V"], 12], [["C", "V", "C"], 13]];
var $word firstcons = #[["b", 50], ["c", 100], ["d", 150], ["bd", 160], ["f", 210], ["g", 260], ["h", 310], ["j", 360], ["k", 410], ["l", 460], ["m", 510], ["n", 560], ["p", 610], ["qu", 640], ["q", 650], ["r", 700], ["s", 750], ["t", 800], ["v", 803], ["w", 813], ["x", 814], ["y", 821], ["z", 822], ["th", 847]];
var $word lastcons = #[];
var $word vowels = #[["a", 500], ["aa", 501], ["ae", 547], ["ai", 585], ["ao", 587], ["au", 621], ["ah", 629], ["ay", 643], ["e", 1143], ["ea", 1242], ["ee", 1281], ["ei", 1307], ["eo", 1348], ["eu", 1376], ["ey", 1384], ["i", 1884], ["ia", 2034], ["ie", 2073], ["ii", 2077], ["io", 2229], ["iu", 2246], ["o", 2646], ["oa", 2670], ["oe", 2687], ["oi", 2727], ["ou", 2855], ["oy", 2860], ["u", 2985], ["ua", 3012], ["ue", 3031], ["ui", 3056], ["y", 3101]];
var $root managed = [$password];

public method .generate() {
    var out, v, c;
    
    return lowercase(pass());
    out = lowercase(pass());
    for v in [1 .. strlen(out)] {
        if (random(4) == 1) {
            if (random(2) == 1) {
                c = uppercase(out[v]);
                out = (substr(out, 1, v - 1) + c) + substr(out, v + 1);
            } else {
                out = (substr(out, 1, v) + (random(10) - 1)) + substr(out, v + 1);
            }
        }
    }
    return out;
};


new object $settings: $utilities;

var $root manager = $settings;
var $root managed = [$settings];
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 857619568;
var $root inited = 1;

public method .is_type() {
    arg value, type;
    
    if (type(value) == type)
        return value;
    switch (type) {
        case 'integer:
            if (value.is_numeric())
                return toint(value);
            else
                throw(~type, "Value is unparseable as integer.");
        case 'objnum:
            return (> $object_lib.to_dbref(value) <);
        default:
            return value;
    }
};

public method .format_boolean() {
    arg value;
    
    if (value)
        return "yes";
    else
        return "no";
};

public method .is_boolean() {
    arg value;
    var bool;
    
    if ((bool = value.is_boolean()) == (-1))
        throw(~invtype, ("Value \"" + value) + "\" is not boolean.");
    return bool;
};

public method .format_onoff() {
    arg value;
    
    if (value)
        return "on";
    else
        return "off";
};

public method .format_object() {
    arg value;
    
    return value.namef('xref);
    
    // $#Edited: 21 Mar 97 15:56 $brandon
};


new object $world: $utilities, $event_handler;

var $root manager = $world;
var $world starting_place = $the_pit;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 850845715;
var $root inited = 1;
var $root managed = [$world];
var $event_handler events = 0;
var $event_handler hooks = #[['realm_announce, [#12397, #2]]];
var $event_handler hooked = #[[#2, ['realm_announce]]];
var $root trusted = [$realm];

public method .starting_place() {
    return starting_place || $body_cave;
    
    // $#Edited: 17 Dec 96 11:04 $brandon
};

public method .startup();

public method .shutdown() {
    // $#Edited: 16 Feb 97 10:46 $user_vang
};

public method .send_event() {
    arg @args;
    
    (> .perms(caller(), 'trusts) <);
    pass(@args);
    
    // $#Edited: 07 Mar 97 16:32 $miro
};


new object $motd: $utilities;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $motd server_name = "the Cold Dark";
var $motd notes = [];
var $motd server_title = "Virtual Environment Server";
var $motd connect_help = ["Connection HELP", "===============", "", "Connecting as a guest:    'connect-guest <name> <email>'", "              Example:    'connect-guest John Doe johnd@site.usa.com'", "", "Connecting as a user:     'connect <name> <password>'", "             Example:     'connect John Doe mypassword'", "", "Quitting (this screen):   '@quit'   or   'quit'", "", "Connected Users Listing: '@who'    or   'who'"];
var $motd server_url = "http://none:1180/";
var $root manager = $motd;
var $root managed = [$motd];
var $root owned = [$motd];
var $root defined_settings = #[["server-name", #[['get, ['get_server_name_setting]], ['set, ['set_server_name_setting]]]], ["server-title", #[['get, ['get_server_title_setting]], ['set, ['set_server_title_setting]]]]];

public method .build() {
    arg @args;
    var output, out;
    
    output = [];
    if (!args)
        args = ['long, 'quote];
    if ((args[1]) == 'default)
        args = ['name, "", 'title, "", "", 'quote, "", 'notes, "", 'admins, 'connected, 'core_version, 'driver_version];
    while (args) {
        if (type(args[1]) == 'string) {
            output += [""];
        } else {
            switch (args[1]) {
                case 'long:
                    args = ['title, 'long_name] + sublist(args, 2);
                    continue;
                case 'short:
                    args = ['title, 'name] + sublist(args, 2);
                    continue;
                case 'title:
                    output += [server_title.center(79)];
                case 'name:
                    output += [(("+ " + server_name) + " +").center(79)];
                case 'notes:
                    output += notes.center_lines(79);
                case 'quote:
                    output += ($code_lib.random_quote()).center_lines(79);
                case 'admins:
                    out = $list.to_english($list.mmap($sys.admins(), 'name));
                    out = ("Administrators: " + out).center(79);
                    output += [out];
                case 'connected:
                    out = "Currently Connected users: ";
                    out += tostr(($user_db.connected()).length());
                    out = out.center(79);
                    output += [out];
                case 'version:
                    args = ['driver_version, 'core_version] + sublist(args, 2);
                    continue;
                case 'driver_version:
                    out = "Driver: " + ($sys.server_info('driver_version, 'long));
                    output += [out.center(79)];
                case 'core_version:
                    out = "Core: " + ($sys.server_info('core_version, 'long));
                    output += [out.center(79)];
            }
        }
        args = delete(args, 1);
    }
    return output;
};

public method .set_motd() {
    arg what, value;
    
    (> .perms(sender()) <);
    if (!(what in (.variables())))
        throw(~motd, (toliteral(what) + " is not a valid motd variable, try one of: ") + toliteral(.variables()));
    if (!(type(value) in ['string, 'list]))
        throw(~motd, "Value must be sent as a string or a list of strings.");
    set_var(what, value);
};

public method .build_html() {
    arg @args;
    
    return [("<head><title>" + server_name) + "</title></head>", "<body bgcolor=\"#000000\" text=\"#ffefef\" link=\"#b000f0\" vlink=\"#9000c0\" alink=\"#f000f0\">", "<p align=center><img src=\"http://www.cold.org/images/tCD.gif\" alt=\"The Cold Dark\"></p>", ("<h3 align=center>" + server_title) + "</h3>", "<p align=center><tt>", @$code_lib.random_quote(), "</tt></p>", "<p align=center>", @notes, "</p>", ("<p align=center>Administrators: " + ((($sys.admins()).mmap('hname)).to_english())) + "<br>", ("<a href=\"/bin/who\">Currently Connected users</a>: " + tostr($user_db.total_connected())) + "<br>", ("Server Lag: " + ($lag_watcher.lag())) + " seconds.<br>", "Driver: <b><a href=\"http://www.cold.org/Software/Genesis/\">Genesis</a></b> " + ($sys.server_info('driver_version)), ("<br>Core: <b>" + ($sys.server_info('core_version, 'long))) + "</b>", ("<p align=center><a href=\"http://" + ($sys.server_info('server_hostname))) + "/login/\"><b><i>Enter the Cold Dark</i></b></a>", "<p align=center>The Cold Dark is a Virtual Environment System.  There is no game in the Cold Dark, the purpose is to create a core which expands the physicality of a Virtual Environment.  To further explore the database, follow the <a href=\"/start.html\">Database Starting Points</a> link.</p>", "<hr>", "<p align=center>", "<a href=\"/history.html\"><b>History</b></a> |", "<a href=\"/features.html\"><b>Features</b></a> |", "<a href=\"http://www.cold.org/Intro/\"><b>Introduction</b></a> |", "<a href=\"/start.html\"><b>DB Starting Points</b></a>", "</p>"];
};

public method .server_name() {
    return server_name;
};

public method .server_title() {
    return server_title;
};

public method .connect_help() {
    return connect_help;
};

public method .set_connect_help() {
    arg text;
    
    (> .perms(sender(), 'manager) <);
    connect_help = text;
};

public method .server_url() {
    return ((("http://" + ($network.hostname())) + ":") + ($http_daemon.current_port())) + "/";
};

root method .core_motd() {
    server_url = "http://none:1180/";
};

public method .get_server_title_setting() {
    arg @args;
    
    return server_title;
};

protected method .set_server_title_setting() {
    arg name, definer, value, @args;
    
    server_title = value;
};

public method .get_server_name_setting() {
    arg @args;
    
    return server_name;
};

protected method .set_server_name_setting() {
    arg name, definer, value, @args;
    
    server_name = value;
};


new object $antisocial: $user_interfaces;

var $root manager = $antisocial;
var $root flags = ['variables, 'methods, 'code, 'command_cache, 'fertile, 'core];
var $root created_on = 838182893;
var $antisocial antisocial_msgs = #[["feh", <$ctext_frob, [[<$generator, ["actor", [], [], 'gen_actor]>, " kicks ", <$generator, ["who", [], [], 'gen_who]>, " rather firmly in the kiester."], #[['this, $antisocial]]]>]];
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[["test", [["test", "", "test", 'anti_cmd, #[]]]], ["ice", [["ice", "*", "ice <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["eye", [["eye", "*", "eye <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["fart", [["fart", "*", "fart <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["kick", [["kick", "*", "kick <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["pat", [["pat", "*", "pat <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["pummel", [["pummel", "*", "pummel <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["poke", [["poke", "*", "poke <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["prod", [["prod", "*", "prod <object>", 'anti_cmd, #[[1, ['object, []]]]]]], ["bonk", [["bonk", "*", "bonk <object>", 'anti_cmd, #[[1, ['object, []]]]]]]];
var $root inited = 1;
var $root managed = [$antisocial];
var $root owned = [$antisocial];

public method .set_antisocial() {
    arg name, message;
    var mes, partial, compiler;
    
    (> .perms(sender(), 'writer) <);
    if (!antisocial_msgs)
        antisocial_msgs = #[];
    compiler = $compiler;
    message = compiler.compile_cml(message);
    antisocial_msgs = antisocial_msgs.add(name, message);
    
    // $#Edited: 23 Jul 96 22:51 $xymox
    // $#Edited: 08 Mar 97 22:13 $miro
};

public method .antisocial_msgs() {
    return antisocial_msgs;
    
    // $#Edited: 23 Jul 96 23:03 $xymox
    // $#Edited: 08 Mar 97 22:13 $miro
};

public method .test() {
    arg @who;
    var vars, m, message;
    
    if (who)
        who = .match_environment(who[1]);
    vars = #[["$actor", this()], ["actor", .name()], ["$who", who], ["who", who.name()]];
    message = (definer().antisocial_msgs())["feh"];
    m = message.set_vars(vars);
    .tell(m);
    .announce(m, this());
    
    // $#Edited: 23 Jul 96 23:23 $xymox
    // $#Edited: 08 Mar 97 22:13 $miro
};

protected method .anti_cmd() {
    arg cmdstr, cmd, @who;
    var message, vars, victim, m;
    
    (> .perms(caller(), 'command) <);
    vars = #[["$actor", this()], ["actor", .name()]];
    if (who)
        vars = (vars.add("$who", who[1])).add("who", (who[1]).name());
    (.location()).announce(.eval_message(cmd, vars, definer()));
    
    // $#Edited: 08 Mar 97 22:13 $miro
};


new object $social: $user_interfaces;

var $root manager = $social;
var $root flags = ['variables, 'methods, 'code, 'command_cache, 'core];
var $root created_on = 838260513;
var $has_commands shortcuts = #[];
var $has_commands remote = #[];
var $has_commands local = #[["bow", [["bow", "*", "bow <object>", 'social_cmd, #[[1, ['object, []]]]]]]];
var $root inited = 1;
var $root managed = [$social];
var $root owned = [$social];
var $user_interfaces links = 1;

protected method .social_cmd() {
    arg cmdstr, cmd, @who;
    var vars, i, n;
    
    (> .perms(caller(), 'command) <);
    vars = #[["$actor", this()], ["actor", .name()]];
    n = 0;
    for i in (who) {
        if ((| i.name() |)) {
            vars = (vars.add(n ? "$victim_" + n : "$victim", i)).add(n ? "victim_" + n : "victim", i.name());
            n++;
        }
    }
    (.location()).announce(.eval_message(cmd, vars));
    
    // $#Edited: 24 Jul 96 20:33 $jenner
    // $#Edited: 26 Jul 96 16:03 $jenner
    // $#Edited: 13 Nov 96 00:21 $levi
};


new object $settings_ui: $user_interfaces;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $has_commands local = #[["@set?tings", [["@set?tings", "on|from *", "@set?tings on|from <object reference>", 'settings_on_cmd, #[[2, ['objref, []]]]]]], ["@set|@setting?s", [["@set|@setting?s", "*", "@set|@setting?s <any>", 'set_cmd, #[[1, ['any, []]]]]]]];
var $root manager = $settings_ui;
var $root managed = [$settings_ui];
var $root owned = [$settings_ui];

protected method .settings_cmd() {
    arg cmdstr, cmd, args;
    var flag, value, template, syn, bool, line;
    
    (> .perms(caller(), 'command) <);
    syn = cmd + " [+|-]<flag>[=<value>]";
    if (!args) {
        return .list_settings('local);
    } else if (args in ["-all", "-a"]) {
        return .list_settings('all);
    } else {
        bool = (args[1]) in ["-", "+"];
        if (bool)
            args = args.subrange(2);
        args = args.explode("=");
        flag = args[1];
        if ((args.length()) == 2)
            value = args[2];
        else
            value = "";
        template = .setting_template(flag);
        if (!template)
            return ("No setting available with the flag \"" + flag) + "\".";
        switch (template[2]) {
            case 'boolean:
                if (!bool)
                    return ("Value must be boolean (+|-" + flag) + ").";
                value = bool - 1;
            case 'integer:
                if (!($string.is_numeric(value)))
                    return ("Value must be an integer (" + flag) + "=<integer>).";
                value = toint(value);
            case 'string:
                if (!value)
                    return ("Value must be a string (" + flag) + "=<string>).";
        }
        .OLD_set_setting(flag, value);
        line = ("Setting " + flag) + " set to ";
        switch (template[2]) {
            case 'boolean:
                line += (value == 1) ? "+" : "-";
            default:
                line += toliteral(value);
        }
        .tell(line);
    }
};

protected method .settings_on_cmd() {
    arg cmdstr, cmd, prep, ref;
    
    (> .perms(caller(), 'command) <);
    
    // this is a hookneyed way to do it, and wont work out in the long run,
    // but until we get arguments in the parser this will work fine
    if ((ref[2]) == (ref[3]))
        return ._show_settings(ref[3]);
    else
        return ._show_settings_on(ref[3], ref[2]);
};

public method ._show_setting() {
    arg setting, definer, object;
    var line;
    
    line = ("  " + setting) + " = ";
    setting = (| object.display_setting(setting, definer) |);
    if (setting != ~setting)
        line += setting;
    return line;
};

public method ._show_settings_on() {
    arg definer, object;
    var settings, s, setting, line, out;
    
    if (!(object.trusts(this())))
        return [(definer.namef('xref)) + ":", "  ** Unable to see settings **"];
    settings = (| definer.OLD_defined_settings() |) || [];
    out = [];
    for s in (settings)
        out += [._show_setting(s, definer, object)];
    if (!out)
        out = ["  (none)"];
    return [(definer.namef('xref)) + ":"] + out;
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

protected method .set_cmd() {
    arg cmdstr, cmd, args;
    var opt, definer, t, p, name, value, object, reg, s;
    
    (> .perms(caller(), 'command) <);
    if (!args)
        return ._show_settings(this());
    if ((reg = regexp(args, "^ *(.*)<([^)]+)>(.*) *$"))) {
        definer = (> .match_env_nice(reg[2]) <);
        args = (((reg[1]).trim()) + " ") + ((reg[3]).trim());
    }
    if ((reg = regexp(args, "^ *([^:=]+): *(.*) *$"))) {
        object = (> .match_env_nice(reg[1]) <);
        args = reg[2];
    } else {
        object = this();
    }
    if ((reg = regexp(args, "^ *([a-z0-9_@-]+)[ =](.*)$"))) {
        name = (reg[1]).trim();
        args = (reg[2]).trim();
    } else {
        name = args;
        args = "";
    }
    if (!name)
        return [("-- Settings on " + (object.namef('ref))) + ":", ._show_settings(object), "--"];
    
    // this should fix the quotes
    value = args.unquote();
    
    // change it
    catch any {
        ._change_setting(name, value, definer, object);
        .tell(["-- Setting changed to:", ._show_setting(name, definer, object), "--"]);
    } with {
        return (traceback()[1])[2];
    }
};

public method ._show_settings() {
    arg object;
    var a, s, out;
    
    if (!(object.trusts(this())))
        return (((object.namef('ref)) + " does not trust you enough to show you ") + (((| object.gender() |) || $gender_neuter).pronoun('pp))) + " settings.";
    out = [];
    for a in (object.ancestors()) {
        if (a == $has_settings)
            break;
        s = (| a.OLD_defined_settings() |);
        if (s)
            out += [._show_settings_on(a, object)];
    }
    return out.reverse();
};

public method ._change_setting() {
    arg name, value, definer, object;
    var current, style, index, pos;
    
    (> .perms(sender(), 'writers) <);
    style = name.last();
    if (style in ["+", "-"]) {
        name = name.subrange(1, (name.length()) - 1);
        if (!definer)
            definer = object._find_setting_definer(name);
        current = (object.setting(name, definer)) || [];
        if (style == "+")
            value = [@current || [], value];
        else
            value = current.delete(toint(value));
    }
    catch ~check, ~set
        (> object.OLD_set_setting(definer, name, value) <);
    with
        throw(~stop, (traceback()[1])[2]);
    
    // $#Edited: 30 Nov 96 21:22 $miro
};


new object $slate: $thing;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $slate connection = 0;
var $slate remote_host = "";
var $slate remote_port = 0;
var $slate request_method = "";
var $slate received_text = [];
var $located location = $void;
var $located obvious = 1;
var $described prose = [];
var $has_name name = ['uniq, "Generic Slate", "the Generic Slate"];
var $root manager = $slate;
var $root managed = [$slate];
var $root owned = [$slate];
var $thing gender = $gender_neuter;

root method .init_slate() {
    connection = 0;
    remote_host = "";
    remote_port = 0;
    request_method = "";
    received_text = [];
};

root method .uninit_slate() {
    connection = 0;
    remote_host = "";
    remote_port = 0;
    request_method = "";
    received_text = [];
};

protected method .received_text() {
    return received_text;
};

protected method .connection() {
    return connection;
};

protected method .remote_host() {
    return remote_host;
};

protected method .remote_port() {
    return remote_port;
};

protected method .request_method() {
    return request_method;
};

protected method .send() {
    arg line;
    
    connection.send(line);
};

public method .connection_ending();


new object $nothing: $thing;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $located location = $lost_and_found;
var $located obvious = 1;
var $described prose = [];
var $has_name name = ['prop, "nothing whatsoever", "nothing whatsoever"];
var $root manager = $nothing;
var $root owned = [$nothing];
var $thing gender = $gender_neuter;
var $root managed = [$nothing];


new object $gender: $has_name;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'core, 'variables];
var $gender pronouns = 0;
var $gender gender = 0;
var $gender cgender_name = 0;
var $gender gender_name = 0;
var $gender person = 0;
var $gender has = 0;
var $gender number = 0;
var $gender context = [];
var $has_name name = ['normal, "Gendered Object", "a Gendered Object"];
var $gender vpronouns = 0;
var $gender apronouns = 0;
var $root manager = $gender;
var $root managed = [$gender];
var $root owned = [$gender];

root method .init_gender() {
    cgender_name = "";
    gender_name = "";
    
    // these should be inited by hand, later.
    pronouns = #[['pr, "itself"], ['pp, "its"], ['po, "it"], ['ps, "it"], ['pq, "its"], ['prc, "Itself"], ['ppc, "Its"], ['poc, "It"], ['psc, "It"], ['pqc, "Its"], ['have, "has"]];
};

public method .pronoun() {
    arg pronoun;
    
    return (> pronouns[pronoun] <);
    
    // $#Edited: 13 Mar 96 17:36 Levi ($user_levi)
};

public method .gender() {
    return gender;
};

public method .set_gender_names() {
    arg name, cname;
    
    .perms(sender());
    cgender_name = cname;
    gender_name = name;
};

public method .set_pronouns() {
    arg nmbr, ps, po, pp, pq, pr, psc, poc, ppc, pqc, prc;
    var x;
    
    .perms(sender(), 'manager);
    pronouns = #[['pr, pr], ['pp, pp], ['po, po], ['ps, ps], ['pq, pq], ['prc, prc], ['ppc, ppc], ['poc, poc], ['psc, psc], ['pqc, pqc]];
    number = nmbr;
    context = [ps, po, pp, pq, pr, psc, poc, ppc, pqc, prc];
};

public method .pronouns() {
    return pronouns;
};

public method .gender_name() {
    arg @caps;
    
    [(caps ?= 'null)] = caps;
    switch (caps) {
        case 'caps:
            return cgender_name;
        default:
            return gender_name;
    }
    
    // $#Edited: 30 Nov 96 21:22 $miro
};

public method .context() {
    return context;
};

public method .cml_pronouns() {
    return cml_pronouns;
};

public method .vpronouns() {
    return vpronouns;
};

public method .apronouns() {
    return apronouns;
};

public method .number() {
    return number;
    
    // $#Edited: 12 Nov 96 00:42 $levi
};


new object $gender_first_person: $gender;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $gender cgender_name = "";
var $gender gender_name = "";
var $gender pronouns = #[['pr, "yourself"], ['pp, "your"], ['po, "you"], ['ps, "you"], ['pq, "yours"], ['prc, "Yourself"], ['ppc, "Your"], ['poc, "You"], ['psc, "You"], ['pqc, "Yours"]];
var $gender number = 1;
var $gender context = ["yourself", "your", "you", "you", "yours", "Yourself", "Your", "You", "You", "Yours"];
var $has_name name = ['normal, "Gender, First Person", "a Gender, First Person"];
var $gender vpronouns = #[["vpr", "yourself"], ["vpp", "your"], ["vpo", "you"], ["vps", "you"], ["vpq", "yours"], ["vprc", "Yourself"], ["vppc", "Your"], ["vpoc", "You"], ["vpsc", "You"], ["vpqc", "Yours"]];
var $gender apronouns = #[["apr", "yourself"], ["app", "your"], ["apo", "you"], ["aps", "you"], ["apq", "yours"], ["aprc", "Yourself"], ["appc", "Your"], ["apoc", "You"], ["apsc", "You"], ["apqc", "Yours"]];
var $root manager = $gender_first_person;
var $root owned = [$gender_first_person];
var $root managed = [$gender_first_person];


new object $gender_female: $gender;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $gender cgender_name = "Female";
var $gender gender_name = "female";
var $gender pronouns = #[['pr, "herself"], ['pp, "her"], ['po, "her"], ['ps, "she"], ['pq, "hers"], ['prc, "Herself"], ['ppc, "Her"], ['poc, "Her"], ['psc, "She"], ['pqc, "Hers"]];
var $gender number = 'singular;
var $gender context = ["herself", "her", "her", "she", "hers", "Herself", "Her", "Her", "She", "Hers"];
var $has_name name = ['prop, "female", "female"];
var $gender vpronouns = #[["vpr", "herself"], ["vpp", "her"], ["vpo", "her"], ["vps", "she"], ["vpq", "hers"], ["vprc", "Herself"], ["vppc", "Her"], ["vpoc", "Her"], ["vpsc", "She"], ["vpqc", "Hers"]];
var $gender apronouns = #[["apr", "herself"], ["app", "her"], ["apo", "her"], ["aps", "she"], ["apq", "hers"], ["aprc", "Herself"], ["appc", "Her"], ["apoc", "Her"], ["apsc", "She"], ["apqc", "Hers"]];
var $root manager = $gender_female;
var $root owned = [$gender_female];
var $root managed = [$gender_female];


new object $gender_first_person_plural: $gender;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $gender cgender_name = "";
var $gender gender_name = "";
var $gender pronouns = #[['pr, "yourselves"], ['pp, "your"], ['po, "you"], ['ps, "you"], ['pq, "yours"], ['prc, "Yourselves"], ['ppc, "Your"], ['poc, "You"], ['psc, "You"], ['pqc, "Yours"]];
var $gender number = 2;
var $gender context = ["yourselves", "your", "you", "you", "yours", "Yourselves", "Your", "You", "You", "Yours"];
var $has_name name = ['normal, "Gender, First Person Plural", "a Gender, First Person Plural"];
var $gender vpronouns = #[["vpr", "yourselves"], ["vpp", "your"], ["vpo", "you"], ["vps", "you"], ["vpq", "yours"], ["vprc", "Yourselves"], ["vppc", "Your"], ["vpoc", "You"], ["vpsc", "You"], ["vpqc", "Yours"]];
var $gender apronouns = #[["apr", "yourselves"], ["app", "your"], ["apo", "you"], ["aps", "you"], ["apq", "yours"], ["aprc", "Yourselves"], ["appc", "Your"], ["apoc", "You"], ["apsc", "You"], ["apqc", "Yours"]];
var $root manager = $gender_first_person_plural;
var $root owned = [$gender_first_person_plural];
var $root managed = [$gender_first_person_plural];


new object $gender_male: $gender;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $gender cgender_name = "Male";
var $gender gender_name = "male";
var $gender pronouns = #[['pr, "himself"], ['pp, "his"], ['po, "him"], ['ps, "he"], ['pq, "his"], ['prc, "Himself"], ['ppc, "His"], ['poc, "Him"], ['psc, "He"], ['pqc, "His"]];
var $gender number = 'singular;
var $gender context = ["himself", "his", "him", "he", "his", "Himself", "His", "Him", "He", "His"];
var $has_name name = ['prop, "male", "male"];
var $gender vpronouns = #[["vpr", "himself"], ["vpp", "his"], ["vpo", "him"], ["vps", "he"], ["vpq", "his"], ["vprc", "Himself"], ["vppc", "His"], ["vpoc", "Him"], ["vpsc", "He"], ["vpqc", "His"]];
var $gender apronouns = #[["apr", "himself"], ["app", "his"], ["apo", "him"], ["aps", "he"], ["apq", "his"], ["aprc", "Himself"], ["appc", "His"], ["apoc", "Him"], ["apsc", "He"], ["apqc", "His"]];
var $root manager = $gender_male;
var $root owned = [$gender_male];
var $root managed = [$gender_male];


new object $gender_plural: $gender;

var $root trusted = [];
var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $gender cgender_name = "Plural";
var $gender gender_name = "plural";
var $gender pronouns = #[['pr, "themselves"], ['pp, "their"], ['po, "them"], ['ps, "they"], ['pq, "theirs"], ['prc, "Themselves"], ['ppc, "Their"], ['poc, "Them"], ['psc, "They"], ['pqc, "Theirs"]];
var $gender number = 2;
var $gender context = ["themselves", "their", "them", "they", "theirs", "Themselves", "Their", "Them", "They", "Theirs"];
var $has_name name = ['prop, "plural", "plural"];
var $gender vpronouns = #[["vpr", "themselves"], ["vpp", "their"], ["vpo", "them"], ["vps", "they"], ["vpq", "theirs"], ["vprc", "Themselves"], ["vppc", "Their"], ["vpoc", "Them"], ["vpsc", "They"], ["vpqc", "Theirs"]];
var $gender apronouns = #[["apr", "themselves"], ["app", "their"], ["apo", "them"], ["aps", "they"], ["apq", "theirs"], ["aprc", "Themselves"], ["appc", "Their"], ["apoc", "Them"], ["apsc", "They"], ["apqc", "Theirs"]];
var $root manager = $gender_plural;
var $root owned = [$gender_plural];
var $root managed = [$gender_plural];


new object $gender_neuter: $gender;

var $root inited = 1;
var $root created_on = 796268969;
var $root flags = ['methods, 'code, 'variables, 'core];
var $gender cgender_name = "Neuter";
var $gender gender_name = "neuter";
var $gender pronouns = #[['pr, "itself"], ['pp, "its"], ['po, "it"], ['ps, "it"], ['pq, "its"], ['prc, "Itself"], ['ppc, "Its"], ['poc, "It"], ['psc, "It"], ['pqc, "Its"]];
var $gender number = 'singular;
var $gender context = ["itself", "its", "it", "it", "its", "Itself", "Its", "It", "It", "Its"];
var $has_name name = ['prop, "neuter", "neuter"];
var $gender vpronouns = #[["vpr", "itself"], ["vpp", "its"], ["vpo", "it"], ["vps", "it"], ["vpq", "its"], ["vprc", "Itself"], ["vppc", "Its"], ["vpoc", "It"], ["vpsc", "It"], ["vpqc", "Its"]];
var $gender apronouns = #[["apr", "itself"], ["app", "its"], ["apo", "it"], ["aps", "it"], ["apq", "its"], ["aprc", "Itself"], ["appc", "Its"], ["apoc", "It"], ["apsc", "It"], ["apqc", "Its"]];
var $root manager = $gender_neuter;
var $root owned = [$gender_neuter];
var $root managed = [$gender_neuter];


new object $mutex: $root;

var $root manager = $mutex;
var $mutex locks = 0;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858071384;
var $root inited = 1;
var $mutex suspended = 0;
var $mutex tasks = 0;
var $mutex queues = 0;
var $root child_index = 2;
var $root help_node = $help_mutex;
var $root managed = [$mutex];

private method ._test_locks() {
    arg tid, values;
    var i;
    
    return filter i in (values) where (!(._test_lock(tid, i)));
    
    // $#Edited: 13 Mar 97 05:50 $miro
};

private method ._add_to_lock() {
    arg tid, val;
    
    if ((| ((locks[val])[1]) == tid |))
        locks = locks.add(val, [tid, ((locks[val])[2]) + 1]);
    else
        locks = locks.add(val, [tid, 1]);
    
    // $#Edited: 13 Mar 97 05:50 $miro
};

public method .release_all() {
    .release(@tasks[task_id()]);
    
    // $#Edited: 13 Mar 97 05:50 $miro
};

private method ._del_from_lock() {
    arg tid, val;
    var i, l;
    
    if (((| (l = locks[val]) |)[1]) != tid) {
        $miro.debug(locks, val, tid);
        return;
    }
    if ((l[2]) == 1) {
        (| (locks = locks.del(val)) |);
        ._del_from_queue(val);
    } else {
        locks = locks.add(val, [tid, (l[2]) - 1]);
    }
    
    // $#Edited: 13 Mar 97 05:50 $miro
};

private method ._test_lock() {
    arg tid, val;
    var i;
    
    if ((| ((locks[val])[1]) != tid |)) {
        queues = queues.add(val, (| (queues[val]) + [tid] |) || [tid]);
        return 0;
    }
    return 1;
    
    // $#Edited: 13 Mar 97 05:50 $miro
};

public method .release() {
    arg @values;
    var tid, t, vlist, i, obj;
    
    values ?= [0];
    tid = task_id();
    vlist = tasks[tid];
    for obj in (.descendants())
        obj.release(@values);
    for i in (values) {
        vlist = vlist.setremove(i);
        ._del_from_lock(tid, i);
    }
    if (vlist)
        tasks = tasks.add(tid, vlist);
    else
        tasks = tasks.del(tid);
    
    // $#Edited: 13 Mar 97 05:50 $miro
};

public method .grab() {
    arg @values;
    var i, tid, l, obj;
    
    values ?= [0];
    tid = task_id();
    for obj in (.descendants())
        obj.grab(@values);
    tasks = tasks.add(tid, (| (tasks[tid]) + [values] |) || values);
    while (1) {
        if (!(l = ._test_locks(tid, values))) {
            for i in (values)
                ._add_to_lock(tid, i);
            return;
        } else {
            suspended = suspended.add(tid, l.length());
            $scheduler.suspend(this());
        }
    }
    
    // $#Edited: 13 Mar 97 05:50 $miro
};

private method ._del_from_queue() {
    arg val;
    var tid, s, q;
    
    q = (| queues[val] |) || [];
    (| (queues = queues.del(val)) |);
    for tid in (q) {
        $miro.debug(suspended, tid, queues, tasks, locks);
        if ((s = suspended[tid]) == 1) {
            suspended = suspended.del(tid);
            (| $scheduler.resume(tid) |);
        } else {
            suspended = suspended.add(tid, s - 1);
        }
    }
    
    // $#Edited: 13 Mar 97 05:50 $miro
};

public method .cleanup_dead_tasks() {
    var t, i, j;
    
    t = tasks();
    for i in (tasks.keys()) {
        if (!(i in t)) {
            for j in (tasks[i])
                ._del_from_lock(i, j);
            tasks = tasks.del(i);
        }
    }
    
    // $#Edited: 13 Mar 97 05:50 $miro
};

root method .init_mutex() {
    tasks = (suspended = (queues = (locks = #[])));
    
    // $#Edited: 13 Mar 97 05:50 $miro
};


new object $mutex_access: $mutex;

var $root manager = $mutex_access;
var $root child_index = 3;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858089211;
var $root inited = 1;
var $root managed = [$mutex_access];


new object $mutex_mail: $mutex_access;

var $root manager = $mutex_mail;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858089236;
var $root inited = 1;
var $root managed = [$mutex_mail];


new object $mutex_vr: $mutex;

var $root manager = $mutex_vr;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858089305;
var $root inited = 1;
var $root managed = [$mutex_vr];


new object $mutex_building: $mutex_access, $mutex_vr;

var $root manager = $mutex_building;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858089261;
var $root inited = 1;
var $root managed = [$mutex_building];


new object $mutex_location: $mutex_access, $mutex_vr;

var $root manager = $mutex_location;
var $root flags = ['variables, 'methods, 'code, 'core];
var $root created_on = 858089228;
var $root inited = 1;
var $mutex tasks = #[];
var $mutex locks = #[];
var $mutex queues = #[];
var $mutex suspended = #[];
var $root managed = [$mutex_location];