MOOsaico: Multilingual Virtual Community

Core Utility Help (#23)
=======================

$alt_quota_utils    $generic_editor	$no_one 	    core-index
$biglist	    $generic_help	$object_utils	    mail-format
$bit_utils	    $generic_options	$perm_utils	    mail-resolve
$building_utils     $generic_utils	$player_db	    mail-system
$charset_utils	    $help		$portuguese_utils   MR-access
$code_utils	    $housekeeper	$quota_utils	    MR-naming
$command_utils	    $language_utils	$recycler	    MR-reading
$container	    $list_utils 	$room		    MR-searching
$english_utils	    $lock_utils 	$seq_utils	    MR-sequences
$error		    $login		$set_utils	    MR-subscribing
$exit		    $mail_agent 	$string_utils	    MR-writing
$frob_utils	    $mail_recipient	$time_utils	    object-matching
$gender_utils	    $match_utils	$trig_utils	    receiving-mail
$generic_db	    $math_utils 	$wiz_utils	    sending-mail


$ALT_QUOTA_UTILS
================

Informa~E7~E3o geral sobre $alt_quota_utils:
----
Na~o se deve usar isto.

$BIGLIST
========

Generic BigList Utilities
----------------------------
$biglist is a collection of routines for maintaining huge persistent (sorted)
lists in a format that is less likely to spam the server (which runs into a
certain amount of trouble dealing with long ordinary lists --- btw we use
`biglist' to refer to the huge data structure we're about to describe and
`list' to refer to ordinary MOO lists {...}).  The biglist in question lives on
a particular object, to which we will refer in the discussion below as the
`home' object, and its various elements appear as leaves of a tree whose nodes
are kept in properties of the home object.  It should be noted that the home
object does not need to be (and in fact should *not* be) a descendant of
$biglist one; $biglist merely provides utilities for manipulating the
properties on the home object that are used in a particular biglist
manipulation.  

All of the utilities below refer to `caller' to locate the home object.  Thus
verbs to manipulate a given biglist must be located on or inherited by its home
object itself.	The home object needs to define the following verbs

  :_make(@args)     => new property on home object with value args
  :_kill(prop)	    delete a given property that was created by :_make
  :_get(prop)	    => home.prop
  :_put(prop,@args) set home.prop = args
  :_ord(element)    given something that is of the form of a biglist element
		    return the corresponding ordinal (for sorting purposes).
		    If you never intend to use :find_ord, then this can be a 
		    routine that always returns 0 or some other random value.

See $generic_biglist_home or $big_mail_recipient for examples.

Those of the following routines that take a biglist argument are expecting
either {} (empty biglist) or some biglist returned by one of the other routines

  :length(biglist)	    => length(biglist) (i.e., number of elements)
  :find_nth(biglist,n)	    => biglist[n]
  :find_ord(biglist,k,comp) => n where n is
     the largest such that home:(comp)(k,home:_ord(biglist[n])) is false, or
     the smallest such that home:(comp)(k,home:_ord(biglist[n+1])) is true.
     Always returns a value between 0 and length(biglist) inclusive.
     This assumes biglist to be sorted in order of increasing :_ord values 
     with respect to home:(comp)().
     Standard situation is :_ord returns a number and comp is a < verb.

  :start(biglist,s,e)  => {biglist[s..?],@handle} or {}
  :next(@handle)       => {biglist[?+1..??],@newhandle} or {}
     These two are used for iterating over a range of elements of a biglist
     The canonical incantation for doing
	for elt in (biglist[first..last])
	  ...
	endfor
     is
	handle = :start(biglist,first,last);
	while(handle)
	  for elt in (handle[1])
	    ...
	  endfor
	  handle = :next(@listdelete(handle,1));
	endwhile

The following all destructively modify their biglist argument(s) L (and M).

  :set_nth(L,n,value)  =>  L[n] = value
     replaces the indicated element

  :insert_before(L,M,n) => {@L[1..n-1],@M,@L[n..length(L)]}
  :insert_after (L,M,n) => {@L[1..n],  @M,@L[n+1..length(L)]}
     takes two distinct biglists, inserts one into the other at the given point
     returns the resulting consolidated biglist

  :extract_range(L,m,n) => {{@L[1..m-1],@L[n+1..]}, L[m..n]} 
     breaks the given biglist into two distinct biglists.

  :delete_range(L,m,n[,leafkiller]) => {@L[1..m-1],@L[n+1..]}
  :keep_range  (L,m,n[,leafkiller]) => L[m..n]
     like extract_range only we destroy what we don't want.

  :insertlast(L,value)	=> {@L,value}
     inserts a new element at the end of biglist.  
     If find_ord is to continue to work properly, it is assumed that the 
     home:_ord(elt) is greater (comp-wise) than all of the :_ord values
     of elements currently in the biglist.

  :kill(L[,leafkiller]) 
     destroys all nodes used by biglist.  
     Calls home:leafkiller on each element.

$BIT_UTILS
==========

Informa~E7~E3o geral sobre $bit_utils:
----
Verbos para manipular os bits individua'is dum nu'mero:

:bit_test(nu'mero,pos)
   Retorna o valor do bit com nu'mero pos do nu'mero.
   :bit_test(6,1) => 0
   :bit_test(6,2) => 1
   :bit_test(6,3) => 1

:bit_set(nu'mero,pos,valor_bina'rio)
   Retorna nu'mero com o bit do nu'mero pos atribuido ao valor_bina'rio.
   :bit_set(6,1,1) => 7
   :bit_set(7,1,0) => 6

:bit_test_named(ordem,nu'mero,nome)
   Retorna o bit chamado nome do nu'mero.
   A ordem dos bits esta' determinado por ordem.
   :bit_test_named({"foo","bar","baz"},6,"foo") => 0
   :bit_test_named({"foo","bar","baz"},6,"bar") => 1
   :bit_test_named({"foo","bar","baz"},6,"baz") => 1

:bit_set_named(ordem,nu'mero,name,valor_bina'rio)
   Retorna nu'mero com o bit chamado nome atribuido ao valor_bina'rio.
   A ordem dos bits esta' determinado por ordem.
   :bit_set_named({"foo","bar","baz"},6,"foo",1) => 7
   :bit_set_named({"foo","bar","baz"},7,"foo",0) => 6

:bits_as_names(ordem,nu'mero)
   Troca um nu'mero para a uma lista de +/- nomes.
   :bits_as_names({"foo","bar","baz"},6) => {"-foo", "+bar", "+baz"}

:names_as_bits(ordem,nu'mero,nomes)
   Troca uma lista de +/- nomes para uma nu'mero.
   :names_as_bits({"foo","bar","baz"},0,{"+bar","+baz"}) => 6
   :names_as_bits({"foo","bar","baz"},0,{"-foo","+bar","+baz"}) => 6
   :names_as_bits({"foo","bar","baz"},1,{"+bar","+baz"}) => 7

BYTE OPERATIONS:

:get_byte(number,pos,size)
   Returns the group of bits with position pos and position size in number.
   Note that :get_byte(n,m,1) is the same as :bit_test(n,m).
   :get_byte(6,1,2) => 2  :get_byte(16,3,3) => 4  :get_byte(20,3,3) => 5
   :get_byte(6,2,2) => 3  :get_byte(16,5,1) => 1  :get_byte(20,3,0) => 0

:set_byte(number,pos,size,newval)
   Sets the group of bits with position pos and position size in number
   to be the bits in newval.  If newval has more than size bits, only
   the bottom values are used.
   :set_byte(6,1,2,1) => 5
   :set_byte(0,1,2,7) => 3

The next operations use a "defs" datastructure which has the form:
 {{name1, name2, ...}, {pos1, pos2, ...}, {size1, size2, ...}}

:get_byte_named(defs,number,name)
   Returns the named byte from number.	For example, if the given name is
   name3 in the defs (see above), returns the byte with pos3 and size3.
   :get_byte_named({{"foo","bar"},{1,3},{2,1}},6,"foo") => 2
   :get_byte_named({{"foo","bar"},{1,3},{2,1}},6,"bar") => 1

:set_byte_named(defs,number,name,newval)
   Sets the byte that would be returned by :get_byte_named.
   As with :set_byte, if newval has more than size bits, only
   the bottom values are used.
   :set_byte_named({{"foo","bar"},{1,3},{2,1}},6,"foo",0) => 4
   :set_byte_named({{"foo","bar"},{1,3},{2,1}},6,"bar",0) => 2

:bytes_as_names(defs,number)
   Returns an alist of the byte names and values in number.
   :bytes_as_names({{"foo","bar"},{1,3},{2,1}},6) => 
    => {{"foo", 2}, {"bar", 1}}

:names_as_bytes(defs,number,value_alist)
   Returns a number augmented by setting the indicated fields.
   :names_as_bytes({{"foo","bar"},{1,3},{2,1}},9,{{"foo", 2}, {"bar", 1}})
    => 14
   When constructing a new number, use 0 for the number:
   :names_as_bytes({{"foo","bar"},{1,3},{2,1}},0,{{"foo", 2}, {"bar", 1}})
    => 6

Autor original: Mickey @ OpalMOO II

$BUILDING_UTILS
===============

Informa~E7~E3o geral sobre $building_utils:
----
Verbos ute'is para construc,a~o.  Para uma descric,a~o completa de um certo
verbo ( em ingle^s ), fac,a `ajuda $building_utils:nomedoverbo'.

make_exit(spec,source,dest[,don't-really-create]) => uma nova sai'da
	  spec e' uma especifica,ca~o de sai'da como em `ajuda @dig'

set_names(object, spec) - define o nome ingle^s e aliases de um objecto
parse_names(spec) => lista de {nomes, aliases}
	  em ambos, spec e' da forma
	    <nome>[[,:]<alias>,<alias>,...]
	  (como descrito em `ajuda @rename')

recreate(object, newparent) - efectivamente recicla e recria o objecto como
			      filho do novo pai

$CHARSET_UTILS
==============

Informa~E7~E3o geral sobre $charset_utils:
----
Verbos para manipular palavras inglesas.

:a_or_an(nome)	       Retorna "a" ou "an" para o nome especificado.
:pluralize(nome)       Retorna o plural do nome especificado.
:cardinal_number(N)    Retorna N como nu'mero cardinal (N=1 => "one").
:ordinal_number(N)     Retorna N como nu'mero ordinal (N=1 => "first").
:ordinal_num(N)        Retorna N como nu'mero ordinal breve (N=1 => "1st").
:grouped_number(n[,m]) Retorna N como nu'mero agrupado (N=1234 => "1,234").
			With M, uses N/M (N=1234,M=10 => "1,234.5").

Para ver exemplos dos plurais, faz:
 @test_plural <palavra_ou_frase> on #1111
 @test_plurals on #1111

$ERROR
======

$error
======

The Error Generator, $error, may be used to automatically generate errors. This
is particularly useful if you are working in a !d verb but have occasion to
-want- to crash with traceback. To raise a specific error, use
$error:raise(error type) -- for example, $error:raise(E_PERM) will produce
traceback resulting from a Permission Denied error.

Random notes about $error:

+ The complete list of errors is stored in $error.names.
+ The seemingly useless :accept() verb on $error is so that $error:E_RECMOVE
and $error:E_NACC will be guaranteed success (success meaning, of course, a
termination by traceback).
+ There is, unfortunately, no way to raise the error E_NONE.

$EXIT
=====

Exits
-----
An exit can be renamed by either the owner of the exit or the owner of its
source.

The standard verbs that are called in exit movement are:

:move(object)  - moves the object via this exit
:invoke()      - equivalent to :move(player)

When an exit is invoked on a particular object (via exit:move(object)), the
following occurs.

(1) The exit may be locked against the object, in which case we print the 
   nogo messages and quit.

(2) (room=exit.dest):bless_for_entry(object) is called.  Assuming that exit is
recognized by room as being a legitimate entrance (i.e., is in room.entrances),
this will enable room:accept(object) to return true.

(3) object:moveto(room) is called and the various messages (see `help
exit-messages') are :announced/:told.  Note that this, in accordance with the
way the builtin move() (and hence the default :moveto()) works, we get a call
to room:accept(object) which checks for the room itself being locked against
the object, and otherwise returns true if the blessing in the previous step
worked.  The move is performed, here:exitfunc(object) and
room:enterfunc(object) are called.  In particular, room:enterfunc clears the
blessing bestowed in (2) now that it is no longer needed.

In general, the move may fail, in which case we :announce the (o)nogo_msgs.

$FROB_UTILS
===========

Informa~E7~E3o geral sobre $frob_utils:
----
:new(parent,@data) => {$frob, parent, objid}
  Cria uma nova frob {$frob, parent, objid}

:destroy(frob)
  Destroi a frob {$frob, parent, objid}

:send(frob,verbname,@args)
  Envia a mensagem verbname para a frob {$frob, parent, objid}

$GENDER_UTILS
=============

Informa~E7~E3o geral sobre $gender_utils:
----

Utilita'rios para manipular os ge'neros.

 :get_conj*ugation(verbspec,objecto) - retorna a conjungac,a~o do 
				       verbo (ingle^s).

 :core_genders() - retorna uma lista dos ge'eneros de "core".

$GENERIC_DB
===========

Generic Database
----------------
This holds a collection of {string key, datum} pairs, where datum can be
anything.  At most one datum may be associated with any given string.  Data may
be anything (lists, strings, numbers, objectids).  If you like, you can think
of this as an array indexed by strings.
Verbs supplied include

  :find(string) 	 => datum, $ambiguous_match or $failed_match
  :find_key(string)	 => full string key,  $ambiguous_match or $failed_match
  :find_exact(string)	 => datum or $failed_match (no partial matches)
  :find_all(string)	 => list of all data corresponding to matching strings
  :find_all_keys(string) => list of all matching strings

  :insert(string,datum)  
       if the string is already present in the db, 
       changes the associated datum and returns {old_datum};
       otherwise enters a new {string,datum} pair and return 0.
  :delete(string)
       if there is a datum associated with string, 
       remove this association and return {datum}; otherwise return 0.
  :delete2(string,datum)
       if the given datum is associated with string, 
       removes that association and return {datum}, 
       if some other datum is associated with string, just return {other datum}
       otherwise return 0.
  :clearall([4|3])
       removes all associations from the database.
       optional argument changes the type of the database 
       (4 is normal, 3 is a kludge for when the data are simply boolean flags
	i.e., this is a set of strings rather than a string-indexed array;
	more on this below)

  count [entries|chars] in this
	provide some vague statistics about how big this thing is.

N.B.  As entries get made, properties belonging to $generic_db.owner will be
created on the db object itself.  These properties will be created having flags
as specified by .node_perms, which by default is "r", but can be changed to ""
should you want to ensure that randoms don't have access to the raw
information.

Implementation notes
 - - - - - - - - - -
The representation is as a `trie', a tree in which each internal node
corresponds to a prefix shared by two or more strings in the db.
Each internal node is kept in a property named " "+<prefix>, where <prefix> is
a prefix shared by all strings in the subtree under this node.
The property value is a 4 element list

this.(" "+<prefix>)[1] = <common>
   maximal continuation shared by all strings beginning with prefix
   i.e., all these names actually begin with <prefix>+<common>

this.(" "+<prefix>)[2] = <continuations>
   string of all characters <c> that can follow <prefix>+<common> for which
   there is more than one string in the db beginning with <prefix>+<common>+<c>

this.(" "+<prefix>)[3] = <exact_matches>
   list of all strings in this subtree for which 
   the character (or lack thereof) following the <prefix>+<common> substring 
   suffices to determine the string.

this.(" "+<prefix>)[4] = <data>
   list of data corresponding to the strings in [3].

Child nodes are       this.(" "+<prefix>+<common>+<c>) 
       for all <c> in this.(" "+<prefix>)[2].
The root node is this.(" ").
If, e.g., there are 2 or more strings in the db beginning with a, 
there will be a node this.(" a").  
If all of these strings actually begin with "ani", then this.(" a")[1]=="ni".
The db consisting of the 5 correspondences

  {"animal", #1}
  {"anime",  #2}
  {"anil",   #3}
  {"anile",  #4}
  {"banal",  #5}

would be represented

this.(" ")    =={"",  "a",  {"banal"},	       {#5}}
this.(" a")   =={"ni","lm", {}, 	       {}}
this.(" anim")=={"",  "",   {"animal","anime"},{#1,#2}}
this.(" anil")=={"",  "",   {"anil","anile"},  {#3,#4}}

In some cases one may merely wish to hold a collection of strings without
trying to associate a particular datum with each string.  One may then instead
set up a db without the fourth field on each of the properties.  In this case
the datum is taken to be the found string itself and that is what gets returned
by :find*() in the event of a successful search.   :find and :find_key are then
equivalent as are :find_all and :find_all_keys.  To setup the db this way, do a
:clearall(3).  :clearall(4) reverts to the above described type of db with a
separately kept datum.	Note that you can't change the type without emptying
the db.  3 and 4 are currently the only db types allowed.

$GENERIC_EDITOR
===============

The Generic Editor enables a player to edit a list of strings.	While one might
contrive to use it directly, it is rather intended as a parent for some actual
editor.  It supplies the following commands:

say	    <text>			w*hat	    
emote	    <text>			abort	    
lis*t	    [<range>] [nonum]		q*uit,done,pause 
ins*ert     [<ins>] ["<text>]		
n*ext,p*rev [n] ["<text>]		
del*ete     [<range>]			
f*ind	    /<str>[/[c][<range>]]	
s*ubst	    /<str1>/<str2>[/[g][c][<range>]]
m*ove,c*opy [<range>] to <ins>		
join*l	    [<range>]			
fill	    [<range>] [@<col>]		

$editor_help.(cmdname) descrbes cmdname
$editor_help.insert    descrbes insertion points (<ins>)
$editor_help.ranges    descrbes range specifications (<range>)

You'll notice that nowhere does it say how to load in a given list of strings
or how and where one may save said list away when one is done editing.	These
commands are supplied by the child editor object.  The generic editor contains
only the code for editing lines, though it defines additional functions for use
by the children:

  :loaded(player)
     returns the index (player in this.active) iff text has been loaded
     from somewhere, otherwise returns 0.

     Note that, by default, there is a difference between 

	having nothing loaded		     (:text(who)==0) and 
	having loaded something with no text (:text(who)=={}).

     If you don't care about this distinction in a particular case,
     just do (player in this.active) instead of this:loaded(player).  
     If you don't want your editor to make this distinction at all, do

	@stateprop texts={} for <youreditor>

     which changes the initial value of :text() to {} 

In all functions below, 'who' is the index returned by :loaded(player) 

BTW, be careful about using 'player' in non-user (i.e., +x this-none-this)
verbs --- much better to have the user verb get the index with :loaded() and
then pass that around.	

Also be careful about suspend() and verbs that call suspend().	In particular,
the player's index in the .active list can change during the suspend interval,
so you must be sure to obtain the index (e.g., using :loaded()) again after the
suspend() returns.

For your non-user verbs, we have

  :ok(who)
     returns E_PERM if the caller is not an editor verb and E_RANGE
     if 'who' does not point to a valid session.

which should take care of the more egregious security holes (but maybe not the
less egregious ones).  For getting and loading text, we have

  :text(who)	
     the current text string list or 0 if nothing loaded yet.
  :load(who,text)
     loads the given list of strings as the text to be edited.
     this also resets the 'changed' flag and pushes the insertion 
     point to the end.

and various flags and properties (all of the set_* routines return E_PERM when
not called from an editor verb, E_RANGE if who is out of bounds, E_INVARG if
something is wrong with the 2nd arg, or the new value, which may not
necessarily be the same as the 2nd arg (e.g., set_insertion(..,37) on a 5 line
text buffer returns 6).

  :changed(who)
     has the text been altered since the last save/load?
     (the child editor gets to define what "save" means).
  :set_changed(who,value)
     Any child editor command that is considered to save the text should do a 
     :set_changed(who,0).  
     Note that if the changed flag is 0, the session will be flushed when 
     the player leaves the editor, so you may also want certain commands to
     do set_changed(who,1)...

  :origin(who)
     room where the player came from.  
  :set_origin(who,room)
     can be used to change the room the player will return to when finished
     editing.  Since origin gets set even in cases where the player teleports
     into the editor you probably won't usually need to do this.

  :insertion(who)
     current insertion point.
  :set_insertion(who,linenumber)
     linenumber needs to be a positive integer and will get 

  :readable(who)
     whether the current editing session has been made globally readable.
  :set_readable(who,boolean)
     change the readability of the current editing session.
     This is used by the publish/perish verbs.

We also provide

  :invoke(...)
      If the player has a previous unsaved (i.e., :changed()!=0)
      session, we return to it, moving the player to the editor.  
      If the player is already in the editor, this has no effect other
      than to print a few nasty messages.  In any case a :changed()
      session must be aborted or set_changed(,0) before anything else 
      can be started

      Otherwise, we pass the arguments (which are assumed to be the
      result of some munging of the command line) to :parse_invoke(),
      move the player to the editor and load whatever parse_invoke()
      specified.  The only interpretation the generic editor makes on
      the arguments is that if the boolean value of the first is true,
      this indicates that the player wanted to load something as
      opposed to resume a previous session.  Usually a command calling
      :invoke will have a true (i.e., nonzero number, nonempty list or
      string) first arg iff the command line is nonempty, in which case 
      'args' works fine for this purpose.

      If the command parses sucessfully (:parse_invoke() returns a list),
      we move the player to the editor if necessary and then call 
      :init_session() to set things up.

The child editor is assumed to provide

  :parse_invoke(...)
     given :invoke()'s arguments, determines what the player wants to edit.
     It either returns 0 and reports syntax errors to player,
     or it returns some list that :init_session() will understand.

  :init_session(who,@spec)
     where spec is something that was returned by :parse_invoke().
     Loads the text and sets the stateprops (below) to indicate that 
     we are working on whatever it is we're suppose to be working on.

  :working_on(who)   
     returns a string X as in "You are working on X."
     This is called by the 'w*hat' command, among other things.

Child editors may have their own properties giving state information for the
various editing sessions.  The value of each such property will be a list
giving a value for each player in the editor.  For each such property, you
should, once the editor object has been created, initialize the property to {}
and do one of

    @stateprop <propname>		  for <editor>
    @stateprop <propname>=<default-value> for <editor>
	       (0 is the default <default-value>)

Henceforth, adding and deleting new editing sessions will amend the list held
by the given property.	The value of the property for a given session can be
obtained via this.<propname>[player in this.active] and can be changed with a
corresponding listset() call.  The usual idiom for an editor command is

   if(!(who=this:loaded(player)))
     player:tell(nothing_loaded_msg());
   else
      ... various references to  this.<propname>[who] ...
   endif

To remove such a property from the list of such state properties:

    @rmstateprop <propname> from <editor>

Note that you can only do this with properties defined on the child editor
itself.  

Sometimes you may wish to @stateprop a new property on an editor where active
editing sessions exist.  @stateprop will fail if the property in question does
not hold a list of the correct length (== length(editor.active); one value for
each editing session).	You need to either give the @flush command to clear out
all sessions and boot all players currently in the editor or somehow manually
initialize the property to a list of appropriate values and pray that nobody
enters/exits the editor between the property initialization and the @stateprop
command --- this problem can be avoided by doing an eval() that does all of the
initializations (beware of suspends()) and calls :set_stateprops directly.

Incidentally, the @flush command may be used at any time to clean out the
editor or to remove all sessions older than a given date.

There are also numerous _msg properties that may be customized

    @depart	     announced at the origin when :invoke() is called. 
    @return	     announced at the origin the player is returned there.
    @nothing_loaded  printed when user attempts editing 
		     before anything has been loaded.
    @no_text	     response to 'list' when :text()=={}
    @no_change	     printed by 'what' when :changed()==0
    @change	     printed by 'what' when :changed()==1
    @no_littering    printed upon leaving the editor with :changed()==1.
    @previous_session  printed by :invoke() when player tries to start a 
		     new session without aborting or saving the old one

The general procedure for creating a child editor:

 @create $generic_editor named <editor>

 define additional <editor> verbs/properties
    At the very least you need 'edit' and 'save' commands.
    Usually you can get away with just having 'edit' call :invoke();
    Presumably, you'll need at least a command to load text from somewhere
    as well as a command to save it back out.

 define a verb (somewhere) to invoke the editor 
    This could be just a one-liner that calls <editor>:invoke(args,verb).
    Either that or
      .  you have to set up an exit somewhere whose destination is <editor>
      .  you have to advertise the object number so that people can 
	 teleport to it.
  
 @stateprop x for <editor>

 if you want the 'abort' command to boot the player from the editor do
    <editor>.exit_on_abort = 1;

 set <editor>.commands to be the list of additional commands defined
    by <editor>.  
    Each element of the list is itself a list of the form {name,args}.
  set <editor>.commands2 to be the list of commands that should appear
    in the `look' listing, and should be a list of strings appearing 
    as names in .commands on either <editor> or some editor ancestor.
  look at $verb_editor or $note_editor for an example.

 If you want to have help text for new verbs you define, create a child of 
    $generic_help and add properties to this object for each of the topics 
    that you want to provide help text.
    Finally, set <editor>.help = {this object} so that the help system
    knows to consult this object.

$GENERIC_HELP/$HELP
===================

The Help System
---------------
When a player types help, the following list of objects is consulted for .help
properties:  the player itself, all ancestors of player up to and including
$player, and, if the current location is a room, the current location together
with all ancestors of the current location back to and including $room.  Each
help property should have as value either an object or a list of objects
(otherwise we just ignore it).	These objects are then strung together as a
list of `help databases' to be searched in order for the requested topic.

A help database (in the sense of anything that is usable by $player:help()) is
any object having the following three verbs:

  :find_topics([string])
     where string is a supposed help topic, returns a list of strings,
     i.e., actual help topics that this db knows about, or some boolean 
     false value in the event that this db is clueless...
     If no arguments are given, this should return a list of all topics
     in the db

  :get_topic(string)
     given one of the strings returned by :find_topics this either
     returns a list of strings (text to be spewed to the player) or
     returns 1 to indicate that it has already taken care of printing
     information to the player.

  :dump_topic(string)
     like get_topic, but instead returns the raw text of a help topic
     as a (download/upload) script

In short if :find_topic reports that a particular db knows about a given topic
it returns the full topic name, so that :get_topic may be called on it later.
:dump_topic is used by maintainers (see $wiz:@gethelp) to edit help topics.

$generic_help and $help
-----------------------
The Generic Help Database, $generic_help, is the parent class of a particular
kind of help database of which $help is an instance.  On help databases of this
type, every help topic has a corresponding property, interpreted as follows:

  this.(topic) = string 	    
      one-line help text.

  this.(topic) = {"*<verb>*",@args}
      call this:<verb>(args,dblist) to get text where dblist is the list of 
      help objects that would have been consulted had the topic not been found 
      on this object.

  this.(topic) = other list of strings 
      multi-line help text

For the {"*<verb>*",...} form, the current verbs available are

  {"*forward*", topic, @rest}	
     - get help text for topic and then append the lines of `rest'.  
       rest may, in turn, begin with a "*<verb>*"...

  {"*pass*", topic, @rest}   
     - get help text for topic from the first help database after this one
       that actually has help text for topic, and then append lines of `rest'.
       As with "*forward*" rest may, in turn, begin with a "*<verb>*"...

  {"*subst*", @lines} 
     - All occurences of %[exp] in lines are replaced with the value of exp
	 which is assumed to evaluate to a string.  
       All lines beginning with %;exp are replaced with the value of exp 
	 which is assumed to evaluate to a list of strings.
       Evaluation is done using $no_one's permissions so exp in either case
       can only refer to public information.

  {"*index*", title}
     - returns a list of all topics in this database, arranged in columns.
       title is used as a heading for this index.

Individual help dbs are free to define additional verbs that may be used in
this context.  $help itself defines the following additional such verbs:

  {"*index_list*"}
     - returns a list of all index topics in all databases in the search list.
       An index topic is one whose actual text is {"*index*", something}.
       When creating a help db, you should be sure to make an index topic.

  {"*full_index*"}
     - prints indices for all help databases in the search list.

It should be noted (once again) that help databases need not be children of
$generic_help, so long as they have :find_topics/:get_topic/:dump_topic working
as specified above.

$GENERIC_OPTIONS
================

Generic Option Package
----------------------
It occasionally happens that one has a command or set of commands for which one
wishes to provide several options/flags that a player can set to customize the
command's behavior for him/herself.  Making each option a separate property is
a bit expensive, especially when the option in question is merely a boolean
flag that gets set to false in most cases.  This package provides an
alternative, as well as providing a uniform set of commands for setting these
flags/options and checking that the values given are of appropriate types.

Instead of needing several properties, only one is required to store a list
containing values for all of the options.  An "option package" (pkg, below) is
then an object of this class, which provides routines for manipulating such
lists.

The set of option names is divided into a set of "real" options, those whose
names will actually appear in a given list, and "extras" which are either
synonyms for or represent combinations of real options.

 pkg:add_name(name)	 adds name to .names  (remove it from .extras if there)
 pkg:add_name(name,1)	 adds name to .extras (remove it from .names if there)
    => 1 - ok, 0 - already added, E_INVARG - illegal name, E_PERM

 pkg:remove_name(name)	 remove name from either .names or .extras
    => 1 - ok, 0 - not present, E_PERM

For setting or retrieving values we have

 pkg:get(options,name) 
    => value (or 0 if name isn't a real option)
 pkg:set(options,name,value)
    => revised options (or string error message if something goes wrong)

By default, a given option can only be a boolean flag, having one of the values
0 (absent from the list), or 1 (present in the list).  :set translates 0/""/{}
to 0 and any other non-object value to 1.

One may however designate a wider range of possible values for an option "foo"
by either installing one of

  pkg.type_foo
    -- list of allowed types, 
       e.g., {NUM,STR}	 => must be a number or a string
       e.g., {OBJ,{OBJ}} => must be an object or a list of objects
    for anything fancier use:

  pkg:check_foo(value)
    => string error message or {value munged as desired}

In general, the only restriction on option values is that 0 is the only false
value; setting an option to "" or {} sets it to 0.  Every option defaults to 0,
and no matter what you install as .type_foo or :check_foo(), 0 will always be a
legal value for option "foo".

When presented with an option that is in .extras, :set will typecheck the value
as described, however, then :actual(name, value) will be called to obtain a
list of {name-of-real-option, value} pairs indicating which combination of real
options should be set.

Other verbs
  pkg:parse(args,...)
    parses the command line arguments of a @whatever_option command
    => {optionname, value}  if the player wants to set an option
    => {optionname}	    if the player wants to view an option
    => string error message  otherwise

  one may install pkg:parse_foo to parse arguments for option "foo" 
    !foo     => {"foo",0}  (:parse_foo not called)
    foo=     => {"foo",0}  (:parse_foo not called)
    -foo     => {"foo",0}  (:parse_foo not called)
    +foo     => pkg:parse_foo("foo",1)
    foo=word => pkg:parse_foo("foo","word")
    foo word1 word2    => pkg:parse_foo("foo",{"word1","word2"})
    foo is word1 word2 => pkg:parse_foo("foo",{"word1","word2"})

 pkg:show(options,name|list of names)
    => list of strings describing the current value of the named option(s).
       calls	 pkg:show_foo(options,list of names) or
       refers to pkg.show_foo
       to describe option "foo"

(see sources for details...  at some point I'll finish writing this... --Rog)

$GENERIC_UTILS
==============

Informa~E7~E3o geral sobre $generic_utils:
----
Isto e' o texto de ajuda para o Generic Utility Object ($generic_utils).
(Se voce^ esta' a ver isto com relac,a~o a algum outro objeco, e' porque o
objecto para que desea ajuda esta' sem documentac,a~o.	Manda uma conta do erro
para obter documentac,a~o melhor.)

$HOUSEKEEPER
============

The housekeeper is an object that can help keep other objects where they
belong.  New MOOs may want to add their own user interface for the housekeeper;
here is some information that may be helpful.

To indicate what objects should be cleaned:

  :add_cleanup(object[, requestor[, where]])
    Ask the housekeeper to clean 'object' for 'requestor' to 'where'.
    Requestor defaults to 'player'.
    Where defaults to object.location.

  :remove_cleanup(what[, requestor])
    Remove 'what' from the cleanup list at 'requestor's request.
    Will remove it only if 'requestor' made the original request and owns
    the object or the destination.

To actually get the housekeeper to clean stuff up:

  :cleanup([insist])
    Clean up player's objects.	Argument is 'up' or 'up!' for manually
    requested cleanups.  'up!' means to clean things even if it's against
    the housekeeper's better judgement.

  :replace(object[, insist])
    Clean up the indicated object.  'insist' is as in :cleanup.

  :continuous()
    Starts the housekeeper cleaning continuously, killing any previous
    continuous task.  This should be called only when starting up a new MOO,
    or if something has gone wrong, as normally it will just keep going
    without any help.

  :litterbug()
    Clean up all the places in housekeeper.public_places by getting rid of
    all contents not in their .residents lists.  This is called by
    :continuous, so it doesn't need to be called directly.

To find out what's being cleaned to where for whom:

  :cleanup_list([whom])
    Show 'player' the personal cleanup list for 'whom', or the housekeeper's
    complete list if no argument is given.

  :clean_status()
    Show 'player' a brief summary of eir personal cleanup list.

$LANGUAGE_UTILS
===============

Informa~E7~E3o geral sobre $language_utils:
----

The language utilities provide linguistic support for programming operations
available in common across all languages.

 $language_utils:localize_string(ml-string[,for-who])

   Localizes an ml-string for the given person (by default, player).
   For info on ml-strings, see `help ml-string'.

 $language_utils:localize_text(ml-text[,for-who/for-lang])

   Localizes an ml-text for the given person (by default, player)
   or language.  For info on ml-texts, see `help ml-text'.

 $language_utils:announce(...strings or ml-strings...)
 $language_utils:announce_all(...strings or ml-strings...)
 $language_utils:announce_all_but(but,...strings or ml-strings...)

   These are like player.location:announce, :announce_all, and
   :announce_all_but, except that they take ml-strings as well as strings.

 $language_utils:announce_to(where,...strings or ml-strings...)
 $language_utils:announce_to_all(where,...strings or ml-strings...)
 $language_utils:announce_to_all_but(where,but,...strings or ml-strings...)

   These are like :announce, :announce_all, and :announce_all_but,
   except they take a where argument instead of assuming it's player.location.

 $language_utils:tell(...strings or ml-strings...)
 $language_utils:tell_to(who,...strings or ml-strings...)

   :tell is like player:tell(...) and who:tell(...), except these allow
   ml-strings.

 $language_utils:tell_lines(...strings or ml-strings or ml-texts...)
 $language_utils:tell_lines_to(who,...strings or ml-strings or ml-texts...)

   :tell is like player:tell_lines(...) and who:tell_lines(...),
   except these allow ml-strings and ml-texts.

 $language_utils:tostr(...strings or ml-strings...)
 $language_utils:tostr_for(who/lang,...strings or ml-strings...)

   :tostr() is like tostr(...) but allows ml-strings and localizes for player.
   :tostr_for() is similar, but localizes for who (or lang).

 $language_utils:all_languages()

   returns a list of all languages.

 $language_utils:match_language(name)

   returns the language object corresponding to name.

 $language_utils:localizable_to(ml-text)

   returns a list of the languages for which ml-text is specifically
   marked as localizable.

 $language_utils:time_string([time])
 $language_utils:time_string_for(who/lang[,time])

   returns a string representing the given time (by default, the current time)
   in the language correct for player (for :time_string) or who
   (for :time_string_for); in the case of :time_string_for, a language is
   also acceptable as a first argument.

 $language_utils:ctime_components([time])
 $language_utils:ctime_components_for([time])

   produces the same information as :time_string_for, but in a list format.
   The order corresponds to the order of component presentations for ctime().

 $language_utils:ctime_components([time])

   produces the same information as :time_string_for, but in a list format
   where no linguistic processing is needed because all information is in
   a language-independent format.

 $language_utils:speaks(who,language)

   returns true of who speaks the given language.

$LIST_UTILS
===========

Informa~E7~E3o geral sobre $list_utils:
----

:match(<string>, <lista-de-objectos>)
 Retorna o objecto na <lista-de-objectos> ao qual se refere o <string>.
 Para mais detalhes, faz `ajuda $match_utils:match'.

:match_nth(<string>, <lista-de-objectos>, <n>)
 Retorna o objecto (de nu'mero <n>) em <lista-de-objectos> que tem
 alias(vulgo) de <string>.

:match_verb(<nome-de-verbo>, <objecto>)
 Procura o verbo <nome-de-verbo> apropriado no <objecto> 
 com os valores correntes de prepstr, dobjstr, dobj, iobjstr, e iobj.
 Se ha' tal verbo, esta' invocado e quando isso retorna,
 :match_verb() retorna 1; o se na~o ha', :match_verb() retorna 0.

:match_list(<string>, <lista-de-objectos>)
 Retorna todos dos objectos da <lista-de-objectos> com alias(vulgo)
 de <string>.

:parse_possessive_reference(<string>)
 Racha o <string> ingle^s (que deve conter um possesivo ingle^s como
 "joe's cat" ou "my dog") a duas partes (como {"joe","cat"} ou {"me","dog"}).

:parse_ordref(<string>)
 Racha o <string> ingle^s (que deve conter uma refere^ncia com nu'mero 
 ordinal como "second box") a duas partes (como {2, "box"}).

$MATH_UTILS
===========

Informa~E7~E3o geral sobre $math_utils:
----
Trigonometric/Exponential functions:
  sin(a),cos(a),tan(a) -- returns 10000*(the value of the corresponding
       trigonometric function) angle a is in degrees.
  arctan([x,]y) -- returns arctan(y/x) in degrees in the range -179..180.
       x defaults to 10000.  Quadrant is that of (x,y).
  exp(x[,n]) -- calculates e^x with an nth order taylor polynomial

Statistical functions:
  combinations(n,r) -- returns the number of combinations given n objects
       taken r at a time.
  permutations(n,r) -- returns the number of permutations possible given
       n objects taken r at a time.

Number decomposition:
  div(n,d) -- correct version of / (handles negative numbers correctly)
  mod(n,d) -- correct version of % (handles negative numbers correctly)
  divmod(n,d) -- {div(n,d),mod(n,d)}
  parts(n,q[,i]) -- returns a list of two elements {integer,decimal fraction}

Other math functions:
  sqrt(x)      -- returns the largest integer n <= the square root of x
  pow(x,n)     -- returns x^n
  factorial(x) -- returns x!

Series:
  fibonacci(n) -- returns the 1st n fibonacci numbers in a list
  geometric(x,n) -- returns the value of the nth order geometric series at x

Integer Properties:
  gcd(a,b) -- find the greatest common divisor of the two numbers
  lcm(a,b) -- find the least common multiple of the two numbers
  are_relatively_prime(a,b) -- return 1 if a and b are relatively prime
  is_prime(n) -- returns 1 if the number is a prime and 0 otherwise
  
Miscellaneous:
  random(n) -- returns a random number from 0..n if n > 0 or n..0 if n < 0
  random_range(n[,mean]) -- returns a random number from mean - n..mean + n
       with mean defaulting to 0
  simpson({a,b},{f(a),f((a+b)/2),f(b)}) -- returns the numerical
      approximation of an integral using simpson's rule

Bitwise Arithmetic:
  AND(x,y) -- returns x AND y
  OR(x,y) -- returns x OR y
  XOR(x,y) -- returns x XOR y (XOR is the exclusive-or function)
  NOT(x) -- returns the complement of x
      All bitwise manipulation is of 32-bit values.

$NO_ONE
=======

$no_one
-------
.is a powerless player.  He owns no objects, not even himself; nor does he own
any verbs.  He is, however, a programmer and thus may use eval().
In fact his sole purpose is to evaluate questionable code.
`questionable' could be in either or both of the following senses

(1) Its origin is sufficiently uncertain so that there is no obvious way of
deciding whose permissions it should run under.
(2) The code itself is potentially malicious, i.e., to the extent that one does
not want to be evaluating it using one's own permissions.

set_task_perms($no_one);  is thus the canonical idiom in wizard code for
rendering anything that follows mostly harmless.  For use by ordinary
programmers, we have:

    $no_one:eval(string)

which attempts to evaluate an arbitrary string using $no_one's permissions.
string is either an expression or ";" followed by one or more statements, of
which the final semicolon may be omitted.  return values are what eval() would
return (either {1,value} or {0,@error_messages}).

$OBJECT_UTILS
=============

Informa~E7~E3o geral sobre $object_utils:
----

Verbos para manipular palavras portuguesas.

:pluralize(nome)	  Retorna o plural do nome especificado.
:cardinal_number(N[,fem]) Retorna N como nu'mero cardinal (N=1 => "one").
:ordinal_number(N[,fem])  Retorna N como nu'mero ordinal (N=1 => "first").
:ordinal_num(N[,fem])	  Retorna N como nu'mero ordinal breve (N=1 => "1st").
:grouped_number(n[,m])	  Retorna N como nu'mero agrupado (N=1234 => "1,234").
			   With M, uses N/M (N=1234,M=10 => "1,234.5").

Nos verbos que implicam numerais cardinais e ordinais, se fem=0, o resultado e
masculino.  Se fem=1, o resultado e' feminino.	Por defeito, fem=0.

Para ver exemplos dos plurais, faz:
 @test_plural <palavra_ou_frase> on #1111
 @test_plurals on #1111

$QUOTA_UTILS
============

Informa~E7~E3o geral sobre $quota_utils:
----
Verbs a user might want to call from a program:
 :bi_create -- built-in create() call, takes same args.

 :get_quota(who) -- just get the raw size_quota property
 :display_quota(who) -- prints to player the quota of who.  If caller_perms()
controls who, include any secondary characters.  Called by @quota.
 :get_size_quota(who [allchars]) -- return the quota of who, if allchars flag
set, add info from all secondary chars, if caller_perms() permits.

 :value_bytes(value) -- computes the size of the value.
 :object_bytes(object) -- computes the size of the object and caches it.
 :recent_object_bytes(object, days) -- computes and caches the size of object
only if cached value more than days old.  Returns cached value.
 :do_summary(user) -- prints out the results of summarize-one-user.
 :summarize_one_user(user) -- summarizes and caches space usage for user.  See
verb help for details.

Verbs the system calls:
 :"creation_permitted verb_addition_permitted property_addition_permitted"(who)
-- returns true if who is permitted to build.
 :initialize_quota(who) -- sets quota for newly created players
 :adjust_quota_for_programmer(who) -- empty; might add more quota to newly
@progged player.
 :enable_create(who) -- sets .ownership_quota to 1
 :disable_create(who) -- sets .ownership_quota back to -1000 to prohibit
create()
 :charge_quota(who, object) -- subtract the size of object from who's quota. 
Manipulates the #-unmeasured if what is not currently measured.  Called by
$wiz_utils:set_owner.
 :reimburse_quota(who, object) -- add the size of object to who's quota. 
Ditto.
 :preliminary_reimburse_quota(who, object) -- Because the set_owner is done
*after* an object has been turned into $garbage, ordinary reimbursement fails. 
So we use this verb in the $recycler.
 :set_quota(who, howmuch)
 :quota_remaining(who) 
 :display_quota_summary -- internal, called by display quota

The measurement task:

 :measurement_task() -- runs once every 24 hours measuring stuff, separated
from the scheduling in case you just want to run it once.  Calls the body and
then reports via moomail.
 :schedule_measurement_task() -- actually schedules it.  Look here to change
the start time.
 :measurement_task_body(timeout) -- does the real work, working for no longer
than timeout seconds.
 .task_time_limit -- integer number of seconds indicating for how long it
should run each day.
 .working -- object indicating the player whom it is either working on now (or
if not running) will pick up working on when it commences tonight.
 .cycle_days -- integer numbers indicating how long ago an object must have
been measured before it will be remeasured.
 .repeat_cycle -- boolean.  0 means have a vanilla cycle (goes through all
players() exactly once measuring their objects measured more than .cycle_days
ago).  1 means to have a much more complex algorithm: The first cycle, it only
measures stuff owned by people who have logged in within .cycle_days.  If, in
.task_time_limit seconds, it measures all objects not measured in cycle_days
owned by such people, it will run again measuring those objects which have not
been measured in cycle_days - 1, considering people who have logged in within 4
* cycle_days, repeating until it has used up its seconds.  ("Doing some of
tomorrow's work.")  Selecting .repeat_cycle = 1 is appropriate only for large
MOOs.
 .exempted -- list of objects to never measure (useful if there are huge
objects).  Suggested huge objects include $player_db and $site_db.
 .measurement_task -- indicates the task_id() of the most recent measurement
task -- used to prevent duplicate invocation.
 .report_recipients -- recipients of the daily reports.  Set to {} to disable
reporting entirely.

See help @measure and help @quota for the command line verbs.


Porter's notes:  If you are planning on porting this system to another MOO,
here are the things to grab in addition to @dumping all of $quota_utils:

The following verbs have been changed on $prog:
@prop*erty @verb @copy (@add-alias @copy-move as well)

The following verbs have been changed on $wiz:
@programmer @quota

The following verbs have been changed on $wiz_utils:
set_programmer set_owner make_player

The following verbs have been changed on $builder:
@quota _create

This verb probably should have gone on $builder.
@measure

The followig verbs have been changed on $recycler
_recycle _create setup_toad

The following verb has been changed on $login:
create

And don't forget $object_quota_utils, which has the object based
implementation.

$RECYCLER
=========

$recycler
=========

Rather than having the server built-in recycle() and create() functions handle
the creation and destruction of objects, a recycling center has been created to
simulate these actions by  changing objects that would have been recycled into
children of $garbage (The Generic Garbage Object) and making them owned by
Hacker, and then when they're needed again, to avoid a raw create() command,
those objects are given to whoever's asking for them.

Most Useful Verbs
-----------------

$recycler:_recycle( object )
  This will effectively recycle an object. (As a point of fact, it changes
ownership of the object to Hacker and makes the object a child of $garbage.) 
It handles .ownership_quota and .owned_objects properly.  Generally, use this
instead of a recycle() in your verbs.

$recycler:_create( parent object [ , new owner object ] )
  This effectively creates an object (with the specified parent, if possible,
and with the specified owner, if possible; these are the same restrictions as
on the server create() builtin).  This is what should generally be used instead
of create() in your programming.

$recycler:valid ( object )
  This is a variant of the server built-in valid() except that it handles the
$garbage objects as well.  It returns a 1 if the object specified -is- valid
and is -not- a $garbage object.

Other Notes
-----------

request <object> from <recycler>
  This is not an internal verb (it's !x).  It is, however, a command-line verb
that can be used to request a specific object from the recycler.  It's also
useful for the creation of objects like a Magic Number Repository.  When the
object is removed from the recycler, the .announce_removal_msg is announced to
the room if it's set (it's piped through $string_utils for pronoun
substitution).

show-history <recycler>
  This is a wizardly verb which allows wizards to check the `history list' of
the recycler. The history maintains the latest ($recycler.nhist) entries.

$recycler.orphans
  This maintains a list of objects for which the recreation process got
mangled. It ought to be checked every once in a while to see what's up.

$ROOM
=====

The Generic Room ($room)
----------------

(1)  Announcements

:announce	  (@text)	  => broadcasts to all except player
:announce_all	  (@text)	  => broadcasts to all
:announce_all_but (objects,@text) => broadcasts to all except those in objects

say, emote


(2)  Command recovery

:huh		(verb,args) - server hook: last chance to make sense of verb
:here_huh	(verb,args) - room's last attempt to parse something
:here_explain_syntax (this,verb,args) - attempts to explain usage of verb


(3)  Residency

free_home  - true => @sethome allows anyone to set his .home to be here
residents  - objects on this list may teleport in and/or set their homes here.

:accept_for_abode(player) 
	    => true iff player should be allowed to set .home to this room.

@resident*s


(4)  Looking

dark  - true => contents are not visible
ctype - 1..4 for four different styles of .contents lists

:match	       (string)        => exit or object in room's .contents
:tell_contents (objects,ctype) - format objects according to ctype, tell player

l*ook


(5)  Entrance and exit.

:accept (object) - Called by move() and :moveto() before an object enters a
room, if false is returned, movement is prevented.  Protocol permits this verb
to make noise (though this is discouraged) as this is the only place the room
will learn the object's original location.

:acceptable (object) - Called by verbs which wish to check whether movement
will be possible.  Protocol prohibits this verb from making noise and requires
it to return the same value as :accept would for the same arguments.

:is_unlocked_for (object) - interface with the @lock protocol.	Returns true or
false depending on the state of locks for the object with the room.  Other
things may prevent entrance even if this returns true.	Protocol prohibits this
verb from making noise. 

:enterfunc (object) - called after entrance has succeeded.  Noise is fine.

:exitfunc (object) - called after an object has successfully left.  Noisemaking
is fine.

(6)  Topology and Movement via Exits

See `help $exit' for an explanation of how the generic $exit works.

free_entry     - true  => `teleporting' in is allowed
		  false => only residents may teleport in
exits	       - list of invokable exits leading from this room
entrances      - list of recognized exits leading to this room
blessed_object - object currently entering via an exit
blessed_task   - task_id for entering object

:match_exit	 (string) => exit whose name matches string
:bless_for_entry (object) - set up room to accept object arriving from entrance
:add_exit	 (exit)
:add_entrance	 (exit)
:remove_exit	 (exit)
:remove_entrance (exit)

e/east/w/west/s/south/n/north/ne/northeast/nw/northwest/se/southeast/sw/southwe
st/u/up/d/down, go, @add-exit, @add-entrance, @remove-exit, @remove-entrance,
@exits, @entrances 


(7)  Ejection

victim_ejection_msg/oejection_msg/ejection_msg
:*_msg()  messages

@eject


$SEQ_UTILS
==========

Informa~E7~E3o geral sobre $seq_utils:
----
Uma seque^ncia e' um conjunto de inteiros (*)
Este pacote fornece os seguintes verbos:

  :add	    (seq,f,t)  => seq com o intervalo [f..t] adicionado
  :remove   (seq,f,t)  => seq com o intervalo [f..t] removido
  :range    (f,t)      => seque^ncia correspondente a [f..t]
  {}		       => seque^ncia vazia
  :contains (seq,n)    => n na seq
  :size     (seq)      => nu'mero de elementos da seque^ncia
  :first    (seq)      => primeiro inteiro na seq ou E_NONE
  :firstn   (seq,n)    => os primeiros n inteiros da seq (como seque^ncia)
  :last     (seq)      => u'ltimo inteiro da seque^ncia ou E_NONE
  :lastn    (seq,n)    => n u'ltimos inteiros da seq (como seque^ncia)

  :complement(seq)	 => [-2147483648..2147483647] - seq
  :union    (seq,seq,...) 
  :intersection(seq,seq,...) 

  :extract(seq,array)		=> array[@seq]
  :for([n,]seq,obj,verbo,@args)  => for s in (seq) obj:verbo(s,@args); endfor

  :tolist(seq)		  => lista correspondente `a seq
  :tostr(seq)		  => elementos da seque^ncia como uma string
  :from_list(lista)	  => seque^ncia correspondente `a lista
  :from_sorted_list(list) => seque^ncia correspondente `a lista ( assumindo
			     que esta' ordenada )
  :from_string(string)	  => seque^ncia correspondente `a string

Para expresso~es boolenas, note que
  a representac,a~o da seque^ncia vazia e' {} (FALSO booleano) e
  todas as seque^ncias na~o vazias sa~o representadas por listas na~o
    vazias (VERD booleano)

A representac,a~o utilizada funciona melhor que a implementac,a~o por listas
usual para conjuntos compostos por grandes domi'nios ininterruptos de inteiros.
Para conjuntos dispersos de inteiros a representac,a~o e' decididamente na~o
o'ptima (embora nunca ocupe mais de o dobro do que a representac,a~o usual por
listas).

(*) Na verdade, o que este pacote implementa sa~o conjuntos de
inteiros-mod-2^32, mas para isso assume-se que a ma'quina onde o servidor esta'
a correr tem inteiros de 32 bits.  Se na~o, precisa-se de alterar this.maxneg
para ser o maior inteiro negativo ("menor"?) disponivel.

$SET_UTILS
==========

Informa~E7~E3o geral sobre $set_utils:
----
Este objecto e' util para operac,o~es que tratam as listas como conjuntos
(i.e., sem se importarem com a ordem e assumindo a na~o existe^ncia de
duplica,co~es).

 union(conj, conj, ...)        => unia~o
 intersection(conj, conj, ...) => intersecc,a~o

 diff*erence(conj1, conj2, ..., conjn)
	=> resultado da remoc,a~o de todos os elementos dos conjuntos 2..n
	   do conjunto 1

 exclusive_or(conj, conj, conj, ...)
	=>  todos os elementos que esta~o contidos exactamente em
	    um dos conjuntos

 contains(conj1, conj2, ..., conjn)
	=> verdadeiro se e so' se todos os conjuntos 2..n sa~o
	   subconjuntos do conjunto 1

 equal(conj1, conj2)
	=> verdadeiro se e so' se o conj1 e conj2 sa~o iguais

$STRING_UTILS
=============

Informa~E7~E3o geral sobre $string_utils:
----
Para uma descric,a~o completa de um certo verbo ( em ingle^s ), fac,a `ajuda
$string_utils:nomedoverbo'

    Rotinas de conversa~o:

:join/from_list    (list [,sep])		     => "foo1foo2foo3"
:english_list (str-list[,none-str[,and-str[, sep]]]) => "foo1, foo2, and foo3"
:title_list*c (obj-list[,none-str[,and-str[, sep]]]) => "foo1, foo2, and foo3"
						  or => "Foo1, foo2, and foo3"
:from_value   (value [,quoteflag [,maxlistdepth]])   => "{foo1, foo2, foo3}"

:to_value	(string)     => {sucesso?, valor ou mensagem de erro}
:prefix_to_value(string)     => {resto da string, valor} ou
				{0, mensagem de erro}

:english_number(42)	     => "forty-two"
:english_ordinal(42)	     => "forty-second"
:ordinal(42)		     => "42nd"
:group_number(42135 [,sep])  => "42,135"

    Verificac,a~o de tipos:

:is_numeric   (string) => retorna verdadeiro se a string e' composta
			  unicamente por digitos

    Parsing:

:split/explode (str,char) -- string => lista de palavras delimitada por
caracter
:words	 (string)      -- string => lista de palavras ( como no analisador da
							da linha de comando )
:word_start (string)   -- string => lista de pares ini'cio-fim

    Matching:

:match_string (string, pattern, options)       => * wildcard matching
:find_prefix  (prefix, string-list)=>list index of element starting with prefix
:index_delimited(string,target[,case]) =>index of delimited string occurrence
:match	      (string, [obj-list, prop-name]+) => matching object
:match_player (string-list[,me-object])        => list of matching players
:match_object (string, location)	       => default object match...
:literal_object (string)		       => match against #xxx, $foo
:match_stringlist (string, targets)	       => match against static strings
:match_string (string, wildcard target)        => match against a wildcard

    Pretty printing:

:space	       (n/string[,filler])     => n spaces
:left	       (string,width[,filler]) => left justified string in field 
:right	       (string,width[,filler]) => right justified string in field
:center/re     (string,width[,filler]) => centered string in field
:columnize/se  (list,n[,width])        => list of strings in n columns
:tabulate(heading1,data1,heading2,data2,...)
				       => Makes a table from the indicating
					  headings and lists of data.

    Substituic,o~es

:substitute (string,subst_list [,case])   -- substituic,o~es gerais
:pronoun_sub (string/list[,who[,thing[,location]]])
					  -- substituic,o~es de pronomes
:pronoun_sub_secure (string[,who[,thing[,location]]],default)
					  -- substitui e verifica nomes
:pronoun_quote (string/list/subst_list)   -- quoting for pronoun substitutions.

    Miscellaneous string munging:

:trim	      (STR)	  => string with outside whitespace removed.
:triml	      (STR)	  => string with leading whitespace removed.
:trimr	      (STR)	  => string with trailing whitespace removed.
:strip_chars  (STR,chars) => string with all chars in `chars' removed.
:strip_all_but(STR,chars) => string with all chars not in `chars' removed.
:capitalize/se(STR)	  => string with first letter capitalized.
:uppercase/lowercase(STR) => string with all letters upper or lowercase.
:names_of     (list of OBJ)  => string with names and object numbers of items.
:a_or_an      (word)	     => "a" or "an" as appropriate for that word.

    Uma propriedade u'til:

alphabet		    => "abcdefghijklmnopqrstuvwxyz"

Existe uma versa~o com _suspended no fim do nome para:
     :print	:from_value	:columnize/se	   :match

$TIME_UTILS
===========

Informa~E7~E3o geral sobre $time_utils:
----
    Converting from seconds-since-1970	  
dhms	      (time)		     => string ...DD:HH:MM:SS
english_time  (time[, reference time)=> string of y, m, d, m, s

    Converting to seconds
to_seconds    ("hh:mm:ss")	     => seconds since 00:00:00
from_ctime    (ctime)		     => corresponding time-since-1970
from_day      (day_of_week, which)   => time-since-1970 for the given day*
from_month    (month, which)	     => time-since-1970 for the given month*
    (* the first midnight of that day/month)
parse_english_time_interval("n1 u1 n2 u2...")
				     => seconds in interval
seconds_until_time("hh:mm:ss")	     => number of seconds from now until then
seconds_until_date("month",day,"hh:mm:ss",flag 
				     => number of seconds from now until then
					(see verb help for details)

    Converting to some standard English formats
day	      ([c]time) 	     => what day it is
month	      ([c]time) 	     => what month it is
ampm	      ([c]time[, precision]) => what time it is, with am or pm
mmddyy	      ([c]time) 	     => date in format MM/DD/YY
ddmmyy	      ([c]time) 	     => date in format DD/MM/YY

    Substitution
time_sub      (string, time)	     => substitute time information

    Miscellaneous
sun	      ([time])		     => angle between sun and zenith
dst_midnight  (time)		     

$TRIG_UTILS
===========

Informa~E7~E3o geral sobre $trig_utils:
----
Trigonometric/Exponential functions:
  sin(a),cos(a),tan(a) -- returns 10000*(the value of the corresponding
       trigonometric function) angle a is in degrees.
  arctan([x,]y) -- returns arctan(y/x) in degrees in the range -179..180.
       x defaults to 10000.  Quadrant is that of (x,y).
  exp(x[,n]) -- calculates e^x with an nth order taylor polynomial

Statistical functions:
  combinations(n,r) -- returns the number of combinations given n objects
       taken r at a time.
  permutations(n,r) -- returns the number of permutations possible given
       n objects taken r at a time.

Number decomposition:
  div(n,d) -- correct version of / (handles negative numbers correctly)
  mod(n,d) -- correct version of % (handles negative numbers correctly)
  divmod(n,d) -- {div(n,d),mod(n,d)}
  parts(n,q[,i]) -- returns a list of two elements {integer,decimal fraction}

Other math functions:
  sqrt(x)      -- returns the largest integer n <= the square root of x
  pow(x,n)     -- returns x^n
  factorial(x) -- returns x!

Series:
  fibonacci(n) -- returns the 1st n fibonacci numbers in a list
  geometric(x,n) -- returns the value of the nth order geometric series at x

Integer Properties:
  gcd(a,b) -- find the greatest common divisor of the two numbers
  lcm(a,b) -- find the least common multiple of the two numbers
  are_relatively_prime(a,b) -- return 1 if a and b are relatively prime
  is_prime(n) -- returns 1 if the number is a prime and 0 otherwise
  
Miscellaneous:
  random(n) -- returns a random number from 0..n if n > 0 or n..0 if n < 0
  random_range(n[,mean]) -- returns a random number from mean - n..mean + n
       with mean defaulting to 0
  simpson({a,b},{f(a),f((a+b)/2),f(b)}) -- returns the numerical
      approximation of an integral using simpson's rule

Bitwise Arithmetic:
  AND(x,y) -- returns x AND y
  OR(x,y) -- returns x OR y
  XOR(x,y) -- returns x XOR y (XOR is the exclusive-or function)
  NOT(x) -- returns the complement of x
      All bitwise manipulation is of 32-bit values.

$WIZ_UTILS
==========

Informa~E7~E3o geral sobre $wiz_utils:
----

Copyright © 1994-2017 MOOsaico, Multilingual Virtual Community
All Rights Reserved. Todos os direitos reservados.
23 years of MOO (1994-2017)