
                                     LIRC Help
                                     ---------

0. Sections
===========

 1. General Use
 2. Setting up choices
 3. Terminal windows
 4. List of people
 5. List of channels
 6. List of members
 7. Format of NickLine, ChanLine & MembLine
 8. Lag Monitor
 9. Text Styles
10. Scripts
11. Children
12. DCC, masquerading, firewalls, etc.
13. The rest
14. Credits
15. Licence


1. General use
==============

Running this requires some toolbox modules, and obviously an internet stack.

It also requires some knowledge of IRC. There are plenty of texts about this,
and I'm not going to repeat it. Here are some links:

http://www.irchelp.org/
http://www.ircnet.org/

Clicking Select on the iconbar icon will open a terminal window and attempt to
connect to your chosen server (if neither of these things have already
happened).

Clicking Adjust will show the Choices, and these are probably what you will
want to change first.


2. Setting up choices
=====================

Connection details
------------------
'Server' is any irc server you like and have access to. There are a few
common choices supplied (and some not so common), but you will have your own
preferences after a while. The list is stored in the Servers file, and you
can edit this to suit yourself.

Be aware, that servers are connected to a certain irc network, and there are
a few of these networks around. Some of them have chosen not to follow
rfc1459 to the letter, and you may have problems with them. For example,
DALnet allows very long nicknames, and will not work with LIRC.
IRCnet, Undernet, and EFnet have been used without problems.

'Retry after' is used if you lose the connection. It will automatically try
to reconnect after the specified time.

'Connect when loaded' will automatically open the window and connect to the
server when the program is loaded. You probably don't want this until you
have set up your user details, so it is off by default.

'Nick', 'User', 'Password', and 'Real name' are all given to the server when
you connect. Usually you will leave password blank, meaning 'none'.
You might find that the nickname you've chosen is already in use. In this
case LIRC will keep trying, while appending an increasing number to your nick
until it is accepted. If this has happened, you might want to change it to
something else, using the command:
/nick <another_nick>

'User info' and 'Finger info' are not given to anyone, unless they ask with
the corresponding ctcp requests.

Terminal windows
----------------
'Terminal lines' sets the height of the windows, in lines.

'Initial height' is used when new terminal windows are opened.

'Line spacing' sets the space between lines, in pixels.

'Left margin' and 'Right margin' will leave leave extra space to the left or
right of the actual window content. Note than if you change this, it will only
have effect when new lines are printed in the window.

'History lines' defines how many commands will be stored in the history
before it starts discarding the oldest ones.

'Horizontal scroll' controls the presence of a horizontal scrollbar on the
terminal windows. Like many of the other settings, changes will only have an
effect on windows opened after the change.

'Auto CAPS' turns on a special feature, that is not very style-guideish.
When the caret is gained, a local CAPS state applies. When it is lost,
the previous state is restored. This can be very handy, but you need to
be aware of what is happening.

'Auto-open friends' will enable opening of new terminal windows automatically.
This can be a great irritation if it is done when anybody sends you a message
(e.g. spam-bots etc.). So only people that are listed as 'friends' will
make a new window open when they speak to you privately.

'Indent wrapped lines' will make extra space before any lines that are wrapped
because they wouldn't fit on one terminal line. The space added will correspond
to the prefix used.

'Display bold text' refers to text containing ascii 2. If this is turned on,
such a character will switch to a brighter version of the colour. The next
one will switch back.

'Display coloured text' is the same kind of effect, but this refers to the
"miRC colours", turned on and off with ascii 3.

'Bold/colour entry using ...' will enable you to enter colour/bold effects
yourself, using the character you set up (default is '~'). See below for
details on this. Be aware, that use of colours are frowned upon by many people,
and some channels will instantly (and automatically) ban you for it.

'Nick length for highlight' controls how much of your nick should appear before
it is turned bold. Setting it to 0 turns this feature off. Nicks won't go
bold if they appear as part of a word, except if they are given in full at
the start of a word.

General use
-----------
'Import period' is used when you drag a text file to the entry-icon. The file
will be sent to the current channel, one line at a time. The Import period
is how long a pause there is between each line sent.
If you set this lower (i.e. faster) than 'Message penalty' (see below), long
files will cause lines to queue up in the output buffer. This can be confusing,
so don't do it unless you have a specific reason.

'Time format' describes the format of the date/time printed in the window or
put into the log file. It is not used by default, but can be turned on by
redefining the Style (see below).

'Speech' turns on speech, using either Superior Software's Speech! module,
or J. Duddington's !Speak application.

'Cut speech' applies only to !Speak, and will cut off previous sentences
when a new one arrives.

'Fixed lists' makes the People and Channel list windows stay the same visible
size, even when entries are added or removed. They will also scroll down
if a new entry is added, but it would be invisible (below the bottom edge).

'Smart lists' will have effect if the pointer is over a list when it changes.
The window will be moved so the pointer is still over the same item in the
list. This can be very handy, escpecially if you're about to click on
something.

'Confirm Quit if connected' will just open a confirmation box if you quit
the program while being connected to the server.

'WimpCTCP has priority' will give external CTCP apps the first shot at dealing
with a CTCP request, then use the internal ones. Turning it off does exactly
the opposite, and this is the default.

Logging
-------
'Logging to:' turns on and off the log files. These are stored in the 'Logs'
directory, given a name that says when they were started. The name is defined
by the writable field, which is a string like "Time format" above. The name
may contain ".", in which case subdirectories are created in the Logs
directory. As an example, I use "%ce%yr.%mo.%dy_%24%mi", which results in
files like <LIRC$Log>.2000.August.23_1817
The display field below will show an example of the log file pathname, or any
problems associated with it.

'Min log size' sets the minimum size of log files you want to keep. If the log
ends up smaller than this, it is removed. Set it to 0 to keep all logs.

Inbound flood protection
------------------------
This is best left alone unless you have a problem with it. The numbers refer
to the limit before the protection kicks in.
For example: All msgs, Max number = 8, Time = 2.00.
This means that if more than 8 messages are received in under 2 seconds,
it is an offence, and the sending party will be ignored until you say
otherwise.
This protection can be overridden by the list of 'Friends', see below.
The 'General' type applies to everybody, also friends. This watches messages
from anyone, but only the ones directed at you in particular. When it kicks
in, it won't start ignoring everybody, but rather change your nickname. Some
nitwits will attack you by sending messages from 50-100 different bots at once.
While this is no problem for LIRC, it can put a real strain on the server
you're on, and it may disconnect. When your nick changes, all the pending
messages are discarded by the server. So it is less likely to kill you.
All this 'attacking' might seem like strange behaviour to you and me, but the
attackers don't know that, because they are nitwits.

