            ╭──────────────────────────────────────────────────────────────────────╮
            │                                 Home                                 │
            ╰──────────────────────────────────────────────────────────────────────╯

             INDEX             GREETING          MSDP              STATEMENTS
             INTRODUCTION      KEYPAD            MSLP              SUBSTITUTIONS
             CHARACTERS        LISTS             PCRE              SUSPEND
             COLORS            MAPPING           REPEAT            TIME
             COORDINATES       MATHEMATICS       SCREEN READER     TRIGGERS
             EDITING           METRIC SYSTEM     SESSIONNAME
             ESCAPE CODES      MOUSE             SPEEDWALK

             INDEX

                       ████████┐██████┐███┐   ██┐████████┐██████┐███┐   ██┐
                       └──██┌──┘└─██┌─┘████┐  ██│└──██┌──┘└─██┌─┘████┐  ██│
                          ██│     ██│  ██┌██┐ ██│   ██│     ██│  ██┌██┐ ██│
                          ██│     ██│  ██│└██┐██│   ██│     ██│  ██│└██┐██│
                          ██│   ██████┐██│ └████│   ██│   ██████┐██│ └████│
                          └─┘   └─────┘└─┘  └───┘   └─┘   └─────┘└─┘  └───┘
                                           ██┐      ██┐
                                           ██│      ██│
                                        ████████┐████████┐
                                        └──██┌──┘└──██┌──┘
                                           ██│      ██│
                                           └─┘      └─┘

                           (T)he K(I)cki(N) (T)ickin D(I)kumud Clie(N)t

             What is TinTin++?

             TinTin++ is a client program specialized to help playing muds. This is
             a souped up version of TINTIN III with many new features.

             Giving Credit Where Credit is Due

             None of this work would be possible, without the work done by Peter
             Unold. He was the author of TINTIN III, the base of TinTin++. Hats off
             to ya Peter. You started the ball rolling.

             Introduction

             If you're new to TinTin++ a good place to start is the introduction,
             which should be linked below.

    Related: introduction

             INTRODUCTION

             On this page you'll find an introduction to using TinTin++. Additional
             information can be found in the individual help sections.

             Starting and Ending

             The syntax for starting TinTin++ is: ./tt++ [command file]

             Read more about the command file in the files section below. Remember
             one thing though. All actions, aliases, substitutions, etc, defined
             when starting up TinTin++ are inherited by all sessions.

             If you want to exit TinTin++ type '#end' or press ctrl-d on an empty
             line.

             For the WinTin++ users, if you want to paste text use shift-insert,
             text is automatically copied upon selection. This is typical Linux
             behavior, but it can take some getting used to.

             Basic features

             I'll start by explaining some of the very basic and important features:

             All TinTin++ commands starts with a '#'.

    Example: #help -- #help is a client command, and isn't sent to the server.

             All TinTin++ commands can be abbreviated when typed.

             #he -- Typing #he is the same as typing #help though it's suggested to
             use at least 3 letter abbreviations just in case another command is
             added that starts with 'he'.

             All commands can be separated with a ';'.

             n;l dragon;s;say Dan Dare is back! -- do these 4 commands
             There are 3 ways ';'s can be overruled.

             \say Hello ;) -- Lines starting with a '\' aren't parsed by TinTin++.
             say Hello \;) -- The escape character can escape 1 letter.
             #config verbatim on -- Everything is sent as is except '#' commands.

             Connecting to a server

    Command: #session {session name} {server address} {port}

    Example: #session someone tintin.sourceforge.net 4321

             You can have more than one session, in which case you can switch
             between sessions typing #<session name>.

             You can get a list of all sessions by typing: #session. The current
             active session is marked with (active). Snooped sessions with
             (snooped). MCCP sessions (compression) with (mccp 2) and (mccp 3).

             Split

    Command: #split

             The split command will create a separated input and output area.

             Using the #prompt command you can capture the prompt and place it on
             the split line. To get rid of the split interface you can use #unsplit
             which will restore the terminal settings to default.

             Alias

    Command: #alias {name} {commands}

             The syntax of the #alias command is almost like alias in csh.
             Use this command to define aliases. The variables %0, %1.. %9 contain
             the arguments to the aliased command as follows:
             the %0 variable contains all the arguments.
             the %1 variable contains the 1st argument
             ....
             the %9 variable contains the 9th argument

    Example: #alias greet say Greetings, most honorable %1

             If you want an alias to execute more commands, you must use braces.

    Example: #alias ws {wake;stand}

             To delete an alias use the #unalias command.

             WARNING! TinTin++ doesn't baby sit, and hence does not check for
             recursive aliases! You can avoid recursion by escaping the entire
             line.

    Example: #alias put \put %1 in %2

             Or by using the send command.

    Example: #alias put #send put %1 in %2

             Action

    Command: #action {action-text} {commands}

             Use this command to define an action to take place when a particular
             text appears on your screen. There are 99 variables you can use as
             wildcards in the action-text.

             These variables are %1, %2, %3 .... %9, %10, %11 ... %97, %98, %99.

    Example: #action {You are hungry} {get bread bag;eat bread}

    Example: #action {%1 has arrived.} shake %1 -- shake hands with people arriving.

    Example: #action {%1 tells you '%2'}
                       {tell bob %1 told me '%2'} -- forward tells.

    Example: #action {tells you} #bell -- beep on tell.

             You can have TinTin++ ignore actions if you type '#ignore actions on'.

             You can see what commands TinTin++ executes when an action triggers
             by typing '#debug actions on'.

             You can remove actions with the #unaction command.

             Command files

             When you order TinTin++ to read a command file, it parses all the text
             in the file. You can use command files to keep aliases/actions in,
             login to a server (name, password etc..) and basically all kinds of
             commands.

             You can make the command files with either a text editor (suggested),
             or use the #write command to write out a file.

             Commands for files:

             #read filename -- read and execute the file.

             #write filename -- write all actions/aliases/substitutes/etc known for
             the current session to a file.

    Example:
             #session x mymud.com 1234
             myname
             mypassword
             #split
             #action {^You are hungry.} {eat bread}

             If you save the above five lines to a file named 'mymud.tin' you can
             use 'tt++ mymud.tin' to start tintin and execute the file, connecting
             you to your mud, logging in, enabling split mode, and setting an action
             to eat a bread whenever you go hungry.

             Highlight

    Command: #highlight {text} {color}

             This command works a bit like #action. The purpose of this command is
             to substitute text from the server with color you provide. This command
             is a simplified version of the #substitute command.

    Example: #high {Snowy} {light yellow}

    Example: #high {%*Snowy%*} {light yellow}

             Use #unhigh to delete highlights.

             Speedwalk

             If you type a command consisting ONLY of letters and numbers n, e, s,
             w, u, d - then this command can be interpreted as a serie of movement
             commands.

    Example: ssw2n -- go south, south, west, north, north

             If you have problems with typing some commands that actually ONLY
             consists of these letters, then type them in CAPS. For example when
             checking the NEWS or when asked to enter NEW as your name.

             You must enable speedwalking with: #config speedwalk on.

             Ticker

    Command: #ticker {name} {commands} {seconds}

             The name can be whatever you want it to be, and is only required for
             the unticker command. The commands will be executed every x amount of
             seconds, which is specified in the interval part.

    Example: #tick {tick} {#delay 50 #show 10 SECONDS TO TICK!;#show TICK!!!} {60}

             This creates a ticker with the name {tick} which will print TICK!!!,
             as well as print a warning when the next tick will occure.

             You can remove tickers with #untick

             Repeating Commands

             You can repeat a command, the syntax is: #number command

    Example: #5 cackle -- if you just killed bob the wizard.
    Example: #10 {buy bread;put bread bag} -- repeat these 2 commands 10 times.
    Example: #100 ooc w00t w00t!!!!! -- nochannel yourself.

             History

             TinTin++ has a limited subset of the csh history features.

             ! -- repeat the last command
             !cast -- repeat the last command starting with cast
             ctrl-r -- enter the reverse history search mode.

             Map commands

             TinTin++ has a powerful highly configurable automapper. Whenever
             you type n/ne/e/se/s/sw/w/nw/n/u/d tt++ tries to keep track of your
             movement.

             Commands for map:

             #map create -- create a map.
             #map goto 1 -- go to the first room in the map, created by default.
             #map map -- display the map.
             #map undo -- undo your last map alteration.
             #map write <filename> -- save the map to file.
             #map read <filename> -- load a map from file.

             There are many other map options and it's beyond the scope of this
             help section to explain everything there is to know, but I'll give
             a set of commands that will get most people started.

             #map create
             #split 12 1
             #map flag unicode on
             #map flag vt on
             #map goto 1

             These commands will create a 12 row vt100 split section at the top of
             your screen where a map drawn using unicode characters is displayed.

    Example: #action {There is no exit in that direction.} {#map undo}

             The map will be automatically created as you move around.

             Help

    Command: #help {subject}

             The help command is your friend and contains the same helpfiles
             inside TinTin++ as are available on the website. If you type #help
             without an argument you will see the various available help subjects
             which try to explain the TinTin++ commands and features in greater
             detail. Entries in cyan describe commands, while entries in white
             describe various features, often in greater detail.

             That's all for the introduction, enjoy

    Related: characters, colors, coordinates, editing, escape_codes, greeting, keypad, lists, mapping, mathematics, screen_reader, sessionname, speedwalk, statements, suspend and time.

             CHARACTERS

             The following special characters are defined:

    #        The hashtag is the default character for starting a command and is
             subsequently known as the command character or tintin character.
             When loading a command file the command character is set to the
             first character in the file. The character can also be redefined
             using #config.

    ;        The semi-colon is used as the command separator and can be used to
             separate two commands. Multiple commands can be strung together as
             well. Trailing semi-colons are ignored when reading a script file
             as this is a common error.

    { }      Curly brackets aka braces are used for separating multi word command
             arguments, nesting commands, and nesting variables. Braces cannot
             easily be escaped and must always be used in pairs.

    " "      Quote characters are used for strings in the #math, #if, #switch,
             and #case commands. It is however suggested to use a set of braces
             { } to define strings instead, particularly when checking strings
             that may contain quotes.

    !        The exclamation sign is used to repeat commands, see #help history.
             The character can be redefined using #config.

    \        An input line starting with a backslash is sent verbatim if you are
             connected to a server. This character can be configured with
             #config, and is itself sent verbatim when the verbatim config mode
             is enabled.

    Related: colors, escape_codes, function, mathematics, pcre and variable.

             COLORS

    Syntax:  <xyz>  with x, y, z being parameters

             Parameter 'x': VT100 code

             0 - Reset all colors and codes to default
             1 - Bold
             2 - Dim
             3 - Italic
             4 - Underscore
             5 - Blink
             7 - Reverse
             8 - Skip (use previous code)

             Parameter 'y':  Foreground color
             Parameter 'z':  Background color

             0 - Black                5 - Magenta
             1 - Red                  6 - Cyan
             2 - Green                7 - White
             3 - Yellow               8 - Skip
             4 - Blue                 9 - Default

    Example: #show <125>Bold green on a magenta background.

             For xterm 256 colors support use <aaa> to <fff> for RGB foreground
             colors and <AAA> to <FFF> for RGB background colors. For the grayscale
             foreground colors use <g00> to <g23>, for grayscale background colors
             use <G00> to <G23>.

             The tertiary colors are as follows:

             <acf> - Azure            <afc> - Jade
             <caf> - Violet           <cfa> - Lime
             <fac> - Pink             <fca> - Orange

    Example: #show <acf>Azure    <afc>Jade     <caf>Violet
    Example: #show <cfa>Lime     <fac>Pink     <fca>Orange

             For 12 bit truecolor use <F000> to <FFFF> for foreground colors and
             <B000> to <BFFF> for background colors.

             For 24 bit truecolor use <F000000> to <FFFFFFF> for foreground
             colors and <B000000> to <BFFFFFF> for background colors.

             If the color code exceeds your configured color mode it will be
             downgraded to the closest match.

    Related: characters, coordinates, escape_codes, mathematics and pcre.

             COORDINATES

             When the 0,0 coordinate is in the upper left corner TinTin++ uses
             a y,x / row,col notation, starting at 1,1. Subsequently -1,-1
             will indicate the bottom right corner. This type of argument is
             used by the #showme command.

             When the 0,0 coordinate is in the bottom left corner tintin uses
             a standard x,y notation. This type of argument is used by the
             #map jump command.

             The vast majority of tintin commands use y,x / row,col notation,
             primarily because that is the notation used by the VT100 standard
             used for terminal emulation.

             Squares

             A square argument takes 2 coordinates. The first coordinate defines
             the upper left corner, the last coordinate defines the bottom
             right corner. The upper left corner of the terminal is defined as
             1,1 and the bottom right corner as -1,-1. This type of argument is
             used by #draw, #button and #map offset.

             Panes

             A pane argument takes 4 size values, which are: top pane, bottom
             pane, left pane, right pane. When a negative value is provided the
             size is the maximum size, minus the value. This type of argument
             is used by the #split command.

             Ranges

             A range argument takes 2 values known as the upper bound and lower
             bound. The upper bound (first value) defines the start of the
             range, the lower bound (second value) the end. The first index of
             a range is defined as 1. When a negative value is provides the last
             index is defined as -1. This type of argument is used by #buffer
             and #variable.

    Related: characters, colors, escape_codes, mathematics and pcre.

             EDITING

    ┌─────────────────────────┐┌────────────────────────────────────────────┐
    │alt b                    ││cursor backward word                        │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │alt f                    ││cursor forward word                         │
    └─────────────────────────┘└────────────────────────────────────────────┘
    ┌─────────────────────────┐┌────────────────────────────────────────────┐
    │ctrl a                   ││cursor home                                 │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl b                   ││cursor backward                             │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl c                   ││clear line                                  │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl d                   ││delete or exit                              │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl e                   ││cursor end                                  │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl f                   ││cursor forward                              │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl g                   ││                                            │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl h                   ││backspace                                   │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl i                   ││tab                                         │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl j                   ││enter                                       │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl k                   ││clear line right                            │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl l                   ││redraw input                                │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl m                   ││enter                                       │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl n                   ││input history next                          │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl o                   ││                                            │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl p                   ││input history prev                          │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl q                   ││                                            │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl r                   ││input history search                        │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl s                   ││                                            │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl t                   ││scroll buffer lock                          │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl u                   ││clear line left                             │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl v                   ││convert meta characters                     │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl w                   ││delete word left                            │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl x                   ││                                            │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl y                   ││paste                                       │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl z                   ││suspend                                     │
    └─────────────────────────┘└────────────────────────────────────────────┘
    ┌─────────────────────────┐┌────────────────────────────────────────────┐
    │arrow left               ││cursor left                                 │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │arrow right              ││cursor right                                │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │arrow up                 ││previous input line                         │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │arrow down               ││next input line                             │
    └─────────────────────────┘└────────────────────────────────────────────┘
    ┌─────────────────────────┐┌────────────────────────────────────────────┐
    │ctrl arrow left          ││cursor left word                            │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl arrow right         ││cursor right word                           │
    └─────────────────────────┘└────────────────────────────────────────────┘
    ┌─────────────────────────┐┌────────────────────────────────────────────┐
    │backspace                ││backspace                                   │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │alt backspace            ││clear line left                             │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl backspace           ││clear line                                  │
    └─────────────────────────┘└────────────────────────────────────────────┘
    ┌─────────────────────────┐┌────────────────────────────────────────────┐
    │delete                   ││delete                                      │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl delete              ││delete word right                           │
    └─────────────────────────┘└────────────────────────────────────────────┘
    ┌─────────────────────────┐┌────────────────────────────────────────────┐
    │end                      ││cursor end                                  │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl end                 ││scroll buffer end                           │
    └─────────────────────────┘└────────────────────────────────────────────┘
    ┌─────────────────────────┐┌────────────────────────────────────────────┐
    │enter                    ││enter                                       │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │shift-enter              ││soft enter                                  │
    └─────────────────────────┘└────────────────────────────────────────────┘
    ┌─────────────────────────┐┌────────────────────────────────────────────┐
    │home                     ││cursor home                                 │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │ctrl home                ││scroll buffer home                          │
    └─────────────────────────┘└────────────────────────────────────────────┘
    ┌─────────────────────────┐┌────────────────────────────────────────────┐
    │page up                  ││scroll buffer up                            │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │page down                ││scroll buffer down                          │
    └─────────────────────────┘└────────────────────────────────────────────┘
    ┌─────────────────────────┐┌────────────────────────────────────────────┐
    │tab                      ││complete word forward                       │
    ├─────────────────────────┤├────────────────────────────────────────────┤
    │shift-tab                ││complete word backward                      │
    └─────────────────────────┘└────────────────────────────────────────────┘

    Related: cursor, edit and macro.

             ESCAPE CODES

             You may use the escape character \ for various special characters.

             \a    beep the terminal.
             \c    send a control character, \ca for ctrl-a.
             \e    start an escape sequence.
             \f    send a form feed.
             \n    send a line feed.
             \r    send a carriage return.
             \t    send a horizontal tab.
             \x    print an 8 bit character using hexadecimal, \xFF for example.
             \x7B  send the '{' character.
             \x7D  send the '}' character.
             \u    print a 16 bit unicode character, \uFFFD for example.
             \u{}  print a 8-21 bit unicode character, \u{2AF21} for example.
             \U    print a 21 bit unicode character, \U02AF21 for example.
             \v    send a vertical tab

             Ending a line with \ will stop tintin from appending a line feed.
             To escape arguments in an alias or action use %%0 %%1 %%2 etc.

    Related: characters, colors, coordinates, mathematics and pcre.

             GREETING

          ####################################################################
          #                                                                  #
          #                    T I N T I N + +   2.02.42                     #
          #                                                                  #
          #      Code by Peter Unold, Bill Reis, and Igor van den Hoven      #
          #                                                                  #
          ####################################################################

             KEYPAD

             When TinTin++ starts up it sends \e= to the terminal to enable the
             terminal's application keypad mode, which can be disabled using #show {\e>}

          Configuration A           Configuration B           Configuration C
     ╭─────┬─────┬─────┬─────╮ ╭─────┬─────┬─────┬─────╮ ╭─────┬─────┬─────┬─────╮
     │num  │/    │*    │-    │ │num  │/    │*    │-    │ │Num  │nkp/ │nkp* │nkp- │
     ├─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┤
     │7    │8    │9    │+    │ │Home │Up   │PgUp │+    │ │nkp7 │nkp8 │nkp9 │nkp+ │
     ├─────┼─────┼─────┤     │ ├─────┼─────┼─────┤     │ ├─────┼─────┼─────┤     │
     │4    │5    │6    │     │ │Left │Cntr │Right│     │ │nkp4 │nkp5 │nkp6 │     │
     ├─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┤ ├─────┼─────┼─────┼─────┤
     │1    │2    │3    │Enter│ │End  │Down │PgDn │Enter│ │nkp1 │nkp2 │nkp3 │nkpEn│
     ├─────┴─────┼─────┤     │ ├─────┴─────┼─────┤     │ ├─────┴─────┼─────┤     │
     │0          │.    │     │ │Ins        │Del  │     │ │nkp0       │nkp. │     │
     ╰───────────┴─────┴─────╯ ╰───────────┴─────┴─────╯ ╰───────────┴─────┴─────╯

             With keypad mode disabled numlock on will give you configuration A,
             and numlock off will give you configuration B. With keypad mode
             enabled you'll get configuration C.

             Terminals that support keypad mode

             Linux Console, PuTTY, MinTTY, Eterm, aterm.

             Terminals that do not support keypad mode

             RXVT on Cygwin, Windows Console, Gnome Terminal, Konsole.

             Peculiar Terminals

             RXVT requires turning off numlock to enable configuration C.

             Xterm may require disabling Alt/NumLock Modifiers (num-lock) in the
             ctrl left-click menu. Or edit ~/.Xresources and add
             XTerm*VT100.numLock:false

             Mac OS X Terminal requires enabling 'strict vt100 keypad behavior' in
             Terminal -> Window Settings -> Emulation.

    Related: colors, coordinates, escape_codes, mathematics and pcre.

             LISTS

             There are several different types of lists in tintin which behave in a
             fairly universal manner. To properly explain lists it's easiest to
             explain the most basic variable type first before discussing more
             complex types.

           - Basic variable: The standard key = value variable.

           - Simple list: A string that contains semicolon delimited fields.
             {a;b;c}. Can be saved as a variable.

           - Brace list: A string in which fields are delimited with braces.
             {a}{b}{c}. Brace lists cannot be stored as a variable because tables
             use braces as well, they must be stored as a simple list instead.

           - Table: Think of this as variables nested within another variable. Or
              as variables contained within another variable.

           - List: A table that uses integers for its indexes. Also known as an
             array. The #list command is a utility command for using tables as
             arrays.

             Simple Variables

    Example:
             #variable {simple} {Hello World!}
             #show $simple

             To see if the 'simple' variable exists you can use &{simple} which
             will display 0 if the variable does not exist, or the variable's index
             if it exists.

             If you have multiple variables they are sorted alphabetically and
             numerically. While it's not all that relevant for simple variables,
             the first variable has index 1, the second variable index 2, and so
             on.

             Variable names need to start with a letter and only exist of letters,
             numbers, and underscores. If you need to use a non standard variable
             name this is possible using braces.

    Example: #variable {:)} {Happy Happy!};#show ${:)}

             Variables can be accessed using their index. While primarily useful
             for tables it is possible to do this for simple variables. Use +1 for
             the first variable, +2 for the second variable, etc. Use -1 for the
             last variable, -2 for the second last variable, etc.

    Example: #show The first variable is: *{+1} with value: ${+1}

             Removing Variables

             To remove a variable, use #unvariable or #unvar (every command can be
             abbreviated). It's possible to remove multiple variables at once
             using #unvar {var 1} {var 2} {etc}

             Variables are unique to each session, so if you have multiple
             sessions, removing a variable from one session won't remove it from
             other sessions.

             If you remove a table variable, all variables contained within that
             table variable are removed as well.

             Simple Lists

             A simple list is a string that contains semicolon delimited fields.
             Commands can be entered as simple lists, for example:
             #show {a};#show {b} will execute a single line as two commands.

             Several commands take a simple list as their input, these are:
             #foreach, #line substitute, #path load, #list create, and #highlight.

             Brace Lists

             A brace list is a string in which fields are delimited with braces.
             Most commands take a brace list for their arguments, for example:
             #session {x} {mud.com} {1234} {mud.tin}. The session command takes
             4 arguments, the 4th argument (command file) is optional.

             Commands that take a simple list as their input will also accept a
             brace list, keep in mind you'll have to embed the brace list in an
             extra set of braces, for example: #path load {{n}{s}{w}{w}}, which is
             identical to: #path load {n;s;w;w}.

             Brace lists cannot be stored as variables because TinTin++ will
             confuse them with tables. You can convert a brace list to a table
             variable using: #list {bracelist} {create} {{a}{b}{c}} this will look
             internally as: {{1}{a}{2}{b}{3}{c}}. You can then convert this table
             back to a simple list using: #list {bracelist} {simplify} which will
             change it to {a;b;c}.

             Braces cannot easily be escaped in TinTin++. Using \{ or \} will not
             work. The reason for this is due to several factors, but primarily
             backward compatibility. To escape braces you must define them using
             hexadecimal notation using \x7B and \x7D. See #help escape for a list
             of escape options, and the help file will also remind you of how to
             escape braces.

             Tables

             Tables are key/value pairs stored within a variable. Tables are also
             known as associative arrays, dictionaries, maps, nested variables,
             structures, and probably a couple of other names. There are several
             ways to create and access tables.

    Example: #variable {friendlist} {{bob}{bob@mail.com} {bubba}{sunset@gmail.com}}

             This will create a friendlist with two entries, the key is the name of
             the friend, the value is the email address of the friend. You can see
             the email address of bob using: #show {$friendlist[bob]}. You can
             also define this table as following:

    Example:
             #variable {friendlist[bob]} {bob@mail.com}
             #variable {friendlist[bubba]} {sunset@gmail.com}

             This would create the exact same table as the single line declaration
             used previously. To see the first key in the table use:
             *friendlist[+1], to see the first value in the table use:
             $friendlist[+1]. To see the size of the table use &friendlist[]. To
             print a bracelist of all friends use *friendlist[], to print a
             bracelist of all friends whose name starts with the letter 'a' you
             would use: *friendlist[a%*]. Similarly to see the number of friends
             you have whose name ends with the letter 'b' you would use:
             &friendlist[%*b].

             See #help regexp for a brief overview of regular expression options.
             While TinTin++ supports PCRE (perl-compatible regular expressions), it
             embeds them within its own regular expression syntax that is simpler
             and less invasive, while still allowing the full power of PCRE for
             those who need it.

    Example: #unvariable {friendlist[bubba]}

             This would remove {bubba} from the friendlist. To remove the entire
             friendlist you would use: #unvariable {friendlist}.

    Example: #variable {friendlist} {{bob} {{email}{bob@ma.il} {phone}{123456789}}}

             There is no limit to the number of nests, simply add more braces. To
             see Bob's email in this example you would use:
             #show {$friendlist[bob][email]}.

             To merge two tables the #cat command can be used.
    Example:
             #variable {bli} {{a}{1}{b}{2}}
             #variable {blo} {{c}{3}{d}{4}}
             #cat {blo} {$bli}

             Lists

             Tables are sorted alphabetically with the exception of numbers which
             are sorted numerically. If you want to determine the sorting order
             yourself you can use use the #list command which helps you to use
             tables as arrays.

    Example: #action {%1 chats %2} {#list chats add {%0}}

             Each time a chat is received it's added to the end of the 'chats' list
             variable. If you type #variable chats this might look like:

             #VARIABLE {chats}
             {
                     {1} {Bubba chats Hi}
                     {2} {Bob chats Hi bub}
                     {3} {Bubba chats Bye}
                     {4} {Bob chats bub bye}
             }

             Parsing

             There are various ways to parse lists and tables, using either #loop,
             #foreach, #while, or #<number>.

             #loop takes two numeric arguments, incrementing or decrementing the
             first number until it matches the second number. The value of the loop
             counter is stored in the provided variable.

             #foreach takes either a simple list or a brace list as its first
             argument. Foreach will go through each item in the list and store the
             value in the provided variable.

             #while will perform an if check on the first argument, if the result
             is true it will execute the commands in the second argument. Then it
             performs an if check on the first argument again. It will continue to
             repeat until the if check returns 0 or the loop is interrupted with a
             control flow command. It takes special care to avoid infinite loops.

             #<number> will execute the provided argument 'number' times. For
             example: #4 {#show beep! \a}

             Here are some examples.

    Example: #list friends create {bob;bubba;zorro}

             Internally this looks like {{1}{bob}{2}{bubba}{3}{zorro}} and the
             list can be parsed in various ways.

    Example: #foreach {$friends[%*]} {name} {#show $name}

    Example: #foreach {*friends[%*]} {i} {#show $friends[$i]}

    Example: #loop {1} {&friends[]} {i} {#show $friends[+$i]}

    Example: #math i 1;#while {&friends[+$i]} {#show $friends[+$i];
             #math i $i + 1}

    Example: #math i 1;#&friends[] {#show $friends[+$i];#math i $i + 1}

             Each of the five examples above performs the same task; printing the
             three names in the friends list.

             If you want to get a better look at what goes on behind the scenes
             while executing scripts you can use '#debug all on'. To stop seeing
             debug information use '#debug all off'.

             List Tables

             List tables are also known as databases and the #list command has
             several options to manipulate them.

             For these options to work properly all tables need to have identical
             keys. Here is an example list table.

             #var {friendlist}
             {
                 {1}{{name}{bob} {age}{54}}
                 {2}{{name}{bubba} {age}{21}}
                 {3}{{name}{pamela} {age}{36}}
             }

             To sort the list table by age you would use:

             #list friendlist indexate age
             #list friendlist order

             To remove everyone whose name starts with a 'b' you would use:

             #list friendlist indexate name
             #list friendlist filter {} {b%*}

             The filter option only supports regular expressions. To filter
             using mathematics you would loop through the list backwards:

             #loop &friendlist[] 1 index
             {
                 #if {$friendlist[+$index][age] < 30}
                 {
                     #list friendlist delete $index
                 }
             }

             Alternatively you can use the refine option.

             #list friendlist indexate age
             #list friendlist refine {&0 >= 30}

             To add an item to a list table there are two options:

             #list friendlist add {{{name}{hobo} {age}{42}}}
             #list friendlist insert -1 {{name}{hobo} {age}{42}}

             Optimization

             TinTin++ tables are exceptionally fast while they remain under 100
             items. Once a table grows beyond 10000 items there can be performance
             issues when inserting and removing items in the beginning or middle of
             the table.

             The plan is to eventually implement an indexable and flexible data
             structure for large tables.

             If you load a large table from file it's important to make sure it's
             sorted, when using #write to save a table it's automatically sorted.

             If you notice performance issues on large tables it's relatively easy
             to create a hash table.

    Example:

             #alias {sethash}
             {
                 #format hash %H %1;
                 #math hash1 $hash % 100;
                 #math hash2 $hash / 100 % 100;
                 #var hashtable[$hash1][$hash2][%1] %2
             }

             #function {gethash}
             {
                 #format hash %H %1;
                 #math hash1 $hash % 100;
                 #math hash2 $hash / 100 % 100;
                 #return $hashtable[$hash1][$hash2][%1]
             }

             #alias {test}
             {
                 sethash bli hey;
                 sethash bla hi;
                 sethash blo hello;
                 #show The value of bla is: @gethash{bla}
             }

             The above script will rapidly store and retrieve over 1 million items.
             Looping through a hash table is relatively easy as well.

    Example:

             #alias {showhash}
             {
                 #foreach {*hashtable[%*]} {hash1}
                 {
                     #foreach {*hashtable[$hash1][%*]} {hash2}
                     {
                         #echo {%-20s = %s}
                                            {hashtable[$hash1][$hash2]}
                                            {$hashtable[$hash1][$hash2]}
                     }
                 }
            }

    Related: break, continue, foreach, loop, parse, repeat, return and while.

             MAPPING

             TinTin++ has a powerful automapper that uses a room system similar to
             Diku MUDs which means that odd map layouts and weird exit
             configurations aren't a problem. The mapper provides tools to improve
             the visual map display. For basic path tracking see #help PATH.

             #map create [size]

             This command creates the initial map. The size is 50,000 by default
             and can be changed at any time with the #map resize command. If you
             play a MUD that uses MSDP or GMCP to provide room numbers you'll have
             to increase it to the highest reported room number. Increasing the
             size of the map doesn't decrease performance.

             #map goto <location>

             When you create the map you are not automatically inside the map. By
             default room number (vnum) 1 is created, so you can go to it using
             #map goto 1. Once you are inside the map new rooms are automatically
             created as you move around. Movement commands are defined with the
             #pathdir command. By default n, ne, e, se, s, sw, w, nw, u, d are
             defined.

             #map map <rows> <cols> <append|overwrite|list|variable> <name>

             To see the map you can use #map map. It's annoying to have to
             constantly type #map map however. Instead it's possible to use #split
             to display a vt100 map. To do so execute:

             #split 16 1
             #map flag vtmap on

             The first command sets the top split lines to 16 and the bottom split
             line to 1. If you want a smaller or larger map display you can use a
             different value than 16.

             If you don't need to display diagonal exits and prefer a more compact
             look you can use #map flag AsciiGraphics off. This will enable the
             standard display which uses UTF-8 box drawing characters, results may
             vary depending on the font used.

             If your terminal supports UTF-8 you can also give #map flag unicode on
             a try.

             If you want to display the map in a different location of the screen
             use something like:

             #split 0 1 0 -80
             #map offset 1 81 -4 -1

             This will display the map on the right side of the screen, if the
             width of the screen is wide enough.

             #map undo

             If you accidentally walk into the wall on your MUD the mapper will
             still create a new room. You can easily fix this mistake by using
             #map undo. If you want to move around on the map without moving around
             on the MUD you can use: #map move {direction}. To delete a room
             manually you can use: #map delete {direction}. To create a room
             manually you can use: #map dig {direction}.

             #map write <filename>

             You can save your map using #map write, to load a map you can use
             #map read <filename>. You can return to the room you were in when
             the map was last saved by using #map return. You can use #event to
             automatically read and write the map on session start and end.

             #map set <option> <value>

             You can set the room name using #map set roomname <name>. You either
             have to do this manually or create triggers to set the room name
             automatically. Once the room name is set you can use #map goto with
             the room name to visit it. If there are two rooms with the same name
             #map goto will go to the most nearby room. If you want to always go
             to the same room you should memorize the room number or create a
             landmark.

             #map landmark firstroom 1

             You can further narrow down the matches by providing additional
             arguments, for example:

             #map goto {dark alley} {roomexits} {n;e} {roomarea} {Haddock Ville}

             You can set the room weight using #map set roomweight {value}. The
             weight by default is set to 1.0 and it represents the difficulty of
             traversing the room. If you have a lake as an alternative route, and
             traversing water rooms is 4 times slower than regular rooms, then you
             could set the weight of the lake rooms to 4.0. If the lake is 3 rooms
             wide the total weight is 12. If walking around the lake has a weight
             less than 12 the mapper will go around the lake, if the weight is
             greater than 12 the mapper will take a route through the lake.

             You can set the room symbol using #map set roomsymbol {value}. The
             symbol should be one, two, or three characters, which can be
             colorized. You can for example mark shops with an 'S' and colorize the
             'S' depending on what type of shop it is.

             #map run <location> <delay>

             The run command will have tintin find the shortest path to the given
             location and execute the movement commands to get there. You can
             provide a delay in seconds with floating point precision, for example:

             #map run {dark alley} {0.5}

             This will make you walk towards the nearest dark alley with 0.5 second
             intervals. Typical MUDs accept commands at 0.25 second intervals.

             #map insert {direction} {flag}

             The insert command is useful for adding spacer rooms called void rooms.
             Often rooms overlap, and by adding void rooms you can stretch out
             exits. For example: #map insert north void. You cannot enter void rooms
             once they've been created, so you'll have to use #map info in an
             adjacent room to find the room vnum, then use #map goto {vnum} to
             visit.

             It's also possible to align rooms using void rooms. This is easily
             done using #map insert north void.

    Related: map, path and pathdir.

             MATHEMATICS

             Number operations

             Operators       Priority     Function
             ------------------------------------------------
             !               0            logical not
             ~               0            bitwise not
             *               1            integer multiply
             **              1            integer power
             /               1            integer divide
             //              1            integer sqrt // 2 or cbrt // 3
             %               1            integer modulo
             d               1            integer random dice roll
             +               2            integer addition
             -               2            integer subtraction
             <<              3            bitwise shift
             >>              3            bitwise shift
             >               4            logical greater than
             >=              4            logical greater than or equal
             <               4            logical less than
             <=              4            logical less than or equal
             ==              5            logical equal
             !=              5            logical not equal
              &              6            bitwise and
              ^              7            bitwise xor
              |              8            bitwise or
             &&              9            logical and
             ^^             10            logical xor
             ||             11            logical or

             Operator priority can be ignored by using parentheses, for example
             (1 + 1) * 2 equals 4, while 1 + 1 * 2 equals 3.

             String operations

             Operators       Priority     Function
             ------------------------------------------------
             >               4            alphabetical greater than
             >=              4            alphabetical greater than or equal
             <               4            alphabetical less than
             <=              4            alphabetical less than or equal
             ==              5            alphabetical equal using regex
             !=              5            alphabetical not equal using regex
             ===             5            alphabetical equal
             !==             5            alphabetical not equal

             Strings must be encased in double quotes or braces. The > >= < <=
             operators perform basic string comparisons. The == != operators perform
             regular expressions, with the argument on the left being the string,
             and the argument on the right being the regex. For example
             {bla} == {%*a} would evaluate as 1.

    Related: math and regexp.

             METRIC SYSTEM

             The #math command supports using 1K, 1M, 1m, and 1u to make large and
             small number handling a little easier. These are case sensitive. Only
             four symbols are supported to keep false positives to a minimum.

             ╭─────────┬────────┬─────────────────────────────────╮
             │    Name │ Symbol │                           Factor│
             ├─────────┼────────┼─────────────────────────────────┤
             │    Mega │      M │                        1 000 000│
             │    Kilo │      K │                            1 000│
             │         │        │                                 │
             │   milli │      m │                            0.001│
             │   micro │      u │                        0.000 001│
             ╰─────────┴────────┴─────────────────────────────────╯

    Related: echo, format and math.

             MOUSE

             To enable xterm mouse tracking use #CONFIG MOUSE ON.

             To see mouse events as they happen use #CONFIG MOUSE INFO. This
             information can then be used to create mouse events with the #event
             command and buttons with the #button command.

             Visual buttons and pop-ups can be drawn on the screen with the #draw
             command.

             The input field can be changed and renamed using #screen inputregion,
             which allows creating named events for enter handling.

             Links can be created using the MSLP protocol which will generate link
             specific events when clicked.

             In order to copy/paste, most terminals require that you press the shift
             key during selection.

    Related: button, draw, event and MSLP.

             MSDP

             MSDP (Mud Server Data Protocol) is part of the #port functionality.
             See #help event for additional documentation as all MSDP events are
             available as regular events.

             Available MSDP events can be queried using the MSDP protocol
             as described in the specification.

             https://tintin.mudhalla.net/protocols/msdp

    Related: event and port.

             MSLP

             MSLP (Mud Server Link Protocol) requires enabling #config mouse on,
             and creating the appropriate LINK events.

             The simplest link can be created by surrounding a keyword with the
             \e[4m and \e[24m tags.

    Example: #substitute {\b{n|e|s|w|u|d}\b} {\e[4m%1\e[24m}

             This would display 'Exits: n, e, w.' as 'Exits: n, e, w.'.

             When clicked this would trigger the PRESSED LINK MOUSE BUTTON ONE
             event of which %4 will hold the link command and %6 holds the
             link name, which in the case of a simple link will be empty.

    Example: #event {PRESSED LINK MOUSE BUTTON ONE} {#send {%4}}

             Keep in mind that if you change PRESSED to DOUBLE-CLICKED the link
             will only work if the text does not scroll in between clicks.

             If you want to create a complex link use an OSC code.

    Example: #sub {\bsmurf\b} {\e]68;1;;say I hate smurfs!\a\e[4m%0\e[24m}

             If you have the LINK event of the previous example set, the %4
             argument will contain 'say I hate smurfs!'.

    Example: #sub {\bgoblin\b} {\e]68;1;SEND;kill goblin\a\e[4m%0\e[24m}

             Notice the previous instance of ;; has been replaced with ;SEND;
             which will name the link. This will generate a named event.

    Example: #event {PRESSED LINK SEND MOUSE BUTTON ONE} {#send {%4}}

             By naming links you can organize things a little bit better instead
             of tunneling everything through the same event.

             Keep in mind that the server is allowed to use \e]68;1;\a as well,
             subsequently various security measures are in place.

             To create secure links, which are filtered out when sent by a server,
             you need to use \e]68;2;\a, and they instead trigger the SECURE LINK
             event.

             To create a link that is not underlined, use \e]4;24m text \e]24m.

    Example: #sub {%* tells %*} {\e]68;2;EXEC;#cursor set tell %1 \a\e[4;24m%0\e[24m}
             #event {PRESSED SECURE LINK EXEC MOUSE BUTTON ONE} {%4}

             This would make you start a reply when clicking on a tell.

    Website: https://tintin.mudhalla.net/protocols/mslp

    Related: event and port.

             PCRE

             A regular expression, regex or regexp is a sequence of characters that
             defines a search pattern. Since the 1980s, different syntaxes for
             writing regular expressions exist, the two most widely used ones being
             the POSIX syntax and the similar but more advanced Perl standard.
             TinTin++ supports the Perl standard known as PCRE (Perl Compatible
             Regular Expressions).

             Regular expressions are an integral part of TinTin++, but keep in mind
             that tintin doesn't allow you to use regular expressions directly,
             instead it uses a simpler intermediate syntax that still allows more
             complex expressions when needed.

             Commands that utilize regular expressions are: action, alias, elseif,
             gag, grep, highlight, if, kill, local, math, prompt, regexp, replace,
             substitute, switch, variable and while. Several other commands use
             regular expressions in minor ways. Fortunately the basics are very
             easy to learn.

             TinTin++ Regular Expression

             The following support is available for regular expressions.

           ^ match start of line.
           $ match of end of line.
           \ escape one character.

      %1-%99 match of any text, stored in the corresponding index.
          %0 should be avoided in the regex, contains all matched text.
         { } embed a perl compatible regular expression, matches are stored.
       %!{ } embed a perl compatible regular expression, matches are not stored.

             [ ] . + | ( ) ? * are treated as normal text unless used within braces.
             Keep in mind that { } is replaced with ( ) automatically unless %!{ }
             is used.

    TinTin++ Description                                      POSIX
          %a Match zero or more characters including newlines ([^\0]*?)
          %A Match zero or more newlines                      ([\n]*?)
          %c Match zero or more ansi color codes              ((?:\e\[[0-9;]*m)*?)
          %d Match zero or more digits                        ([0-9]*?)
          %D Match zero or more non-digits                    ([^0-9]*?)
          %i Matches become case insensitive                  (?i)
          %I Matches become case sensitive (default)          (?-i)
          %s Match zero or more spaces                        ([\r\n\t ]*?)
          %S Match zero or more non-spaces                    ([^\r\n\t ]*?)
          %w Match zero or more word characters               ([A-Za-z0-9_]*?)
          %W Match zero or more non-word characters           ([^A-Za-z0-9_]*?)
          %? Match zero or one character                      (.??)
          %. Match one character                              (.)
          %+ Match one or more characters                     (.+?)
          %* Match zero or more characters excluding newlines (.*?)

             Ranges

             If you want to match 1 digit use %+1d, if you want to match between 3
             and 5 spaces use %+3..5s, if you want to match 1 or more word
             characters use %+1..w, etc.

             Variables

             If you use %1 in an action to perform a match the matched string is
             stored in the %1 variable which can be used in the action body.

    Example: #act {%1 says 'Tickle me'} {tickle %1}

             If you use %2 the match is stored in %2, etc. If you use an unnumbered
             match like %* or %S the match is stored at the last used index
             incremented by one.

    Example: #act {%3 says '%*'} {#if {"%4" == "Tickle me"} {tickle %3}}

             The maximum variable index is 99. If you begin an action with %* the
             match is stored in %1. You should never use %0 in the trigger part of
             an action, when used in the body of an action %0 contains all the parts
             of the string that were matched.

             To prevent a match from being stored use %!*, %!w, etc.

             Perl Compatible Regular Expressions

             You can embed a PCRE (Perl Compatible Regular Expression) using curley
             braces { }, these braces are replaced with parentheses ( ) unless you
             use %!{ }.

             Or

             You can separate alternatives within a PCRE using the | character.

    Example: #act {%* raises {his|her|its} eyebrows.} {say 42..}

             Brackets

             You can group alternatives and ranges within a PCRE using brackets.

    Example: #act {%* says 'Who is number {[1-9]}?} {say $number[%2] is number %2}

             The example only triggers if someone provides a number between 1 and
             9. Any other character will cause the action to not trigger.

    Example: #act {%* says 'Set password to {[^0-9]*}$} {say The password must
               contain at least one number, not for security reasons, but just to
               annoy you.} {4}

             When the ^ character is used within brackets it creates an inverse
             search, [^0-9] matches every character except for a number between 0
             and 9.

             Quantification

             A quantifier placed after a match specifies how often the match is
             allowed to occur.

           ? repeat zero or one time.
           * repeat zero or multiple times.
           + repeat once or multiple times.
         {n} repeat exactly n times, n must be a number.
        {n,} repeat at least n times, n must be a number.
       {n,o} repeat between n and o times, n and o must be a number.

    Example: #act {%* says 'Who is number {[1-9][0-9]{0,2}}?} {Say $number[%2] is
               number %2}

             The example only triggers if someone provides a number between 1 and
             999.

             Parantheses

             TinTin Regular Expressions automatically add parenthesis, for example
             %* translates to (.*?) in PCRE unless the %* is found at the start or
             end of the line, in which cases it translates to (.*). Paranthesis in
             PCRE causes a change in execution priority similar to mathematical
             expressions, but parentheses also causes the match to be stored to a
             variable.

             When nesting multiple sets of parentheses each nest is assigned its
             numerical variable in order of appearance.

    Example: #act {%* chats '{Mu(ha)+}'} {chat %2ha!}

             If someone chats Muha you will chat Muhaha! If someone chats Muhaha
             you will chat Muhahaha!

             Lazy vs Greedy

             By default regex matches are greedy, meaning {.*} will capture as much
             text as possible.

    Example: #regex {bli bla blo} {^{.*} {.*}$} {#show Arg1=(&1) Arg2=(&2)}

             This will display: Arg1=(bli bla) Arg2=(blo)

             By appending a ? behind a regex it becomes lazy, meaning {.*?} will
             capture as little text as possible.

    Example: #regex {bli bla blo} {^{.*?} {.*?}$} {#show Arg1=(&1) Arg2=(&2)}

             This will display: Arg1=(bli) Arg2=(bla blo).

             Escape Codes

             PCRE support the following escape codes.

        PCRE Description                                    POSIX
          \A Match start of string                          ^
          \b Match word boundaries                          (^|\r|\n|\t| |$)
          \B Match non-word boundaries                      [^\r\n\t ]
          \c Insert control character                       \c
          \d Match digits                                   [0-9]
          \D Match non-digits                               [^0-9]
          \e Insert escape character                        \e
          \f Insert form feed character                     \f
          \n Insert line feed character                     \n
          \r Insert carriage return character               \r
          \s Match spaces                                   [\r\n\t ]
          \S Match non-spaces                               [^\r\n\t ]
          \t Insert tab character                           \t
          \w Match letters, numbers, and underscores        [A-Za-z0-9_]
          \W Match non-letters, numbers, and underscores    [^A-Za-z0-9_]
          \x Insert hex character                           \x
          \Z Match end of string                            $
          \\ Match a backslash                              \\

             \s matches one space, \s+ matches one or multiple spaces, the use
             of {\s+} is required for this sequence to work in tintin, \s by
             itself will work outside of a set of braces.

             Use \% to forcibly match a literal % character.

             Color triggers

             To make matching easier text triggers (Actions, Gags, Highlights,
             Prompts, and Substitutes) have their color codes stripped. If you
             want to create a color trigger you must start the triggers with a ~
             (tilde). To make escape codes visible use #config {convert meta} on.

    Example: #action {~\e[1;37m%1} {#var roomname %1}

             If the room name is the only line on the server in bright white
             white color trigger will save the roomname.

             This covers the basics. PCRE has more options, most of which are
             somewhat obscure, so you'll have to read a PCRE manual for additional
             information.

    Related: map and path.

             REPEAT

    Command: #[number] {commands}

            Sometimes you want to repeat the same command multiple times. This is
            the easiest way to accomplish that.

    Example: #10 {buy bread}

    Related: mathematics and statements.

             SCREEN READER

    Command: #config {SCREEN READER} {ON|OFF}

             Screen reader mode is enabled by using #config screen on. One purpose
             of the screen reader mode is to report to servers that a screen reader
             is being used by utilizing the MTTS standard. The MTTS specification
             is available at:

             https://tintin.mudhalla.net/protocols/mtts

             With the screen reader mode enabled TinTin++ will try to remove or
             alter visual elements where possible.

    Related: config

             SESSIONNAME

    Syntax:  #[sessionname] {commands}

             You can create multiple sessions with the #session command. By default
             only one session is active, meaning commands you input are executed in
             the active session. While all sessions receive output, only output sent
             to the active session is displayed.

             When you create a session with the #session command you must specify a
             session name, the session name, prepended with a hashtag, can be used
             to activate the session when used without an argument. If an argument
             is given it will be executed by that session as a command, the session
             will not be activated.

    Example: #ses one tintin.net 23;#ses two tintin.net 23;#one;#two grin

             This will create two sessions, the session that was created last (two
             in this case) will be automatically activated upon creation. Using
             #one, session one is activated. Using #two grin, the grin social will
             be executed by session two, session one will remain the active session.

             If you send a variable to another session it will be substituted before
             being passed. If you want the variable value of the receiving session
             to be used you need to use '$${variable}' to properly escape it.

    Syntax:  @[sessionname]{substitution}

             If you want to pull the value of a variable from another session you
             can do so in a similar way as you would use a #function call. Using
             #showme {@two{$test}} in session one would print the value of $test,
             as defined by session two.

    Related: suspend

             SPEEDWALK

             SPEEDWALK V1

             Speedwalking allows you to enter multiple directions without using
             semicolons. Directions should be prefixed with a number and will be
             executed the given number of times.

             You can enable speedwalking with #CONFIG {SPEEDWALK} {ON}.

    Example: Without speedwalk, you have to type:
             s;s;w;w;w;w;w;s;s;s;w;w;w;n;n;w
             With speedwalk, you only have to type:
             2s5w3s3w2nw

             SPEEDWALK V2

             Modern MUDs have increasingly adopted the use of diagonal exits, like
             ne, nw, sw, and se. To make accomodations for this the #map and #path
             command no longer interpret nesw as a speedwalk and require this to
             be written as 1n1e1s1w, which then allows 2ne2e to execute ne;ne;e;e.

             Speedwalks entered on the input line continue to use the v1 system.

             The #path load command is backward compatible with v1 speedwalks and
             to load v2 speedwalks the #path unzip command needs to be used, unless
             the speedwalk was saved using #path save in which case a v2 compatible
             format is used that can also contain timing data.

    Example: #path unzip 3n1e2nw
    Example: #map move 3ne1d

    Related: keypad, mapping and repeat.

             STATEMENTS

             TinTin++ knows the following statements.

             #break
             #case {value} {true}
             #continue
             #default {commands}
             #else {commands}
             #elseif {expression} {true}
             #foreach {list} {variable} {commands}
             #if {expression} {true}
             #loop {min} {max} {variable} {commands}
             #parse {string} {variable} {commands}
             #return {value}
             #switch {expression} {commands}
             #while {expression} {commands}

    Related: mathematics, pcre and repeat.

             SUBSTITUTIONS

              TinTin++ will perform various types of substitions as detailed below.

              Variables

    $ & * @   All variable and function names must begin with an alphabetic
              character, followed by any combination of alphanumeric characters and
              underscores.

    $         The dollar sign is used to retrieve the value of a variable.

    &         The ampersand sign is used to retrieve the index of a variable.

    *         The astrix sign is used to retrieve the name of a variable.

    @         The at sign is used for functions.

    [ ]       Brackets are used for nested variables which function as an
              associative array. Associative arrays are also known as tables and
              maps. Regex can be used within brackets to match multiple variables.

    + -       The plus and minus signs are used to access variables by their index,
              with the first variable having index +1, and the last variable
              having index -1. Variables are ordered alphanumerically.

              All variables and functions can be escaped by doubling the sign,
              like $$variable_name or @@function_name. To escape a variable
              twice use $$$var_name. One escape is removed each time tintin
              needs to substitute a variable or function.

              Arguments

    %0 - %99  The percent sign followed by a number is used for arguments by the
              following triggers:

              alias, action, button, event, function, prompt, and substitute.

    &0 - &99  The ampersand sign followed by a number is used for arguments in the
              regex and replace commands.

              All trigger and command arguments can be escaped by doubling the
              sign like %%1 or &&1. One escape is removed each time tintin
              substitutes trigger or command arguments. To escape three times
              triple the sign like %%%1, etc.

              Colors

    <000>     Three alphanumeric characters encapsulated by the less- and greater-
              than signs are used for 4 and 8 bit color codes.

    <0000>    Either a B (background) or F (foreground) followed by three
              hexadecimal characters encapsulated by < > signs are used for 12
              bit color codes. Requires truecolor capable terminal.

    <0000000> Either a B (background) or F (foreground) followed by six
              hexadecimal characters encapsulated by < > signs are used for 24
              bit color codes. Requires truecolor capable terminal.

              More information is available at #help color.

              Escapes

    \         The back slash is used to escape a character. All available options
              are listed at #help escape. Escapes are typically escaped when text
              leaves the client, by being sent to a server, the shell, being
              displayed on the screen, or being processed as part of a regex.
              Escapes try to mimic escapes in PCRE when possible.

    Related: characters, colors, escape_codes and pcre.

             SUSPEND

    Command: #cursor suspend

             Temporarily suspends tintin and returns you to your shell.  To
             return to tintin, type 'fg' at the shell prompt.

             While suspended your tintin sessions will freeze. To keep a
             suspended session running use the #daemon command.

    Related: sessionname

             TIME

    Command: #format {variable} {%t} {argument}

             The %t format specifier of the #format command allows printing dates
             using the strftime() format specifiers. By default the time stamp used
             is the current time, if you want to print a past or future date use:

    Command: #format {variable} {%t} {{argument} {epoch time}}

             The current epoch time value is obtained using #format {time} {%T}.

             When using %t the argument should contain strftime format specifiers.
             Below are some common specifiers, see man strftime for the full list.

             %a  Abbreviated name of the day of the week (mon ... sun).
             %A  Full name of the day of the week. (Monday ... Sunday)
             %b  Abbreviated name of the month (Jan ... Dec)
             %B  Full name of the month. (January ... December)
             %C  2 digit numeric century. (19 ... 20)
             %d  2 digit numeric day of the month (01 ... 31)
             %H  2 digit numeric 24-hour clock hour. (00 ... 23)
             %I  2 digit numeric 12-hour clock hour. (01 ... 12)
             %j  3 digit numeric day of the year (001 ... 366)
             %m  2 digit numeric month of the year (01 ... 12)
             %M  2 digit numeric minute of the hour (00 ... 59)
             %p  Abbreviated 12 hour clock period (AM ... PM)
             %P  Abbreviated 12 hour clock period (am ... pm)
             %S  2 digit numeric second of the minute (00 ...59
             %u  1 digit numeric day of the week (1 ... 7)
             %U  2 digit numeric Sunday week of the year (00 ... 53
             %w  1 digit numeric day of the week (0 ... 6)
             %W  2 digit numeric Monday week of the year (00 ... 53
             %y  2 digit numeric year. (70 ... 38)
             %Y  4 digit numeric year. (1970 ... 2038)
             %z  5 digit timezone offset. (-1200 ... +1400)
             %Z  Abbreviated name of the time zone. (CET, GMT, etc)

    Related: echo, event and format.

             TRIGGERS

             All available triggers in TinTin++ are displayed when you use the #info
             command without an argument. All of them are written to file when you
             use the #write command, except commands, histories, and paths.

             Triggers can be disabled with the #ignore command. The #message
             command can be used to disable messages generated or related to the
             corresponding trigger, though this is generally not needed.

             The #debug command will generate useful debugging information for the
             corresponding trigger when enabled. The #info command can be used on
             triggers to generate additional information that might be of use.

    Example: #info event on

             When #info event is set to on you will see when most events are raised.
             Since this can get rather spammy some of the events won't generate
             messages, unless you have an event in the same category set already.

             Text triggers

             When a block of text arrives from the host it is split into individual
             lines, and all action, prompt, gag, substitute, and highlight triggers
             are checked for each line. Only one action can trigger per line, while
             the other triggers can trigger multiple times.

             Packet fragmentation

             MUDs that send long blurbs of text, don't have MCCP support, have a bad
             connection, or a combination of all three, will deliver broken packets.
             This can cause triggers to not fire, as well as displaying problems if
             #split is enabled.

             To mitigate this you can use #config packet_patch 0.5.

             TinTin++ will automatically enable packet patching if the IAC GA or IAC
             EOR telnet sequences are used to mark the end of the prompt. A MUD can
             negotiate the EOR option: https://tintin.mudhalla.net/protocols/eor

             In addition #prompt can be used to make packet patching less noticable.

             Color triggers

             By default most color, control, and vt100 codes are stripped from
             incoming text before being ran through the trigger engine. To create
             a trigger that runs on the unstripped text, the regular expression in
             the trigger should start with a ~.

             To view control codes you can use #config convert_meta on which will
             translate both input and output codes to PCRE escape sequences.

             Multi-line triggers

             If an action or substitution contains the \n sequence it will be
             turned into a multi-line trigger. A multi-line trigger is executed on
             incoming blocks of text from the MUD, and they will not trigger if the
             regular expression spans more than one block. You can visualize
             incoming blocks by using the following event:

             #event {RECEIVED OUTPUT} {#echo <058>%+80h BLOCK}

             Since the %* expression does not capture the \n sequence it is required
             to use %a to capture multiple lines. To capture the start of the block
             use \A and for the end use \Z. You can use ^ and $ to capture the
             start and end of a line.

             Multi-line triggers trigger before regular triggers. Multiple
             multi-line actions can trigger per block, and each multi-line action
             can trigger multiple times per block. Packet fragmentation is not
             currently handled.

             Multi-line triggers are experimental and subject to change.

             Input triggers

             The alias, history and pathdir triggers are checked for each line of
             input. The macro and tab triggers are checked for key presses.

             Time triggers

             The delay, path, and ticker triggers will execute at a set timed
             interval.

             Substitution triggers

             The function and variable triggers will generally execute right
             before the final processing of a line of text.

             Mouse triggers

             The button trigger is checked for each mouse input. #config mouse
             must be set to on to enable mouse tracking.

             Event triggers

             Events can be used for a wide variety of pre-defined triggers.

    Related: pcre, substitutions and escape_codes.