Outbound flood protection
-------------------------
This is protection against being kicked off the server for sending too much
data too quickly. You can alter this because different servers (and networks)
impose different limits. It is not easy to find out exactly what the limit is
on a given server, and the easiest is probably to ask the administration. If
you ever get kicked off with the reason "Excess flood", either the 'Message
penalty' or the 'Time base' is set too low.

The explanation of what happens to your outgoing messages is as follows:
Assume a Time base of 10 sec, and a Message penalty of 2 sec.
If you send messages with 2 seconds or more between them, nothing special
happens at all, they are just sent. If you send them faster, with e.g. 1.5
seconds in between, the remaining 0.5 second penalty is added to a total every
time. When this total is more than 10 seconds (i.e. after 20 messages), they
start being put on hold in a queue (this is when the server would have kicked
you off). The queued messages are then sent off as time passes, exactly when
it's safe to do so.
While this is happening, the bar at the left of the input line is all red.
This bar shows the 'penalty total' mentioned, and goes from 0 (all grey) to
'Time base' (all red).

The practical upshot of which is, that if you ever see an all-red bar, you
will know that whatever message you enter, it will not be sent immediately.

Reaction times
--------------
These all refer to the duration of various events.

'Doubt nick/channel after' controls how often a nick or channel will be
checked to see if it still exists. This only happens if nothing has been
heard from the nick/channel for this amount of time.

'Nick/channel activity' refers to the green 'activity bars' you can add to
the People/Channel lists (see below). These times define how long it takes
for the bars to disappear.

'Lag check period' is the time between checking the lag between you and the
server. See "Lag Monitor" below for details.

File reception (dcc_rx)
-----------------------
This is used when you receive a file from someone.

'Truncate filenames to 10 chars' can be useful on some ADFS discs.

'Create default directory' will create a directory called "dcc_rx" in
LIRC$Scrap. Inside that is created another directory with the same name as
the sender of the file. This is then opened, and the default filename is set
to be inside this last directory. In effect, it enables you to just press
'Start' when you are offered a file, instead of first dragging the icon
somewhere.

File transmission (dcc_tx)
--------------------------
This is used when sending a file to someone.

'Block size' affects the speed. Increasing it cal speed up the transfer, but
obviously also uses more memory.

'Fixed host'. If the receiver can't seem to connect, you might have a special
connection (perhaps through a proxy/firewall). In the case where the IRC server
has the wrong idea about which machine you are using (i.e. your hostname is
wrong in /whois), you can set this variable to your real hostname or IP (the
one visible from outside). See also the "DCC, masquerading, firewalls, etc."
section below.

'Fixed port'. Alternatively (for some firewall configurations), if your IP is
ok, but people still can't connect, you can set a fixed port number to use. The
ident port (113) is sometimes open for outside connections (as the only one).

Others
------

'Open' will open the choices directory in !Boot. This is handy for getting
at those files when you want to edit them.

'Save&use' and 'Use' are self-explanatory, except you should know that also
the colour choices are saved when you click Save & Use.

Note that when you save the choices, or any of the other lists that can be
saved, they will be stored in <Choices$Write>. This means that the default
choices in the application directory are unchanged, and you can overwrite
with a newer version without losing your saved choices. It also means that
you can revert to the default settings by deleting one or more files in the
!Boot.Choices.IRC.LIRC directory.


3. Terminal windows
===================

The Terminal windows are where all the text appears that you receive and
send.
If the window has a target (displayed in the title), you will have the
ability to execute certain commands on that target from the menu.
You can also open the People or Channels lists, which will be described
later.
The Selection submenu is very simple, just allows you to Select all and
Clear selection.
Lastly, you can redefine the colours and voices used, and your own face.

If you have selected something, you can treat it almost as a text file in a
filer window. That means you can drag the selection (from within it) to any
other program, or a filer-directory, and it will be copied there. You can
also drag it to the entry icon beneath, and have it entered as commands. Or
you can double-click on it, and have it run like a text file would. When
saving it to disc, it gets a name that is related to the window's target.
If you want to drag from a window that isn't current, and want to keep it that
way, hold shift when you click.

URLs will be recognised if they contain "://". They will then become "URL
colour" (default yellow), and you can launch them by double-clicking.

If you drag a Zap font file into the window, that font will be used. These
are usually found somewhere in !Zap.Fonts. It will be copied as part of your
choices, and you don't need to 'save choices' to keep it.

Dragging a different file into the window will prepare a DCC transfer of
that file to the target. The title bar shows the current target at all times.
This also works with selected parts of windows. You can't DCC a whole channel,
so any attempts at this will be ignored.

Anything you type into the 'entry icon' below, will be sent to the current
target. The exception to this is lines starting with '/'. These are commands,
either to LIRC or to the irc server. I won't explain much about them here,
because there is help on every one of them, which you can access by typing
'/?'. If a command is not understood, it is sent to the server, which might
know what to do.
If you need to start a text line with '/', use '//', e.g. "//dev/null".

The buttons below the entry icon are called 'Macros' for want of a better name.
They are defined in the !Macros file, and you can make your own.
This can be done by editing the file, and saying "/load macros".
Or you can shift-click on a button. The command that will define it is put
into the entry-icon, and you can examine and edit it.
If you want to keep your redefined macros, use "/save macros".

Other functions of the terminal window are:
* Clicking in the window makes it 'current', and it gains the entry-box.
* Double clicking on an URL (that shows up yellow), will launch it.
* Pressing TAB in an empty entry icon, will type in '/msg <last>', where <last>
  is the last person that sent you a private message (or a ctcp).
* Shift-TAB will open a new terminal window to that person instead.
* Pressing TAB in front of some word, will 'complete' that word.
  If the word starts with /, it will complete the command.
  If it starts with #, &, !, or +, it will complete a channel name (using the
  ones in the channel list).
  Otherwise it will complete a nick, using the 'People' list.
* Pressing up or down arrow will recall previous commands/messages from the
  history.
* Pressing Shift-up/down arrow will select the previous/next terminal window.
* Pressing Return executes the command or sends the message, and clears the
  icon.
* Ctrl-C will 'copy' the current selection, sending it to the current target
  one line at a time. If there is something in the entry-line at the time,
  the selection will be prefixed with whatever is to the left of the caret,
  and postfixed with the part to the right.

Internal targets
----------------

In addition to the normal targets of channels, nicks etc., there are a few
"internal" targets, that all start with "%":

%Help		Help text will come from this target. Talking to the target
		will give help on what you said (exactly like /?).
%Debug		This displays full information of the raw IRC commands sent and
		received. Talking to the debug target will send the text
		directly to the server with no interpretation.
%Error		All errors appear from this target.
%Internal	All remaining internal texts will be from this target.

So what can you use these for? The most obvious application is saying things
like "/open %help". This will give you a specific window to browse the help
files in.
Other than this, it is mostly used from scripts that need to react to these
targets, or ensure their own output (e.g. errors) go to the right place.


4. List of people
=================

This list contains nicknames known to LIRC. People become known when they do
something that you can see - sending you a message, being in a channel you're
examining, etc.

The appearance of the list is user-defined. The 'NickLine' file contains
instructions about how the list looks, and what happens when you click
in it. The description below applies to the default 'NickLine'.

There are several things you can do to each nick. Some of them are accessible
from the menu, and from clicking in the window:
'Query'  selects that nick as the current target. The same happens when you
         click Select on the nick.
'WhoIs'  requests information (from the server) about that nick. The same
         happens when clicking Select on the '?' button.
'Trace'  requests a trace of the route to that nick.
'Op'     makes that person an operator on the current channel, if you are an
         operator yourself. The same happens when clicking Select on the 'op'
         button.
'DeOp'   takes away operator status from that person. Also only works if you
         are an operator. The same happens when clicking Adjust on the 'op'
         button.
'Kick'   kicks a person off the current channel. You need to be op for this too.
         The same happens when clicking Select on the 'boot' button.
'Forget' removes the nick from the list. It will reappear if the person does
         something 'visible' again. A person who is on a channel with you is
         always visible, so you can't remove those.
The 'CTCP' submenu contains other functions. All of them sends a ctcp of that
type to the person in question.

Clicking Adjust on the face to the left of the nick, requests that person's
face. Normally used when you haven't got it already.

Clicking on the 'square' button will open/close a window with the nick as the
target. This is handy for initiating a private conversation.

Clicking on the 'no entry' button registers/unregisters a ban on that person's
hostmask (in the current channel). You need to be operator to do that.

Clicking on the 'garbage can' button will filter out all or nothing of what
comes from that person's hostmask. See the help on /ignore for details.

Clicking on the 'smiley' button will register/unregister that person as a
friend. Friends can flood you without the flood protection kicking in (but
if it's bad, the general protection will).

Dragging a file to a nick, will prepare for a DCC transfer to that person.
You need to accept the transfer before it actually starts.

Clicking on the hostmask will send a Info DNS ctcp to yourself. If !IRCInfo
is available, this will return DNS information about that host.


Format of faces
---------------

A face sprite must be 16 by 16 pixels. It is 16 colour greyscale, with a
palette going from black (0) to white (15). ChangeFSI can generate these, if
you set it to 16 colours (square pixels), and Special mode "t".
Using the 'Your face' box is the easiest way of registering your own sprite.


5. List of channels
===================

Like the list of people, this contains a list of known channels. These are
channels that have been seen, plus any in the 'Channels' file. You can use
"/save channels" to save the list, and then add any channels you want to
be known at startup. They will start disappearing if they don't actually
exist.

Again, the list is defined in 'ChanLine'. The following is for the default
ChanLine file.

The small green bar shows activity in the channel.
Clicking Select on a channel will make it the current target.
Select/Adjust on the square will open/close a window, like above.
Select on the '?' button requests a list of the people on that channel.
Adjust will enquire about the mode of that channel.
Select on the '+' button will make you join that channel.
Adjust makes you leave.

The menu has the some of the same functions, plus the ability to change the
topic. You need to be op on the channel to do that.

You can also make CTCP requests to the channel. The populations of many
channels will regard this as annoying behaviour.

To open a list of Members (below), choose the 'Members' entry. You must have
joined the channel for this to work.


6. List of members
==================

The member lists each applies to a channel you have joined, and contains the
people in that channel. Unlike the other lists, these are kept up to date
with no 'reaction' time. And the functions available are easier to use, as
both the nick and channel names are known.
The 'MembLine' file contains the format of these lists.
The default MembLine file is almost identical to the NickLine file, with
the exception that the 'op' button shows the current op status. This is
possible because the channel is known. Otherwise it works like the People
list. There is no 'Forget' menu entry, because of the abovementioned update
method.


7. Format of NickLine, ChanLine & MembLine
==========================================

These files contain a line for each icon in a list. A line consists of TAB-
seperated parametres:

<type>	<width>	<select>	<adjust>

There are 14 icon types, some will only work in certain lists.
Each has a default width. For some types, the width is taken from a sprite:

Type		Works in list	Default Width	Appearance

!face		N M		32		Plots the face if any
!nick		N M		180		Nickname
!host		N M		512		Hostmask
!name		 C		256		Channel name
!topic		 C		1024		Channel topic
!join		 C		join0		Join button
!talkh		NC		32		Horizontal activity bar
!talkv		NC		8		Vertical activity bar
!friend		N M		friend0		Friend button
!ignore		N M		ignore0		Ignore button
!op		  M		op0		Op button
!voice		  M		voice0		Voice button
!watch		N		watch0		Watch button
<sprite>	NCM		?		Generic button

The <sprite> type is taken as a 'generic button'. The type is the name of the
sprite to use. The sprite also determines the default width.
If the sprite doesn't exist, the 'nosprite' button is used instead.
These sprites reside in <LIRC$Dir>.Sprites

<width> allows you to adjust the widths relative to the default. This is a
signed number of os-units.

If <adjust> or <select> are missing, nothing happens when you click.
Otherwise the given command is executed. Parameters are given to all
commands, and you can use them by including %<number>.
The parameters are:
%0	Channel name (current target in people list ('*' if none))
%1	Nickname (nothing in channel list)
%2	Hostmask (nothing in channel list)

There is a special type too:
!space	<gap>

This doesn't create an icon, but leaves a gap instead. The default gap is
4 os-units between icons, but by using !space, you can have any gap. The
amount you specify is added to the default, so 4 would leave a gap of 8,
and -4 would leave no gap at all.

When experimenting with this, the commands "/load nickline", "/load chanline"
and "/load membline" should prove useful. Again, is it best to save your
modified files in !Boot.Choices, (which /save <list> will do for you), so they
won't get overwritten if you upgrade.


8. Lag Monitor
==============

Choosing "Lag..." in the terminal menu, or using the "/Show lag" command, will
open a small window containing a graph. This graph is the result of measuring
the lag to the server at regular intervals. You can set the period between
the checks in Choices. Usually, the lag should be under one second (the grey
line), but if it becomes longer for a while, it can be taken as an indication
that the server is overloaded and might split. This may be a good time to
change server if you can.

Don't set the period too low on real-world servers. These lag measurements
have high priority, and you can get kicked off for flooding if you issue
them too often. 5 seconds is probably a sensible minimum time.


9. Text Styles
==============

When someone says something on a public channel, you see:
<Nick> Hello

All the different things that might happen, have a certain way of being
printed, and a certain colour. All these definitions are called the current
'Style'. It is stored in the Style file. You can change style with the /style
command, and then use '/save style' when you're satisfied.

In order to change them, you must know how the styles are defined.
The lines in the Style file, and the arguments given to /style are exactly
the same.

Each line starts with a list of style types, or the word "default". If there
is a default entry, it must be the first line, because all style types are
changed when this is seen. This applies to the command as well.

The style types are given in hex. The first digit says something about where
the text will be printed:

0x	There's an exact window open for this Forum (see below)
1x	There is no exact window open, and the Forum is not a channel.
2x	There is no exact window open, and the Forum is a channel.

The last hex digit is the event type:

x0	PRIVMSG received
x1	PRIVMSG sent
x2	NOTICE received
x3	NOTICE sent
x4	Action received
x5	Action sent
x6	Child task input
x7	Script input
x8	Child task output
x9	Script output
xA	Commands sent
xB	Unknown data
xC	Internal text
xD	WAllOps
xE	Misc info about channel/nick
xF	Error

So, for example, changing the style type 22 would affect any public notice
received from a channel, for which you have no window open.

The 'Forum' means who or what the message is related to. It can be a nick,
channel, child name, script title, or many other things. The only important
thing here, is whether there's a window open with the Forum as a target.

The next word on the line is which colour the text should be. The names of
the colours are listed further below. Note that using mIRC colours here would
mean that bold text won't work.

Then follows the text format, given as a 'template string'. %0, %1 etc. are
used to insert the relevant words.

%0 will be the message forum (nick, channel, etc.)
%1 will be the source of the message (typically a nick, but in some cases it
   will be '' if there is no relevant source).
%2 will be the current time, using the format set in choices.

If there is another template after this, it controls what goes into the log
file. If not, it will be the same as the printed text.

Please note, that all the spaces in the default prefixes are hard-spaces
(ascii 160). This is to avoid the wordwrapping breaking the line between the
prefix and the first word, if the first 'word' is very long (i.e. beyond the
edge of the terminal window).
You will probably want to use hard spaces too (can be entered with Alt-Space),
unless this breaking effect is just what you're after.


10. Scripts
===========

Scripts are (usually small) programs, that enable you to do things that would
be impossible in macros or /exec files.

The script language is very much like Basic, with some added features. Some
knowledge of Basic will help a lot.

Scripts are stored in either Text or Basic files, anywhere. Often used scripts
should be placed in the Script directory, because then you can refer to them
by leafname instead of the full pathname.

This directory already contains some examples, referred to below.
I'd advice you to check out the scripts, even if they seem irrelevant to the
task at hand, as some of them contain comments and hints.

The scripts are executed from Choices:Scripts as first priority; put your
own scripts there so they don't get overwritten by new versions of the
default ones.

Basics
------

A simple script could just be a series of commands, see 'Ex1'.

There are a few things to note in this example:
1. The '/' before commands has a special function in scripts. It works like
   * in Basic, i.e. the rest of the line is a normal LIRC/IRC command. If you
   need to refer to variables in the command, you use the equivalent of
   Basic's "OSCLI", which is "DO".
2. The "SCRIPT" line must be present, it marks the end of the header, and
   the start of the program.
3. Parameters are available through the ARG$() and ARGS$() functions.

With this example, you would be able to use commands like:
/run ex1 orfey
/run ex1 orfey tightly
etc.


Aliases
-------

Even if you stored the above in a file called 'Hug', it would be nicer to
have a _real_ command called "/hug" instead. This is where aliases come into
the picture, and things get a bit more complicated. Consider 'Ex2'.

In this one, the following has changed:
1. Running the script does not actually send anything. But an alias will be
   defined.
2. The 'IDLE' command is very important. This stops execution of the script,
   but the script stays loaded. This lets you use the alias afterwards, which
   would otherwise have been thrown away with the rest of the script's data.
3. We now define variables for parameters instead of using ARG$(). This is to
   get the parameters given to the _alias_ (not to the script). If you had
   used ARG$() here, it would have used the parameters given in the /run
   command, like above. But that is not what we want in this case.

To use it, say "/run Ex2". Now you can use "/hug orfey" etc.
It might be nice to have certain aliases available without having to run
files first. For this purpose, there is a script called '!OnConnect'. It will
be run after connecting to the server.
In '!OnConnect', you could put either:
1. A command to /run your script defining the aliases.
2. The alias definitions themselves.

As all the other choices, it is best to store your own scripts in
Choices:IRC.LIRC.Script (create it if necessary), so they won't get
overwritten.


Parameter checking
------------------

Now what is wrong with the /hug command? You will see if you say "/hug".
The text becomes "* You spots  in the corner..." etc.

The solution is to check the supplied parameters, exactly like a built-in
command would have done. See 'Ex3'.

The effect should be pretty obvious. There are two things to note by now:
1. The titles of the last two scripts have been the same, and that is no
   coincidence. Scripts are _identified_ by their title, and it is used to
   kill them, for example. Also, when a script is started, any other script
   with the same title will be killed. This is why the examples are all
   called 'Example', otherwise you would end up with several of them running
   (but idle), even though the latest alias definition would override all the
   others as expected.
2. The first example didn't have a TITLE line, so it got its leafname as
   title instead.

Checking the parameters properly is of course important, if you're aliasing
an existing command. You could, for example make a 'join' alias, that would
both join a channel and open a window. Here it is important to remember that
join takes more than one parameter, if the channel is +k (needs a password).

If you need to use a standard command that has been aliased, the method is
the same as in Obey files: Prefix the command with %. This is very important
to remember when aliasing standard commands, because you could easily end
up with the alias calling itself indefinitly.
Don't make it do this, it's a mess (because the programs are parallel, they
don't wait for each other).


Using events
------------

So far, the examples have only been able to act on commands typed by you.
However, it is sometimes desirable to make them react on things happening on
IRC. To this end, you can use events.
There are several different types, see below for a complete list.

Events are used much like aliases. To receive a certain event, you simply
define the appropriate routine. 'Ex4' is an example.

This will simply display the arguments received, when a PubMsg event happens.
Replace 'PubMsg' with any other event type to see the arguments for that.
Note that most events do not give exactly 4 arguments. If they give less,
the remaining variables will be empty strings. If they give more, the last
variable will contain the rest, separated by spaces.
This applies, no matter how many variables you give in the EVENT definition.

Note that events, like IRC, are highly asynchronous. This means that you can't
expect events in any particular order, except of course that responses always
come _after_ the command that triggers them.

Also note that events are subject to filters like everything else. If all
messages from a certain source have been ignored, you won't get message
events either.


Event type	Arguments		Description

PrivMsg		Nick,Text		Happens when receiving a private
					message from somebody. Note this
					differs from the IRC 'PRIVMSG', which
					can be either private or public.
PubMsg		Channel,Nick,Text	This event is triggered when someone
					speaks in public on a channel you have
					joined.
PrivNotice	Nick,Text		As PrivMsg, when it's a notice.
PubNotice	Channel,Nick,Text	As PubMsg, when it's a notice.
PubCTCP		Channel,Nick,Type,Data	A CTCP to a channel.
PubCTCPRep	Channel,Nick,Type,Data	A CTCP reply to a channel, as above.
PrivCTCP	Nick,Type,Data		A CTCP to you.
PrivCTCPRep	Nick,Type,Data		A CTCP reply to you.
DCC		Type,Data		These happen while a DCC is in
					progress. See below for details.
Join		Channel,Nick,[F]	This happens when someone joins a
					channel. The F is present if the
					person is in your list of friends.
Topic		Channel,Nick,Text	Someone has changed topic on a channel
					you are on.
Leave		Channel,Nick,[Reason]	Someone left a channel you are on.
Kick		Channel,Nick1,Nick2,Reason
					Nick1 has kicked Nick2 off the Channel,
					giving the Reason supplied.
Quit		Forum,Nick,Reason	When someone you can see leaves IRC.
					Forum is either Nick, or a channel
					common to you and Nick.
Kill		Source,Forum,Nick,Reason
					Source has forcefully removed Nick
					from IRC, giving the Reason. Forum is
					either Nick, or the channel common to
					you both.
ChanMode	Channel,Nick,Change	Nick has changed a Channel's mode
					flags. The Change is e.g. "+i"
UserMode	Channel,Nick,Target,Change
					Nick has changed the mode for Target,
					related to Channel. This can be
					several different things, e.g. the
					Target could be another nick, and the
					change "+o", "+v" etc. Or the target
					could be a usermask and the change
					"+b".
Nick		Nick1,Nick2		Nick1 has changed name to Nick2.
Invite		Channel,Nick		Nick invites you to Channel.
Flood		Type,Host		Happens when Host flooded you enough
					to get auto-ignored.
WallOps		Source,Text		Message from Source to all IRCOps.
Response	Source,Type,Data	This is a general response to various
					commands. The Type says what it is,
					refer to rfc1459 for a list of types.
Error		Source,Type,Data	Same as Response, but these are
					errors (Type 400 and higher).
SentMsg		Target,Text		Happens when sending a private message
					to a channel or a nick.
SentNotice	Target,Text		As SentMsg, when it's a notice.
SentCTCP	Target,Type,Data	A CTCP from you.
SentCTCPRep	Target,Type,Data	A CTCP reply from you.
Watch		Type,Nick		When a nick that is being watched
					appears or leaves IRC. Type is either
					"here" or "gone".

The above are all related to events happening on IRC. Apart from these,
the are also some internal events:


Event type	Arguments	Description

User		Script,Data	This event is generated by the /UserEvent
				command, and can be used by scripts to send
				data to each other. Script is the sender, and
				Data is whatever you want it to be.
HotKey		Code,Index,Text	Happens when you press a key in the entry icon,
				which wouldn't otherwise do anything. The Code
				is the key code, and Index is the current caret
				position in the line. The Text is whatever is
				in the entry icon at the time. It is often used
				in combination with the /Entry command.
Enter		Text		Happens when you press Return in the entry
				icon. The default action is to execute Text as
				a command. Use this to e.g. grab the event and
				issue a different command given certain input
				lines.
Child		Name,Text	Happens when a child task has printed a line of
				text. The Name is the name given in the /task
				command, with a @ prefix.
SentChild	Name,Text	Happens when you send a message to a child.
Exit		Reason		This event happens just before the execution of
				the script stops. See below for details.
Input		Text		This happens when you 'talk' to the script, by
				using /msg $<name>, or having it selected as
				current target etc. It is up to you what Text
				is used for.
Title		Target		Happens when setting the title of a terminal
				window. You can grab this event and use
				/Set Title to set your own title.
BadTarget	Target,Operation,Arguments
				This happens when trying to e.g. talk to a
				target that has an illegal name. See below.
Open		Target		Happens when a new terminal window is created
				and opened.
Close		Target		Happens when a terminal window is closed.



Finally, you can get events when something happens in the wimp (like the ones
returned from a normal poll loop). They all supply a pointer to the normal
block returned from the wimp. The difference here is, that the single pointer
argument _must_ be supplied, even if it isn't used.

There is another difference. You can't use PRINT or similar VDU output while
inside these wimp events. Well, you can, but it will appear on the desktop,
not in the terminal window. Use DISPLAY instead.
It is futile to 'grab' wimp events, as you are the only one that sees them
anyway.


Event type	Description

W_Null		Null reason code
W_Redraw	Redraw window request
W_Open		Open window request
W_Close		Close window request
W_P_Leave	Pointer leaving window
W_P_Enter	Pointer entering window
W_Mouse		Mouse click
W_Drag		User drag box
W_Key		Key pressed
W_Menu		Menu selection
W_Scroll	Scroll request
W_C_Lose	Lose caret
W_C_Gain	Gain caret
W_PWord		Poll word non-zero
W_Msg		User message
W_MsgR		User message recorded
W_MsgA		User message acknowledge
W_Toolbox	Toolbox event

About HotKey
------------
If you are going to act on a keypress, you must _immediately_ use the
ACKKEY statement. It has to be before making commands etc. because otherwise
the key will be passed on to other scripts, and eventually to the wimp for
further processing. In that case you could get several things happening with
only one keypress.

About DCC
---------
There are 12 different types of these. They are all called DCC, but the Type
says what actually happened:

DCC,"rx_resume",From,Size,Pathname,Pos		If resuming from offset Pos
DCC,"rx_start", From,Size,Pathname		When reception starts
DCC,"rx_end",   From,Size,Pathname		When complete
DCC,"rx_abort", From,Size,Pathname		If aborted by you
DCC,"rx_lost",  From,Size,Pathname		If aborted by sender
DCC,"rx_error", From,Size,Pathname,Error	Any other error

DCC,"tx_resume",To,  Size,Pathname,Pos		If resuming from offset Pos
DCC,"tx_start", To,  Size,Pathname		When transmission starts
DCC,"tx_end",   To,  Size,Pathname		When complete
DCC,"tx_abort", To,  Size,Pathname		If aborted by you
DCC,"tx_lost",  To,  Size,Pathname		If aborted by receiver
DCC,"tx_error", To,  Size,Pathname,Error	Any other error

Note that in the case of reception, it is possible to receive a file of unknown
size. Size will be 0 in this case, and the transfer won't end with rx_end as
normal, it will be rx_lost when the sender closes the connection.

About Exit
----------
You can use this to release any system resources you might have claimed (such
as sockets). Be careful of generating errors in the exit routine, because if
you do, they will be reported by the wimp (in an error box), hence halting
the multitasking. Also, PRINT won't work, use DISPLAY instead.

Reason may be one of:
"End"		At normal END or QUIT statements.
"Wimp quit"	When a wimp quit message was received.
"Kill"		Because of the "/script kill" command.
"Restart"	A script started with the same title.
"LIRC"		Because the LIRC that started the script died.
<error message>	Anything else.

About BadTarget
---------------
When trying to do things like "/msg *bob hello", this event happens because
a nickname can't start with *. The event can then be used by scripts that
give a special meaning to targets like that. Grabbing the event means that
LIRC won't print '! Unknown target', and you can then take appropriate action
instead. The event supplies three arguments:
Target		Is the illegal target
Operation	Can be one of:
		"talk"		When the operation was /msg or similar.
		"note"		When it was /notice.
		"creq"		When it was a ctcp request, e.g. /ping
		"crep"		When it was a ctcp reply. This is not often
				encountered.
		"kill"		When the /kill command was used.
Arguments	Is whatever else was supplied, e.g. the text of the /msg.
		In case of creq and crep, the string does not contain the
		enclosing <1>'s.


Is this Basic or what?
----------------------

It is very close. You can do everything that would be possible in Basic, but
there are some further requirements. The header is one requirement, there
must be at least a 'SCRIPT' statement.
Furthermore, if you use the / statement, it must either be on a line of its
own, OR preceeded by a colon.

Be aware that the desktop will stall if you make a loop that takes a long time.
If you do need a long loop, put in NOP statements to allow the multitasking
to work.

There are certain identifiers you shouldn't use:

1. FNevent_*
2. FNalias_*
3. Any integer variable, string variable, PROC, or FN whose name is shorter
   than 4 characters and ends in '_'".

Defining any of these will probably mess up everything, so don't.

Otherwise you are safe. Be aware, that if you use EVAL on your own integer or
string variables, it won't work on names shorter than 3 characters. This is
because they are being renamed (to the above) in order to avoid clashing with
the library variables.

In fact, you can use A%..H%,L%,O%,P% safely, without them being renamed. This
is to enable the use of assembler. Also @% is preserved.


Case sensitivity
----------------

Which parts of scripts are case sensitive have not been told yet.
If you _assume_ case sensitivity in all parts, you can't go wrong. But of
course there are rules for it.
All keywords and variables, both Basic and script ones are case sensitive.
Event types, and alias names are case insensitive.
LIRC/IRC commands, whether written after / or using DO, are case insensitive.
The exception to this, is if the command would be tokenised, e.g. /CLS.
When using /, it is best to stick to mixed or lower case, if you do not know
for certain which keywords might get tokenised.


List of non-basic functions
---------------------------

Functions returning numerics:

ACCEPT(S%)	waits for a connection attempt on the listening socket S%.
		When one is received, it creates a socket and connects,
		returning the number of the connected socket.
C_ACT(C$)	returns the time when the channel C$ was last active.
C_SEEN(C$)	returns the time when the channel C$ was last seen.
CONNECT(H$,P%)	creates a socket and connects it to host H$, port P%. Returns
		the socket number (or generates an error).
EXIST(O$)	returns TRUE if the object (dir/file etc.) exists.
H_IGNORE(H$)	returns the filter type of hostmask H$. See F_TYPE$().
H_FRIEND(H$)	returns TRUE if the hostmask H$ is a friendly one.
HTON(A%)	converts between host and network byte order in an address.
ISALPHA(Code)	returns TRUE if the ascii code is an alphabetic character.
M_NAMES(C$)	returns the number of members on channel C$.
M_OF(C$,N$)	returns TRUE if nick N$ is a member of channel C$.
M_OP(C$,N$)	returns TRUE if nick N$ is an op in channel C$.
M_VOICE(C$,N$)	returns TRUE if nick N$ has a voice in channel C$.
N_SEEN(N$)	returns the time when the nick N$ was last seen.
N_ACT(N$)	returns the time when the nick N$ was last active.
N_AWAY(N$)	returns TRUE if the nick is marked "away". Note this is not
		always up to date, but you can make it pretty recent by
		triggering e.g. a /who just before checking this state.
NOW		returns the current monotonic time.
NTOH(A%)	equivalent to HTON(A%).
POLLWORD	returns a pointer to the pollword.
RESOLVE(H$)	returns the IP of host H$ (or an error).
SERVER(P%)	creates a listening socket on port P%. P% can be 0 to allocate
		a free port.
SPOS(A$,B$,P)	is like INSTR(A$,B$,P), but case-insensitive.
T_OPEN(T$)	returns TRUE if there is a window open for target T$.
WCMPS(S$,W$)	returns TRUE if S$ is a match of the wildcarded string W$.
WCMPI(S$,W$)	does the same, but is case-insensitive.
		Be aware that these two WCMP functions can require more stack
		space than immediately available if the strings are long. Use
		MEMORY to allocate more memory temporarily.

The functions returning a 'time', do so in relation to NOW. I.e. if you
want to know how many seconds have passed since 'Chocky' was seen, use:
(NOW-N_SEEN("chocky"))/100
They all return 0 if the nick/channel is unknown.

Functions returning strings:

ARG$(N)		returns argument number N+1, given to the /run command.
		In other words, ARG$(0) is the first.
ARGS$(N,M)	returns arguments N+1 through M+1. If M is -1, returns from N+1
		onwards until the last.
C_TOPIC$(C$)	returns the topic of channel C$, if known.
COL$(C$)	returns a suitable ctrl-sequence for selecting colour C$.
F_TYPE$(T)	converts a filter type into a string describing it.
FIRSTARG$(A$)	returns the first argument in a space-seperated string of
		arguments. Updates A$ to contain the rest (so it must be a
		variable, not a string expression).
LASTMSG$	returns the most recent person to send you a private message.
LEAF$(S$)	returns the leafname of the full pathname S$.
LOWER$(S$)	returns S$ in lowercase.
M_NAMES$(C$)	returns a space-seperated list of members on channel C$.
N_HOST$(N$)	returns the hostmask of nick N$, as "userid@host".
N_NAME$(N$)	returns the nick of nick N$. The point of that is, that it will
		return "" if the nick has not been seen. Also, N$ is case-
		insensitive, whereas the result has the correct case.
NICK$		returns your current nickname.
PATH$(S$)	returns the path part of the full pathname S$.
PROVIDER$(A$)	returns the name of the script currently providing the A$
		command (as an alias). Returns "" if it is unknown.
RXLINE$(S%)	loops until a line is received from socket S%. Generates an
		error if the connection is closed by the other end.
SOURCE$		returns the URL where the latest version is found.
T_OPEN$		returns a list of the targets that have a terminal window open.
TARGET$		returns the current target (nick/channel).
TITLE$		returns the title of this script (after expansion, if any).
THISFILE$	returns the full pathname of the script running.
UPPER$(S$)	returns S$ in uppercase.
VERSION$	returns the version of LIRC.

Use of colours
--------------

When printing text from scripts, you can change colour in 3 ways:
1. Using CHR$2 to select a bold version of the current colour.
2. Using CHR$3 to select a mIRC colour.
3. Using COL$("name") to select any colour.

The third way is of course the best. HOWEVER, if you are sending the text to
someone on IRC, you have to use the first or second method.

1. The bold colours work on the standard colours, not the mIRC ones. You
   simply toggle the effect with CHR$2, like this:
   PRINT "This is " CHR$2 "bold" CHR$2 ", and this is not"

2. The mIRC colours are 16 colours used by mIRC and some other clients. They
   are selected by a CHR$3+"nn", where NN is a number between 0 and 99 (they
   repeat after every 16). Example:
   PRINT "This is " CHR$3 "04red" CHR$3 "."
   Note that every other CHR$3 turns it off, like bold.

3. The COL$() function returns a colour change sequence given a named colour.
   This is much better, as the colour numbers may change but the names will
   not. Also, you can select any of the 40 colours this way. Example:
   PRINT "This word is " COL$("private") "private"
   
   The colour names are case-insensitive. This is the list:

   Background,Public,Private,Misc		These are the same as in the
   Selection,Internal,URL,Script		Colour menu. They refer to the
   Child,Command,Error,Unknown			type of text rather than the
   						colour.

   B_*						With a B_ prefix (e.g. B_Child)
   						you get the bold version of
   						that colour.

   M_White,M_Black,M_Blue,M_Green		All the mIRC colours. These
   M_Red,M_Brown,M_Magenta,M_Orange		names refer to the colour, and
   M_Yellow,M_Lime,M_Cyan,M_Aqua		there is no specific use for
   M_Royal,M_Purple,M_Grey,M_Silver		them.

You may discover that COLOUR <n> also changes colour. However, this method is
not recommendable, since the colour numbers may change.


List of non-basic keywords
--------------------------

ACKKEY
Acknowledges that you have dealt with the HotKey event. Stops the event from
being sent to any other scripts, and stops LIRC from eventually sending it
to other hotkey applications. GRABEVENT can also be used, and does the same.

AUTHOR author
Defines the author of the script. This is only valid in the header (i.e. before
SCRIPT). The author is a literal string of characters, and if it contains
spaces, it must be enclosed in quotes. It is only used for reporting in a
status report.

BOO
Breaks out of SLEEP state prematurely.

DEFALIAS(command,arg1$,arg2$,...,argN$)
Defines an alias routine. The command argument is not an expression, it is
a literal string of characters (not enclosed in double quotes).

DO string
Sends the string expression to LIRC, as if it was typed into the entry icon.

END, QUIT
Terminates the script normally.

ENDALIAS
Terminates the ALIAS routine.

ENDEVENT
Terminates the EVENT routine.

DEFEVENT(type,arg1$,arg2$,...,argN$)
Defines an event routine. Like alias, "type" is a literal string, not a
variable or expression. arg1$ etc. is however many arguments you want to
access using the given string variables. They will be local to the event
routine in question, so you can use the same variables, even if another event
occurs while inside the routine.

DEFEVENT(type,block%)
Same as above, except for the wimp events (which give a pointer to the event
block instead of strings).

DISPLAY string
Prints the string in the terminal window, like PRINT would. But this command
can be used in wimp event routines, and it is a more immediate form of
printing.

GRABEVENT
Claims an event in an event routine. This will stop other scripts getting the
event, and stop LIRC from performing the fallback action. The wimp events are
'grabbed' by default, i.e. there is no fallback action if you have defined a
routine in the script.

IDLE
Puts the program in an endless multitasking loop. From there on, only alias
and event routines will be executed. This should only be used in the main
part of the program, unless you want the stack to continually grow.

KILL number
Closes the socket <number>. You don't usually need to do this, as all sockets
created will be removed when the script dies.

MEMORY kilobytes
1. When used in the header:
   Sets the amount of memory the script gets for extra workspace. On top of
   this, memory will be added for the actual program, plus control routines.
2. When used inside the script:
   Extends your workspace (temporarily) by the given amount.
If you allocate too much, it will be released as soon as you start multi-
tasking, so if you need it, you must make use of it.
If you need less than 2K between each poll, you can just DIM what you need,
and the wimpslot will extend when necessary.

NOP
Lets other programs run for a while. This command is needed if you take a
long time doing something, which would otherwise stall the desktop until
completed.

OUTPUT number
This changes what kind of event the script output (from PRINT and DISPLAY)
will be. The event types are listed above in the Style section. Apart from
these, there is a special one which is 64. This type is a "raw" kind of
printing, with no prefixes and no style entry.
The default event type is 9, i.e. 'Script output'.

SCRIPT
Divides the header from the main program. Execution starts after this command.

SLEEP number
Like IDLE, it loops around doing nothing but aliases and events. But it
only does this for the specified number of centiseconds, then normal
execution resumes.
Note that if you use this statement in an event or alias routine, you should
make sure the routine is re-entrant.

STOP
Terminates the program with the error "Stopped".

TITLE string
Defines the title of the script. This is only valid in the header (i.e. before
SCRIPT). The title is a literal string of characters, not an expression. If it
contains % it must be enclosed in quotes. Spaces in the title are not allowed.
%0, %1 etc. can be used, and will make the title depend on the command
arguments given to the /run command. This allows several instances of the same
script.

TXLINE number,string
Sends string to the socket <number>. It will be sent as a line, i.e. with CRLF
on the end.

USEREVENT string
Generates a user event, with the given string expression as data.


List of Basic keywords, that are special
----------------------------------------

As a general rule, you can use any Basic function, including assembler etc.
But there are some operations that might give unexpected results, mostly
because you are writing a multitasking program. If you are used to this,
you shouldn't find anything really unexpected in the following list:

CIRCLE,CLG,DRAW,ELLIPSE,FILL,GCOL,LINE,MOVE,ORIGIN,PLOT,POINT,RECTANGLE,TINT:
Plotting graphics directly will most probably mess up the desktop.

COUNT,POS,VPOS,WIDTH:
Doesn't return anything meaningful.

*,OSCLI:
You can use CLI commands, but don't run anything that might be loaded on top
of the current application. If you need to run programs, use *WimpTask.
* must be on its own line, or be preceeded by a colon.

GET,GET$,INKEY,INKEY$,INPUT,INPUTLINE,LINEINPUT:
These work, but are unsuitable for wimp programs. They stop multitasking
while waiting for input.

HIMEM=,END=,LOMEM=,PAGE=:
Use MEMORY instead of END= and HIMEM=.
LOMEM= and PAGE= are not relevant in scripts.

INSTALL,LIBRARY,OVERLAY:
Will work, but you may need to make sure you have space for it. Use MEMORY
to allocate more memory.

MOUSE:
Is not nice in the wimp, as it removes an entry from the mouse buffer,
causing clicks to be missed. Use Wimp_GetPointerInfo instead, if you must.
Don't use MOUSE TO at all.

ON ERROR:
You can use error handlers, but keep to local ones. Always call the default
error handler if the program is going to exit because of the error.

TIME=:
You can read TIME, but don't assign a value to it.


11. Children
============

You can start child tasks with the /task command. These will be run by
TaskWindow, and any output will be displayed in a special style for this
purpose. There is also a Child-event, which happens when this text is output.
Using this, it is possible to make scripts that control the children they start
themselves, but with LIRC as the taskwindow parent.
Using the SendChild event you can get at the input send to the child, and
have it displayed in a different way perhaps.

Use the flush-time to deal with tasks that display input prompts. It can be
set to 0, but then there is a danger of breaking up the lines, which would
make it harder to deal with the output-events. Setting flush_time to X, will
_guarantee_ silence from the task for X seconds before the event happens, and
that is the most useful option.


12. DCC, masquerading, firewalls, etc.
======================================

Sending a file with DCC requires the receiver to connect to your computer.
This is exactly what firewalls are in place to prevent, so most times it
won't work. It can be fixed in most cases, though.

If you have a firewall, you will need to make a hole in it to allow incoming
connections on a port you decide on yourself. Consult your firewall
documentation to find out how to make that hole. After this, use that port
number as "Fixed port" in Choices, and that should be enough.
Alternatively, you may be able to use a port that is already open, as mentioned
above under "Fixed port".

If you use masquerading instead/as well, it gets more complicated. Here you
have 2 possibilities:

A. Setting a fixed rule to use for DCC.
B. Letting the masquerader set up rules by itself as needed.

A. is the approach most likely to work. You set up a rule on a port you have
decided on, to forward all traffic on that port to the machine that runs the
IRC client. Then you set that as "Fixed port" in the client.

B. requires that the masquerader "understands" the IRC and DCC protocols, and
is capable if spotting DCC requests. It then sets up a temporary rule by
itself, and changes the DCC request to reflect the real outside address.
For this to work, the IRC client must appear to know nothing about the ouside
world, so you need to use "Fixed host", and set it to your LAN address.
Fixed port is left blank. The masquerader should then replace this with the
values that can be reached from outside.
There are many reasons why this may fail to work, in particular it is very
complicated to accurately identify and modify a DCC request when you only have
the raw packets (which might not contain the complete line). The linux module
for this (ip_masq_irc.o) has gotten better, but there are still many possible
ways for it to fail. Therefore it is better to use solution A above if you have
any choice. Be aware that by default, ip_masq_irc.o only looks for DCC attempts
on connections to port 6667. If you are using a different port on the server
(very likely these days), you will need to extend the list of ports to include
it. This can be done with a command similar to:
modprobe ip_masq_irc ports=6665,6666,6668,6669


13. The rest
============

A lot of additional information is accessible from the command line. Use
/? <command> to get information about specific commands, or /? on its own for
a list.


14. Credits
===========

Thanks are due to:

Gerph    - for good ideas, countless protocols, and support programs.

abca     - for extensive testing and putting up with it.
           And the voice buttons :-)

Chocky   - for extensive testing and a long list of suggestions.

technium - lots of good suggestions, and script testing.

crispE   - for a better icon sprite...

rjw      - for virtually _all_ the sprites in use now :-)

N        - more suggestions...

daco     - more suggestions...

unCiscy  - advanced (and pretty weird) scripts...

Xen0     - bug reports and weird patches...

Spanners - for !SocketMgr

chasm    - for giving a new meaning to the word "face".

chod     - for spotting a missing letter, and then not being able to say where.
           :-)

And the rest of you, you know who you are.


15. Licence
===========

This program is PD, and there is of course no guarantee.

You may use this privately as much as you like, and give it away if you want.
But it may not be supplied as (part of) any commercial product without getting
my permission.

14 Dec 2000
Thomas Olsson
lirc@armware.dk

New versions can be found at:
http://www.armware.dk/files/

