Initial git import v0.9.6
authorSteve Youngs <steve@sxemacs.org>
Sun, 31 Oct 2010 06:35:41 +0000 (16:35 +1000)
committerSteve Youngs <steve@sxemacs.org>
Sun, 31 Oct 2010 06:35:41 +0000 (16:35 +1000)
55 files changed:
.arch-inventory [new file with mode: 0644]
.gitignore [new file with mode: 0644]
ChangeLog.SFCVS [new file with mode: 0644]
ChangeLog.d/ChangeLog-0.6.Eicq [new file with mode: 0644]
ChangeLog.d/ChangeLog-0.7.Eicq [new file with mode: 0644]
ChangeLog.d/ChangeLog-0.8.Eicq [new file with mode: 0644]
ChangeLog.d/ChangeLog-0.9.1.Eicq [new file with mode: 0644]
ChangeLog.d/ChangeLog-0.9.2 [new file with mode: 0644]
ChangeLog.d/ChangeLog-0.9.Eicq [new file with mode: 0644]
INSTALL [new file with mode: 0644]
Makefile [new file with mode: 0644]
NEWS [new file with mode: 0644]
README [new file with mode: 0644]
TODO [new file with mode: 0644]
build.el [new file with mode: 0644]
emchat-buddy.el [new file with mode: 0644]
emchat-convert.el [new file with mode: 0644]
emchat-curl.el [new file with mode: 0644]
emchat-doctor.el [new file with mode: 0644]
emchat-emphasis.el [new file with mode: 0644]
emchat-history.el [new file with mode: 0644]
emchat-log.el [new file with mode: 0644]
emchat-menu.el [new file with mode: 0644]
emchat-meta.el [new file with mode: 0644]
emchat-report.el [new file with mode: 0644]
emchat-setup.el [new file with mode: 0644]
emchat-status.el [new file with mode: 0644]
emchat-toolbar.el [new file with mode: 0644]
emchat-track.el [new file with mode: 0644]
emchat-utils.el [new file with mode: 0644]
emchat-v8.el [new file with mode: 0644]
emchat-wharf.el [new file with mode: 0644]
emchat-world.el [new file with mode: 0644]
emchat-xwem.el [new file with mode: 0644]
emchat.el [new file with mode: 0644]
emchat.texi [new file with mode: 0644]
images/auth-here.xpm [new file with mode: 0644]
images/emchat-icon.png [new file with mode: 0644]
images/exit.xpm [new file with mode: 0644]
images/help.xpm [new file with mode: 0644]
images/info-around.xpm [new file with mode: 0644]
images/info-here.xpm [new file with mode: 0644]
images/log-header.xbm [new file with mode: 0644]
images/login.xpm [new file with mode: 0644]
images/logo.png [new file with mode: 0644]
images/logout.xpm [new file with mode: 0644]
images/mini-logo.png [new file with mode: 0644]
images/msg-around.xpm [new file with mode: 0644]
images/msg-here.xpm [new file with mode: 0644]
images/new-log.xpm [new file with mode: 0644]
images/password.xpm [new file with mode: 0644]
images/search.xpm [new file with mode: 0644]
images/upd-info.xpm [new file with mode: 0644]
images/url-around.xpm [new file with mode: 0644]
images/url-here.xpm [new file with mode: 0644]

diff --git a/.arch-inventory b/.arch-inventory
new file mode 100644 (file)
index 0000000..4ce86c6
--- /dev/null
@@ -0,0 +1,4 @@
+unrecognized ^(.*\.rej)$
+precious ^(.*\.elc|(auto-autoloads|custom-(load|defines)|emchat-version)\.el|emchat\.info|TAGS)$
+precious ^(emchat-version.texi)$
+precious ^(prepsrc.el)$
diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/ChangeLog.SFCVS b/ChangeLog.SFCVS
new file mode 100644 (file)
index 0000000..f61371f
--- /dev/null
@@ -0,0 +1,1324 @@
+This is the old ChangeLog from when Eicq was in CVS at SF.net
+
+2004-06-09  Steve Youngs  <steve@youngs.au.com>
+
+       * eicq-log.el (eicq-log-buddy-message): Remove call to
+       `goto-addr'.  We'll write our own using XEmacs extents.
+       Don't require goto-addr.el, so we don't need the fsf-compat
+       package. 
+
+2004-06-09  Steve Youngs  <steve@youngs.au.com>
+
+       * eicq-v8.el: New file.
+
+2004-05-30  Steve Youngs  <steve@youngs.au.com>
+
+       * *: Update copyright notices and my email address.
+
+2003-10-17  Steve Youngs  <sryoungs@bigpond.net.au>
+
+       * eicq-v8proto.el (eicq::CLI_IDENT): Comment out entries that were
+       causing "Variable binding depth exceeds max-specpdl-size" errors.
+       BE AWARE! The code is STILL broken, this is just a temporary
+       workaround so that Eicq compiles.
+
+       * Makefile (distclean): Delete the TAGS file too.
+
+2003-10-15  Steve Youngs  <sryoungs@bigpond.net.au>
+
+       * Makefile (EMACS): Removed, this is XEmacs not Emacs.
+       (EMACS_FLAGS): Ditto.
+       (XEMACS): New.
+       (XEMACS_FLAGS): New, add '-no-autoloads' to ensure we are building
+       in a clean environment.
+       (AUTO_PRELOADS): Removed.
+       (AUTOLOAD_PACKAGE_NAME): New.
+       (AUTOLOAD_FILE): New.
+       (all): Use 'compile' target instead of '$(OBJECTS)'.  This is so
+       we can compile all the .el files from a single instance of
+       XEmacs.  The old way loaded XEmacs for each and every file that
+       was built.
+       (.el.elc): Removed.
+       (compile): New.
+       (auto-autoloads.el): Set it up to use '-no-autoloads'
+       (custom-loads.el): Ditto.
+       (distclean): Remove core* files.
+
+       * eicq-buddy.el: Require advice at compile time.
+
+       * eicq-comm.el: Require passwd at compile time.
+       (eicq-encrypt-password): Return in hex.
+
+       * eicq-log.el: Require smiley and goto-addr at compile time.
+
+       * eicq-report.el: Require font-lock, yow, and pp at compile time.
+
+       * eicq-v8proto.el: Require eicq-world, eicq.
+       (eicq-put-alist): Removed.
+       (eicq-alist-hex-to-bin): Simplified.
+       (eicq-fun-hex-to-bin): New.
+       (deficq): Simplified.
+       (eicq-valid-prefix-list): New.
+
+       * eicq-world.el: Require font-lock and sort at compile time.
+
+       * eicq.el: Require ehelp, cus-edit, browse-url, and passwd at
+       compile time.
+
+2003-10-02  Steve Youngs  <sryoungs@bigpond.net.au>
+
+       * README: Update my email address.
+
+       * eicq-v8proto.el: Ditto.
+
+       * eicq.el: Ditto.
+
+       * eicq-world.el: Ditto.
+
+       * eicq-toolbar.el: Ditto.
+
+       * eicq-status.el: Ditto.
+
+       * eicq-setup.el: Ditto.
+
+       * eicq-report.el: Ditto.
+       (eicq-prepare-email-author): Ditto.
+
+       * eicq-meta.el: Ditto.
+
+       * eicq-menu.el: Ditto.
+
+       * eicq-log.el: Ditto.
+
+       * eicq-comm.el: Ditto.
+
+       * eicq-buddy.el: Ditto.
+
+2003-10-01  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq-v8proto.el (eicq::CLI_IDENT): Fix 'Invalid read syntax:
+       ". in wrong context"' error.
+       (eicq::CLI_SETSTATUS): Ditto.
+
+2003-09-19  Steve Youngs  <youngs@xemacs.org>
+
+       * *: Update to BSD license.
+
+       * eicq.el (eicq-copyright): A function to satisfy condition 2 of
+       the BSD license.
+
+       * eicq.texi: Removed practically everything in the file because it
+       desparately needs a complete rewrite.
+
+       * infohack.el: Removed.
+
+       * Makefile (MAKEINFO): New.
+       (.texi.info): Use it.
+       (EICQ_INFO_COMPILE): Removed.
+
+2003-09-06  Steve Youngs  <youngs@xemacs.org>
+
+       * Makefile (VER): Bump.
+
+       * eicq-comm.el (eicq-network-buffer):
+       (eicq-network-hostname): Removed.
+       (eicq-server-hostname):
+       (eicq-network-port): Removed.
+       (eicq-local-network-p): Removed.
+       (eicq-network):
+       (eicq-int-byte):
+       (eicq-network-kill):
+       (eicq-connected-p):
+       (eicq-binary-process): New.
+       (eicq-connect):
+       
+       * eicq-convert.el:
+       
+       * eicq-meta.el (eicq-pack):
+
+       * eicq-report.el (eicq-version):
+       * eicq-status.el:
+
+       * eicq-toolbar.el (eicq-change-password):
+
+       * eicq-v8proto.el (eicq-use-firewall): New.
+       (eicq-hex-to-bin): New.
+       (eicq-put-alist): New.
+       (eicq-alist-hex-to-bin): New.
+       (deficq): New.
+       (eicq::FLAP_header): New.
+       (eicq::FLAP_channels): New.
+       (eicq::CLI_bytefiller): New.
+       (eicq::CLI_IDENT): New.
+       (eicq::CLI_READY): New.
+       (eicq::CLI_RATESREQUEST): New.
+       (eicq::CLI_ACKRATES): New.
+       (eicq::CLI_REQINFO): New.
+       (eicq::CLI_SNAC1_11): New.
+       (eicq::CLI_FAMILIES): New.
+       (eicq::CLI_SETSTATUS): New.
+       (eicq::CLI_REQLOCATION): New.
+       (eicq::CLI_SETUSERINFO): New.
+       (eicq::CLI_REQBUDDY): New.
+       (eicq::CLI_ADDCONTACT): New.
+       (eicq::CLI_REMCONTACT): New.
+       (eicq::CLI_SETICBM): New.
+       (eicq::CLI_REQICBM): New.
+       (eicq::CLI_REQBOS): New.
+       
+       * eicq-world.el:
+
+       * eicq.el (eicq-version):
+       (eicq-status-auto-reply):
+       (eicq-frame):
+       (eicq-network-show-buffer): Removed.
+       (eicq-send-internal):
+       (eicq-pack-login-a):
+       (eicq-login):
+
+       Big huge changes trying to get ICQv8 protocol working.  This is a
+       long way from complete and Eicq is totally broken at this point.
+
+2003-03-02  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq-v8proto.el (deficq): New macro to define ICQ packets.
+
+2002-10-03  Steve Youngs  <youngs@xemacs.org>
+
+       * etc/*: Removed, we do it all in lisp now.
+       
+       * eicq-buddy.el (eicq-buddy-status-color-hint-flag): Removed.
+       (eicq-face-online): Removed.
+       (eicq-face-away): Removed.
+       (eicq-face-occ): Removed.
+       (eicq-face-dnd): Removed.
+       (eicq-face-ffc): Removed.
+       (eicq-face-na): Removed.
+       (eicq-face-offline): Removed.
+       (eicq-buddy-update-status): Removed.
+
+       * NEWS: Updated.
+       
+       * TODO: Updated.
+
+       * INSTALL: Updated.
+
+       * eicq-convert.el: Update requires
+
+       * eicq-report.el (eicq-report-debug): Add missing .el files.
+
+       * eicq-toolbar.el (eicq-icon-directory): Removed.
+       (eicq-use-toolbar): Test for featurep 'xpm.
+       (eicq-password-icon): Create toolbar icon in lisp.
+       (eicq-send-message-here-icon): Ditto.
+       (eicq-send-message-around-icon): Ditto.
+       (eicq-send-url-here-icon): Ditto.
+       (eicq-send-url-around-icon): Ditto.
+       (eicq-query-info-here-icon): Ditto.
+       (eicq-query-info-around-icon): Ditto.
+       (eicq-update-info-icon): Ditto.
+       (eicq-search-icon): Ditto.
+       (eicq-authorize-here-icon): Ditto.
+       (eicq-login-icon): Ditto.
+       (eicq-logout-icon): Ditto.
+       (eicq-disconnect-icon): Ditto.
+       (eicq-new-log-icon): Ditto.
+       (eicq-help-icon): Ditto.
+
+       * .cvsignore: Updated.
+
+       * Makefile (DATA_DIR): Removed.
+       (BIN_DIR): Removed.
+       (BIN_STAGING): Removed.
+       (DATA_STAGING): Removed.
+       (INSTALL): Remove the BIN and DATA stuff.
+       (SOURCES): Use a wildcard instead of listing each file.
+
+       * eicq-menu.el (eicq-main-map): Autoload it.
+       (eicq-global-map-set): Ditto.
+       (eicq-global-key-prefix): Ditto.
+       (eicq-log-mode-map): Ditto.
+       (eicq-alias-map): Ditto.
+       (eicq-url-map): Ditto.
+       (eicq-buddy-mode-map): Ditto.
+
+       * eicq-world.el (eicq-world): New.
+       (eicq-all-aliases): New.
+       (eicq-world-rc-regexp): New.
+       (Format): New.
+       (unknown)): New.
+       (unknown-2)): New.
+       (eicq-do-meta-user-work): New.
+       (eicq-do-meta-user-more): New.
+       (Language-1): New.
+       (Language-2): New.
+       (Language-3): New.
+       (eicq-do-meta-user-about): New.
+       (eicq-do-meta-user-interest): New.
+       (eicq-do-meta-user-background): New.
+       (eicq-do-meta-user-picture): New.
+       (eicq-do-meta-user-found): New.
+       (eicq-do-meta-user-update-general-confirm): New.
+       (eicq-do-meta-user-update-work-confirm): New.
+       (eicq-do-meta-user-update-more-confirm): New.
+       (eicq-do-meta-user-update-about-confirm): New.
+       (eicq-do-meta-user-update-security-confirm): New.
+       (eicq-do-meta-user-password): New.
+       (eicq-update-meta-info): New.
+
+       * eicq-setup.el: New.
+
+       * eicq-status.el (eicq-buddy-status-color-hint-flag): New.
+       (eicq-status-window-height): New.
+       (eicq-valid-statuses): New.
+       (eicq-user-initial-status): New.
+       (eicq-status-update-hook): New.
+       (eicq-face-online): New.
+       (eicq-face-away): New.
+       (eicq-face-occ): New.
+       (eicq-face-dnd): New.
+       (eicq-face-ffc): New.
+       (eicq-face-na): New.
+       (eicq-face-offline): New.
+       (eicq-statuses): New.
+       (eicq-status-face): New.
+       (eicq-status-bin): New.
+       (eicq-status-auto-reply): New.
+       (eicq-status-idle-reply): New.
+       (eicq-status-name): New.
+       (eicq-buddy-update-status): New.
+       (eicq-user-status): New.
+       (eicq-pack-status-change): New.
+       (eicq-do-status-update): New.
+       (eicq-change-status): New.
+       (eicq-status-buffer): New.
+       (eicq-status-show-buffer): New.
+
+       * eicq.el (eicq-meta): Removed.
+       (eicq-user-meta-nickname): Removed.
+       (eicq-user-meta-firstname): Removed.
+       (eicq-user-meta-lastname): Removed.
+       (eicq-user-meta-primary-email): Removed.
+       (eicq-user-meta-secondary-email): Removed.
+       (eicq-user-meta-old-email): Removed.
+       (eicq-auto-response-messages-p):
+       (eicq-valid-statuses): Removed.
+       (eicq-user-initial-status): Removed.
+       (eicq-new-message-hook): defvar -> defcustom
+       (eicq-status-window-height): Removed.
+       (eicq-read-message-hook): defvar -> defcustom
+       (eicq-user-status): Removed.
+       (eicq-system-message-hook): defvar -> defcustom
+       (eicq-status-update-hook): Removed.
+       (eicq-load-hook): New.
+       (eicq-monthnames): Removed.
+       (eicq-country-code): Removed.
+
+2002-10-01  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq-buddy.el: New file.
+
+       * eicq-log.el: New file.
+
+       * eicq-menu.el: New file.
+
+       * eicq-world.el: New file.
+
+       * eicq-v8proto.el: New file.
+
+       * eicq.el (eicq-log-*): Moved to eicq-log.el.
+       (eicq-buddy-*): Moved to eicq-buddy.el.
+       (eicq-*-menu): Moved to eicq-menu.el.
+       (eicq-*-map): Ditto.
+       (eicq-alias-*): Moved to eicq-world.el
+       (eicq-world-*): Ditto.
+
+       * eicq-report.el (eicq-report-debug): Add eicq-menu.el,
+       eicq-buddy.el, eicq-log.el eicq-world.el
+
+       * Makefile: Remove stuff concerning icq2tcp binary, we do it all
+       in lisp now.
+       (SOURCES): Add eicq-menu.el eicq-buddy.el eicq-log.el
+       eicq-world.el eicq-v8proto.el.
+
+2002-09-30  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-pack-login-a): New.  The login is now a 2 stage
+       process so 'eicq-pack-login' has been split into -a & -b.
+       (eicq-pack-login-b): New.
+
+2002-09-29  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq-convert.el (eicq-import-from-micq): Support new micq rc
+       file format.
+
+2002-07-29  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-user-password): Move to eicq-comm.el
+       (eicq-connected-p): Ditto.
+       (eicq-network-mode): Ditto.
+       (eicq-network-kill): Ditto.
+
+2002-06-17  Steve Youngs  <youngs@xemacs.org>
+
+       * Makefile (SOURCES): Add eicq-comm.el.
+
+2002-06-16  Jack Twilley  <jmt@tbe.net>
+
+        * eicq.el (eicq-log-buddy-message): Made smileys optional.
+          (eicq-smiley): Created a configure variable in the 
+          'eicq-interface' group.
+
+2002-05-16  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-world-rc-regexp): Update regexp so we don't gobble
+       whitespace.
+       From Vladimir Alexiev <Vladimir@worklogic.com>.
+
+2002-05-12  Steve Youngs  <youngs@xemacs.org>
+
+       * icq2tcp.c: Add a "This file is part of" clause.
+
+       * eicq-comm.el: Ditto.
+
+       * eicq-convert.el: Ditto.
+
+       * eicq-report.el: Ditto.
+
+       * eicq-toolbar.el: Ditto.
+
+       * eicq-wharf.el: Ditto.
+
+       * eicq.el (eicq-dropped-packet-counter): Moved to eicq-comm.el.
+       (eicq-resend-packet-counter): Ditto.
+       (eicq-recent-packet): Ditto.
+       (eicq-trimmed-packet-counter): Ditto.
+       (eicq-error-packets): Ditto.
+       (eicq-network): Ditto.
+       (eicq-bridge): Removed.
+       (eicq-connect): Moved to eicq-comm.el.
+       (eicq-main-map): We don't have "bridges" anymore, we use
+       "networks". 
+       (eicq-main-menu): Ditto.
+       (eicq-bridge-mode): Renamed to 'eicq-network-mode'.
+       (eicq-bridge-kill): Removed.
+       (eicq-disconnect): Bridges are now networks.
+       (eicq-pack-login): Use the encrypted password from eicq-comm.el.
+       (eicq-hide-window): Bridges are now networks.
+       Add a "This file is part of" clause.
+
+2002-05-11  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-bridge-filename): Removed.
+       (eicq-bridge-buffer): Ditto.
+       (eicq-bridge-hostname): Ditto.
+       (eicq-bridge-port): Ditto.
+       (eicq-local-bridge-p): Ditto.
+
+       * eicq-comm.el: New file.
+
+       * eicq.el (eicq-comm): Require it.
+
+2002-04-10  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq-report.el (eicq-report-debug): Add eicq-comm.el.
+
+2002-02-17  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-version): Boost it up to version 0.5.0 as the
+       start of the ICQv7/8 series.
+       (eicq-server-hostname): Change to "login.icq.com".
+       (eicq-server-port): Change to 5190.
+
+2002-01-11  Steve Youngs  <youngs@xemacs.org>
+
+       * TODO: Add items about PostgreSQL, X-Faces, Balloon-help
+       dialogs. 
+
+2001-12-24  Steve Youngs  <youngs@xemacs.org>
+
+       * TODO: Add item about implementing new protocol.
+
+2001-10-8   Thorsten Bonow <thorsten.bonow@post.rwth-aachen.de>
+
+       * icq2tcp.c (main): Assign command line arguments to variables
+       only after checking if correct number of them is passed to the
+       program. Cygwin segfaults when none existing arguments are
+       assigned.
+
+2001-09-29  Steve Youngs  <youngs@xemacs.org>
+
+       * Version 0.2.17 released.
+
+2001-09-28  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-do-info): Prompt for a group to add a new user
+       to. 
+
+2001-09-27  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-do-info): Check for blank or invalid nick-names
+       for 'eicq-add-user'.  Prompt for an alternative.
+
+2001-09-25  Erik Arneson  <erik@aarg.net>
+
+       * eicq-wharf.el (eicq-wharf-change-messages): If the Wharf buffer
+       hasn't been created, don't try to do anything.
+
+2001-09-26  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-status-bin): Send correct packet for web-aware so
+       'eicq-user-meta-web-aware' works.
+
+2001-09-25  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-connect): Test for 'open' not 'run' in
+       process-status because it is a network stream.
+       (eicq-do-kicked-out): Don't try to auto-reconnect if
+       'eicq-delete-offline-messages-flag' is set to "ask".
+       (eicq-add-user): New.
+       (eicq-add-user-p): New.
+       (eicq-new-buddy): New.
+       (eicq-new-uin): New.
+       (eicq-do-info): Handle doing a 'eicq-add-user'.
+       (eicq-add-new-user-to-buddy-buffer): New.
+       (eicq-do-search-end): Use it.
+
+2001-09-23  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-pack-search-by-uin): Changed to a defconst.
+       (eicq-search-by-uin): New.
+
+2001-09-18  Erik Arneson  <erik@aarg.net>
+
+       * eicq.el (eicq-connect): Removed check for `eicq-bridge-port', as
+       some folks might want to set variable before running
+       `eicq-connect'.  Besides, we're already checking
+       `eicq-bridge-local-p'.
+       (eicq-disconnect): Check to see if a symbol indicates a live
+       buffer before killing it.
+
+2001-09-19  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-logout): Reset counters in EicqWharf to zero.
+       (eicq-logout): Test for EicqWharf before trying to reset it.
+
+2001-09-17  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-logout): Do a 'eicq-world-update' and
+       'eicq-send-contact-list' to reset the buddy buffer to it's
+       "pre-logged-in-state". 
+
+2001-09-16  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-show-window): Emergency fix - I left out a
+       'select-frame'. 
+       (eicq-disconnect): Emergency fix - Uncomment something I'd
+       commented out for debugging purposes.
+       (eicq-do-kicked-out): Test for 'eicq-user-password', don't attempt
+       auto-reconnect if it's nil.
+
+2001-09-15  Steve Youngs  <youngs@xemacs.org>
+
+       * Version 0.2.16 released.
+
+       * README: Add comments about EicqWharf and starting Eicq in a new
+       frame. 
+
+       * eicq.el (eicq-save-log-on-exit-p): New.
+       (eicq-disconnect): Use 'eicq-save-log-on-exit-p'.  And don't
+       prompt to save the buffer, just kill it.
+       (eicq-disconnect): Only delete the wharf frame if it's loaded.
+       (eicq-show-window): Create the wharf frame after all the other
+       Eicq buffers have been created, and then only if it's needed.
+       (eicq-do-meta-user-general): A little nicer output.
+
+2001-09-13  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el: Autoload 'eicq-wharf-new-frame' to kill off a
+       byte-compile warning.
+       (eicq-idle-reply): Set 'eicq-auto-reply-p' so we
+       auto-online when we should.
+
+2001-09-11  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-auto-reply): Use a modified subset of
+       'eicq-send-message-helper' so the outgoing message doesn't get
+       logged.  Instead use 'eicq-log-system "Automatic response sent."'
+       (eicq-idle-reply): Ditto.
+
+2001-09-07  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-do-kicked-out): Attempt auto-reconnect.
+
+2001-09-02  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq-report.el: Require 'message. 
+
+       * eicq.el (eicq-face-online): Remove background colour to make it
+       look better for light backgrounds.
+       (eicq-face-away): Ditto.
+       (eicq-face-occ): Ditto.
+       (eicq-face-dnd): Ditto.
+       (eicq-face-ffc): Ditto.
+       (eicq-face-na): Ditto.
+       (eicq-face-offline): Ditto.
+       (eicq-face-log-unread): Ditto.
+       (eicq-face-log-read): Ditto.
+       (eicq-auto-response-messages-p): New.
+       (eicq-do-message-helper): Use 'eicq-auto-response-messages-p'.
+
+       * eicq-wharf.el (eicq-wharf-default-face): Remove background
+       colour to make it look better for light backgrounds.
+
+2001-08-18  Steve Youngs  <youngs@xemacs.org>
+
+       * README: Minor updates.
+
+       * Makefile (SOURCES): Add eicq-wharf.el.
+
+       * eicq.el (eicq-show-window): Fire up the EicqWharf frame.
+       (eicq-disconnect): Kill the EicqWharf frame if present.
+
+       * eicq-wharf.el (eicq-wharf-frame-use-p): New.
+
+2001-08-18  Erik Arneson  <erik@aarg.net>
+
+       * eicq-wharf.el: New file.
+
+2001-08-17  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-buddy-show-buffer): Remove the text "*** Bottom ***".
+       (eicq-sound-directory): Use 'locate-data-directory'.
+       (eicq-read-message-hook): New.
+       (eicq-system-message-hook): New.
+       (eicq-do-message-hook): Rename to 'eicq-new-message-hook'.
+       (eicq-do-status-update-hook): Rename to 'eicq-status-update-hook'.
+       (eicq-do-system-message): Use 'eicq-system-message-hook'.
+       (eicq-log-mark-read): Use 'eicq-read-message-hook' if called
+       interactively. 
+       (eicq-idle-reply-away): New.
+       (eicq-idle-reply-na): New.
+       (eicq-status-idle-reply): New.
+       (eicq-idle-reply): New.
+       (eicq-do-message-helper): Use 'eicq-idle-reply'.
+       (eicq-do-info-ext): Hopefully, nicer layout for query results.
+       (eicq-do-info): Ditto.
+
+       * eicq-toolbar.el (eicq-icon-directory): Use
+       'locate-data-directory. 
+
+       * eicq-report.el: Require shadow and font-lock.
+       (eicq-report-bug-send-init): New.
+       (eicq-report-debug): Include checking eicq-report.el for changed
+       variables.
+       (eicq-prepare-report): Include load-path shadows, list of
+       installed XEmacs Packages and optionally the contents of the 
+       user's init.el.
+       (eicq-report-post-hook): Force font-locking so the prompt for
+       a Subject isn't hidden with font-locking messages.
+       
+
+2001-08-11  Steve Youngs  <youngs@xemacs.org>
+
+       * Version 0.2.15 released.
+
+       * eicq-toolbar.el (eicq-use-toolbar): Change to customize group
+       'eicq-interface'.
+
+       * eicq.el (eicq-start-in-new-frame): Change to customize group
+       'eicq-interface'.
+
+       * INSTALL:  Add comments about building on Solaris.
+
+2001-08-11  Jack Twilley  <jmt@tbe.net>
+
+       * icq2tcp.c (main): Use 'perror' instead of 'herror' for Solaris
+       builds.
+
+       * Makefile: Make necessary changes for Solaris builds.
+       
+2001-08-10  Erik Arneson  <erik@aarg.net>
+
+       * eicq.el (eicq-show-window): Minor fix.  Changed `framep' to
+       `frame-live-p' just in case the active frame has been destroyed
+       since we last used it.
+
+2001-08-11  Steve Youngs  <youngs@xemacs.org>
+
+       * README: Change URLs to eicq.sf.net.
+       * TODO: Ditto.
+       * eicq-convert.el: Ditto.
+       * eicq.el: Ditto.
+       * icq2tcp.c: Ditto.
+
+2001-08-10  Erik Arneson  <erik@aarg.net>
+
+       * eicq.el (eicq-local-bridge-p): New customize option.  When
+       non-nil, Eicq will try to use a remote bridge.  This should be
+       safer than trying to second guess ourselves by looking at various
+       variables.
+       (eicq-connect): Second try.  This seems to work for both remote
+       and local bridges very nicely.
+
+2001-08-10  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-connect): Revert Erik's patch.
+       (eicq-auto-reply-p): New variable, if non-nil the auto-response
+       message won't automatically reset state to "online".
+       (eicq-do-message-helper): Use 'eicq-auto-reply-p'.
+       (eicq-send-message-helper): Ditto.
+       (eicq-auto-reply-away): Include shameless plug in auto-reply.
+       (eicq-auto-reply-occ): Ditto.
+       (eicq-auto-reply-dnd): Ditto.
+       (eicq-auto-reply-na): Ditto.
+
+2001-08-09  Erik Arneson  <erik@aarg.net>
+
+       * eicq.el (eicq-frame): New variable.  Keep track of EICQ's frame.
+       (eicq-show-window): Will now make sure that EICQ is redisplayed in
+       its preferred frame.
+       (eicq-disconnect): Reset the eicq-frame variable on disconnect,
+       when all of the buffers are killed and stuff.  If
+       `eicq-start-in-new-frame' is non-NIL, it will delete the frame
+       that Eicq created during eicq-show-window.
+       (eicq-start-in-new-frame): New customize option.  If non-NIL, Eicq
+       will start in its own frame.
+
+2001-08-09  Steve Youngs  <youngs@xemacs.org>
+
+       * Makefile (CC): Change to 'gcc'.
+
+       * eicq.el (eicq-do-message-helper): Auto-response messages
+       now work.
+
+2001-08-08  Erik Arneson  <erik@aarg.net>
+
+       * eicq.el (eicq-connect): Better support for remote icq2tcp
+       bridges.
+
+       * Makefile ($(BIN)): Fixed to compile icq2tcp.c instead of the C++
+       version.  Woohoo!
+
+       * icq2tcp.c: Replacement for icq2tcp.cc.  It's a direct port to C,
+       and now should compile pretty cleanly on FreeBSD and Linux.
+
+       * icq2tcp.cc: Removed.  Obsolete!  Kaput!
+
+2001-08-07  Erik Arneson  <erik@aarg.net>
+
+       * Makefile (INFO_FILES): Changed.
+       ($(BIN)): New target to accurately reflect dependancies.
+       (.texi.info): Ditto!
+
+2001-08-07  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq-convert.el (eicq-import-from-licq): Autoload it.
+       Use '====' to take advantage of outline regexp of world-mode.
+       (eicq-import-from-micq): Ditto.
+
+2001-08-06  Erik Arneson  <erik@aarg.net>
+
+       * eicq-convert.el (eicq-import-from-micq): Converts an MICQ
+       configuration to an EICQ 'world' file.  I tried to get less
+       carried away -- this one has fewer lines!  Imports these users
+       into the `micq' group.
+       (eicq-import-from-licq): Users are imported into the `licq' group.
+
+2001-08-07  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq-convert.el: require 'eicq.
+       (eicq-import-from-licq): Use 'eicq-world-rc-filename' in case 
+       the user has their world file in a different place from the default.
+       Remove 'buf' variable, it's not used. Did somebody get a little 
+       carried away? :-)
+
+       * Makefile (SOURCES): Add eicq-convert.el
+
+2001-08-06  Erik Arneson  <erik@aarg.net>
+
+       * eicq-convert.el: New File.
+       (eicq-import-from-licq): New.  Converts an LICQ configuration to
+       an EICQ 'world' file.
+
+2001-08-02  Thorsten Bonow  <thorsten.bonow@post.rwth-aachen.de>
+
+       * Makefile: Add program locations/path for Windows/Cygwin.
+
+       * eicq-user-install.sh: ditto.
+
+       * INSTALL: Add Windows/Cygwin Installation instructions.
+
+2001-07-22  Steve Youngs  <youngs@xemacs.org>
+
+       * Version 0.2.14 released.
+
+       * eicq-toolbar.el (eicq-help-icon): New.
+       (eicq-toolbar-help): New.
+       (eicq-log-toolbar): Use them.
+
+       * eicq.texi: Still not finished, but some progress has been
+       made. :-)
+
+2001-07-19  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-disconnect): Update doc string.
+
+2001-07-16  Steve Youngs  <youngs@xemacs.org>
+
+       * Makefile (BIN): Rename udp2tcp to icq2tcp.
+       (BIN_DIR): Change to lib-src.
+       (STAGING): New.
+       (BIN_STAGING): New.
+       (DATA_STAGING): New.
+       (INFO_STAGING): New.
+       (LISP_STAGING): New.
+       (TAR): New.
+       (TAR_FLAGS): New.
+       (VER): New.
+       (pkg): New target.
+
+       * udp2tcp.cc: Removed.
+
+       * icq2tcp.cc: New file, at this stage it is a direct copy
+       of udp2tcp.cc.
+
+       * eicq.el: Use icq2tcp throughout instead of udp2tcp.
+       (eicq-bridge-filename): Don't use a path, XEmacs can find it providing
+       it's in the XEmacs exec path.
+       
+
+2001-06-06  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq-report.el (eicq-report-debug): New.
+       (eicq-prepare-report): Use it.
+
+2001-06-05  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-version): Add optional arg so you can insert the
+       version string at point.  Autoload it.
+       (eicq-user-meta-web-aware): Type boolean.
+       (eicq-user-meta-hide-ip): Ditto.
+       (eicq-user-meta-authorization): Ditto.
+       (eicq-log-info-mark): Ditto.
+       (eicq-log-buddy-status-mark): Ditto.
+       (eicq-log-buddy-message-mark): Ditto.
+       (eicq-log-outgoing-mark): Ditto.
+       (eicq-log-error-mark): Ditto.
+       (eicq-log-debug-mark): Ditto.
+       (eicq-log-system-mark): Ditto.
+       (eicq-buddy-status-color-hint-flag): Ditto.
+
+       Most user variables moved to take advantage of new bug-report
+       code.
+
+2001-06-03  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-user-meta-birth-year): Format for this variable
+       should be YY, update doc accordingly.
+
+2001-05-31  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-pack-keep-alive-1): Remove - obsolete.
+       (eicq-pack-info-request): Ditto.
+       (eicq-pack-info-ext-request): Ditto.
+       (eicq-pack-update-info): Ditto.
+       (eicq-pack-update-info-ext): Ditto.
+       
+2001-05-20  Steve Youngs  <youngs@xemacs.org>
+
+       * Makefile (superupgrade): Make sure owner/group is set correctly
+       in source tree.
+
+       * eicq.texi: Finally started to write this.  Not finished yet,
+       but maybe by the end of the weekend.
+
+       * eicq.el (eicq-log-buddy-message): Switch to log buffer for smileys.
+       (eicq-auto-away-timeout-set): Use a 2nd itimer so auto na works 
+       properly.
+
+       * etc/eicq/world: Updated.  Somehow it got overwritten with an old
+       version of itself.
+
+2001-05-07  Steve Youngs  <youngs@xemacs.org>
+
+       * Makefile (superupgrade): New target for me only.
+
+       * eicq.el (eicq-buddy-show-buffer): Remove "*** Contacts ***".
+       (eicq-auto-away-timeout-set): Typo.
+       (eicq-interface): New customize group.
+       (eicq-hide-window): Add eicq-status-window.
+
+2001-05-05  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-status-show-buffer): Change name of buffer to "*Status*".
+
+2001-05-02  Steve Youngs  <youngs@xemacs.org>
+
+       * Makefile (AUTO_PRELOADS): New.
+
+2001-04-28  Steve Youngs  <youngs@xemacs.org>
+
+       * Version 0.2.13 released.
+
+       * eicq.el (eicq-message-sound): Removed, put into alist.
+       (eicq-chat-sound): Ditto.
+       (eicq-url-sound): Ditto.
+       (eicq-buddy-sound): Ditto.
+       (eicq-auth-sound): Ditto.
+       (eicq-emailx-sound): Ditto.
+       (eicq-pager-sound): Ditto.
+       (eicq-sound-alist): New.
+       (eicq-use-sound-flag): New.
+       (eicq-do-message-helper): Use 'eicq-sound-alist', 'eicq-use-sound-flag'.
+       (eicq-do-online): Ditto.
+       (eicq-log-buddy-message): Run 'smiley-buffer' and 'goto-address'.
+
+
+2001-04-22  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-buddy-show-buffer): Rename and rearrange status widgets.
+       (eicq-status-window-height): New.
+       (eicq-status-buffer): New.
+       (eicq-status-show-buffer): New.
+       (eicq-show-window): Show the status buffer as well.
+       (eicq-disconnect): Kill the status buffer.
+       (eicq-switch-to-buddy-buffer): New.
+
+       * eicq-toolbar.el: Reduced the number of tools on the toolbar.
+
+2001-04-21  Steve Youngs  <youngs@xemacs.org>
+
+       * Version 0.2.12 released.
+
+       * eicq-toolbar.el (eicq-toolbar-disconnect): Do 'eicq-logout' before
+       'eicq-disconnect'.
+       (eicq-buddy-toolbar): Remove.  Use the same toolbar for both the 
+       buddy and log buffers.
+       (eicq-install-buddy-toolbar): Use the log toolbar.
+
+       * eicq.el (eicq-do-login-confirm): Run 'eicq-show-window'.
+       (eicq-disconnect): Kill the Eicq buffers.
+       (eicq-log-mode): Load both the log menu and the buddy menu.
+       (eicq-buddy-mode): Ditto.
+
+2001-04-01  Steve Youngs  <youngs@xemacs.org>
+
+       * README: Added section about submitting patches.
+
+2001-03-21  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-log-next-unread): Make it interactive.
+       (eicq-log-previous-unread): Ditto.
+
+2001-03-19  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-log-mode-map): 'n' & 'p' are now next and previous
+       Unread messages.  'N' & 'P' are for next and previous message.  
+       Mark unread has been moved to 'v'.
+       (eicq-buddy-show-buffer): Add widgets for changing status via the 
+       buddy buffer.
+
+2001-03-18  Jack Twilley  <jmt@tbe.net>
+
+       * eicq.el (eicq-log-next-unread): New.
+       (eicq-log-previous-unread): New.
+
+2001-03-12  Jack Twilley  <jmt@tbe.net>
+
+       * eicq.el (eicq-user-auto-away-p): New variable.
+       (eicq-auto-away-timeout-set): Use new variable, change docstring.
+       Reordered away tests.   
+       (eicq-send-message-helper): Use new variable.
+       (eicq-change-status): Use new variable.
+       (eicq-log-*-mark): New variables.
+       (eicq-log-*): Use new variables.
+       (eicq-log-buffer-position-flag): New variable.
+       (eicq-log-entry-re): New variable.
+       (eicq-log): Use new variables, change docstring.
+       (eicq-buddy-update-status): Only display status packet if status
+       has changed.
+
+2001-03-09  Steve Youngs  <youngs@xemacs.org>
+
+       * Version 0.2.11 released.
+
+       * eicq.el (eicq-blurb): Update.
+       (eicq-do-offline-message): Remove require 'timezone and move
+       it to top of file.
+
+       * eicq-report.el (eicq-prepare-report): New.
+       (reporter-version): Remove.
+       (vars): Ditto.
+       (reporter-confirm-p): Ditto.
+       (reporter-package-abbrev): Ditto.
+       (eicq-report-other-vars): Ditto.
+       (eicq-report-avoid-vars): Ditto.
+       (eicq-report-get-versions): Ditto.
+       (eicq-report-get-user-vars): Ditto.
+       (eicq-gnus-submit-report): Ditto.
+       (eicq-report-bug): Don't use reporter.el.
+
+       * eicq-toolbar.el (eicq-icon-directory): Make it customizable.
+
+2001-03-06  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el: (eicq-delete-offline-messages-flag): Change default to 'ask.
+
+2001-03-06  Steve Youngs  <youngs@xemacs.org>
+
+       * Version 0.2.10 released.
+
+       * eicq.el: Re-arrange variables and constants for a clean build.
+       (eicq-version): Increment.
+       (eicq-bridge-filename): Change default to /usr/local/bin/udp2tcp
+       (eicq-browse-homepage): Autoload it.
+
+       * eicq-user-install.sh (RCFILE): Change default to
+       /usr/local/lib/xemacs/site-packages/etc/eicq/world.
+
+       * eicq-report.el: Update doc strings.
+
+       * eicq-toolbar.el: Ditto.
+       (eicq-icon-directory): Change default to
+       /usr/local/lib/xemacs/site-packages/etc/eicq/
+
+       * infohack: New file.
+
+       * README: Update URL.
+
+       * INSTALL: Updated to reflect not being an XEmacs Package.
+
+       * Makefile: Complete re-write to use standard 'make', 'make install'.
+
+2001-03-02  Steve Youngs  <youngs@xemacs.org>
+
+       * Makefile: Re-shuffle the order of the variables so everything
+       gets installed properly.  This supercedes the change I made earlier.
+
+       * INSTALL: Update.
+
+       * NEWS: Ditto.
+
+       * TODO: Ditto.
+
+       * Makefile (ELCS): Add eicq-report.elc.
+       (include ../../XEmacs.rules): Move to below other variables so
+       everything gets installed properly.
+
+       * eicq-toolbar.el: Add require 'eicq.
+
+2001-03-01  Steve Youngs  <youngs@xemacs.org>
+
+       * Makefile (REQUIRES): Add eicq, gnus.
+
+       * eicq.el (eicq-blurb): New
+       (eval-when-compile): Remove require 'eicq-report.
+
+       * udp2tcp.cc (main): Update URL.
+
+2001-02-28  Ben Wing  <ben@xemacs.org>
+
+       * udp2tcp.cc (main): Conditionalize change to third arg to accept
+       on __CYGWIN__, so that all other systems keep size_t -- simply
+       changing the arg makes this not compile under Linux.
+
+2001-02-24  Ben Wing  <ben@xemacs.org>
+
+       * Makefile (STRIP):
+       * Makefile (EXTRA_SOURCES):
+       * Makefile (EXTRA_OBJS):
+       Fix udp2tcp compilation to work under MS Windows.
+       
+       * udp2tcp.cc (main):
+       Emergency fixes so it compiles. (change bzero to memset; fix type
+       of third arg to accept)
+
+2001-03-01  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-main-menu): Capitalise entries.
+       (eicq-log-menu): Ditto.
+
+2001-02-21  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el: Update all doc strings.
+       (eicq-email-author): Move to eicq-report.el
+
+       * eicq-report.el: New file.
+
+2001-01-25  Steve Youngs  <youngs@xemacs.org>
+
+       * version 0.2.8 released - XEmacs package 1.03
+
+       * eicq.el (eicq-buddy-view): Remove :set 'eicq-buddy-view-set.
+       (eicq-version): Increment.
+
+       * eicq.texi (VERSION): Ditto.
+
+2000-11-27  Steve Youngs  <youngs@xemacs.org>
+
+       * Makefile (CFLAGS): Add -static so people that use a different
+       compiler to me wont have problems.
+
+2000-11-14  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el: Doc fix.
+
+2000-10-23  Steve Youngs  <youngs@xemacs.org>
+
+       * version 0.2.7 released - XEmacs package 1.02
+
+       * *: Update my email address.
+
+2000-10-05  Martin Buchholz  <martin@xemacs.org>
+
+       * *: Mega typo fix.
+
+2000-08-22  Steve Youngs  <youngs@xemacs.org>
+
+       * Makefile (EXTRA_OBJS): New variable.
+
+2000-08-16  Steve Youngs  <youngs@xemacs.org>
+
+       * version 0.2.6 released - XEmacs package 1.01
+
+       * etc/world: added info about adding your own UIN
+
+       * INSTALL: ditto
+
+       * INSTALL: fixed typo
+
+2000-08-15  Steve Youngs  <youngs@xemacs.org>
+
+       * verion 0.2.5 released - XEmacs package 1.00
+
+       * package-info-in: changed description
+
+2000-07-18  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.texi: new file
+
+       * INSTALL: total re-write for XEmacs packages
+
+       * package-info.in: new file
+
+       * eicq-toolbar.el: updated license
+
+       * eicq.el: updated license
+
+       * Makefile: total re-write for XEmacs packages
+
+2000-06-26  Steve Youngs  <youngs@xemacs.org>
+
+       * README: moved install stuff to INSTALL
+
+       * INSTALL: new file
+
+       * world: my UIN was wrong :-(  fixed
+
+2000-06-07  Steve Youngs  <youngs@xemacs.org>
+
+       * version 0.2.4 released
+
+       * README: updated install instructions
+
+2000-06-06  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-buddy-mode-hook): add-hook 
+       eicq-install-buddy-toolbar
+       (eicq-log-mode-hook): add-hook eicq-install-log-toolbar
+       (eicq-email-author): change address
+
+       * Makefile: updated for a more "system-wide" install
+
+       * eicq-user-install.sh: New file
+
+       * eicq-toolbar.el: New file
+
+2000-06-05  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-do-message-helper): added new sounds
+       (eicq-do-message-helper): pager now decodes message
+       (eicq-auth-sound): New variable
+       (eicq-emailx-sound): New variable
+       (eicq-pager-sound): New variable
+       (eicq-global-map-set): new key bindings added to eicq-buddy-map 
+       and eicq-log-map 
+
+2000-06-01  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el (eicq-main-menu): "Update Meta Info" pointed to
+       the wrong place.  Now points to eicq-update-meta-info
+
+2000-05-30  Steve Youngs  <youngs@xemacs.org>
+
+       * version 0.2.3 released
+
+2000-05-13  Steve Youngs  <youngs@xemacs.org>
+
+       * eicq.el
+       (eicq-sound): New customization group
+       (eicq-sound-directory): New variable
+       (eicq-message-sound): New variable
+       (eicq-chat-sound): New variable
+       (eicq-url-sound): New variable
+       (eicq-buddy-sound): New variable
+
+1999-08-12  Stephen Tse  <stephent@sfu.ca>
+
+       * version 0.2.2 released
+
+       * eicq.el
+       (eicq-world-update): extent for alias (from Erik)
+       (eicq-log-buddy-url): new function, extent for url (from Erik)  
+       (eicq-url-map): new variable
+       (eicq-alias-map): new variable
+       (eicq-send-message-via-mouse): new function
+       (eicq-send-message-alias-here-via-mouse): removed
+       (world-mode): new mode and world-* helper
+       (world-find): new function
+       (world-sort): new function
+       (eicq-change-user): new function
+       (eicq-buddy-view-connected): update eicq-buddy-view
+       (eicq-status-bin): zero-padded
+       (eicq-bridge-buffer): store buffer id instead of name
+       (eicq-hide-window): new function
+       (eicq-email-author): carbon-copy to mailing list
+
+       * world: add sample records     
+
+1999-07-10  Stephen Tse  <stephent@sfu.ca>
+
+       * version 0.2.1 released.
+
+       * eicq.el
+       (eicq-do-kicked-out): remove relogin
+       (eicq-log-around): fixed to include first line
+       (eicq-do-message-helper): display authorization message
+       (eicq-bridge-mode): fixed kill-buffer-query-functions
+
+1999-06-29  Stephen Tse  <stephent@sfu.ca>
+
+       * version 0.2.0 released.
+       - ICQ version 5 protocol
+       - outgoing delay queue and resent queue
+       - meta user info query and update
+
+       * eicq.el
+       (eicq-log-mark-*): mark all log in a region
+       (eicq-keep-alive-stop): use start-itimer
+       (eicq-pack-contact-list): use smaller packet
+       (eicq-do-message-helper): receive contact list transfer
+       (eicq-register-new-user): new function
+       (eicq-do-info-ext): fixed age bug
+       (eicq-world-update): RC file not closed if current or modified
+       (eicq-auto-away-timeout-set): added auto-na
+       (eicq-bin-alias): optional from
+       (eicq-alias-around): cleaned up
+       (eicq-log-around): new function
+       (eicq-send-message): encode only outgoing part
+       (eicq-forward-message-around): new function
+       (eicq-change-status): allow only valid statues
+       (eicq-logout): clear buddy buffer when offline
+       (eicq-change-status): change only if different
+       (eicq-valid-packet-p): integrated into eicq-do
+       (eicq-ack-alist): removed
+       (eicq-ack): integrated into eicq-do
+       (eicq-pack-login): fixed initial status
+       (eicq-relogin): fixed relogin initial status
+       (eicq-query-info): skip nil local info
+       
+       - more debugging and profiling counters
+       eicq-dropped-packet-counter
+       eicq-resend-packet-counter
+       eicq-auto-relogin-counter
+
+       * README: split into readme.developer
+       * README.developer: new
+       * udp2tcp.cc: protocol version 5
+
+1999-06-16  Stephen Tse  <stephent@sfu.ca>
+
+       * version 0.1.3 released.
+
+       * eicq.el
+       (eicq-spliter): new function
+       (eicq-send-message): send long messages
+       (eicq-do-info): fixed authorization check
+       (eicq-pack-update-info): new function
+       (eicq-do-search-end): new function
+       (eicq-auto-na-timeout-set): new function
+       (eicq-current-seq-num): follow micq, start from 0 instead of 1
+       (eicq-do-kicked-out): graceful relogin
+       (eicq-login): login only when offline
+       (eicq-buddy-getf): new function
+       (eicq-buddy-putf): new function
+       (eicq-int-byte): new function
+       (eicq-network-separator): eicq-trimmed-packet
+       (eicq-pack-contact-list): fixed random uin
+       (eicq-network-filter): fixed bug in checking validity of packets
+       (eicq-do-message-hook): new variable
+       (eicq-do-status-update-hook): new variable
+       (eicq-hex-bin): downcase uppercase
+       (eicq-process-alias-input): new function
+
+       : select
+       (eicq-group-select-aliases)
+       (eicq-select-alias-around)
+       (eicq-buddy-select-all-in-view)
+       (eicq-buddy-select-all-in-view-by-status)
+       (eicq-buddy-select-all-in-view-by-regexp)
+       (eicq-buddy-selected-in-view)
+       (eicq-select-alias-here)
+
+       : use length prefix instead of delimiting magic string
+       - (eicq-redo-hex)
+       - (eicq-network-filter)
+       - (eicq-network-separator)
+       - (eicq-send)
+       - (eicq-magic-string)
+
+       * README
+       : updated for new resource file
+       : fixed wrong assumption about eicq-pack-contact-list
+
+       * udp2tcp.cc (debug_socket):
+       : use length prefix instead of delimiting magic string
+       : remove usleep 
+
+1999-06-01  Stephen Tse  <stephent@sfu.ca>
+       
+       * version 0.1.2 released.
+
+       * eicq.el:
+       - add `encode/decode-coding-string'
+
+1999-05-22  Stephen Tse  <stephent@sfu.ca>
+
+       * eicq.el: 
+       (eicq-send-contact-list): make interactive
+       (eicq-main-menu): add "Resend contact list"
+
+1999-05-18  Stephen Tse  <stephent@sfu.ca>
+
+       * Makefile: brand new from Erik Arneson <erik@mind.net> 
+
+       * README:
+       - change installation steps for new Makefile
+       - mention mailing list and `eicq-log-new-file' in tips
+
+       * eicq.el: merge patches from Erik Arneson <erik@mind.net>
+       - add confirmation for sending blank message/url
+       - `eicq-send-message-alias-here-via-mouse'
+       - `browse-url-at-point' and other key bindings
+
+       * eicq.el (eicq-message-types): one byte instead of two
+
+1999-05-12  Stephen Tse  <stephent@sfu.ca>
+
+       * version 0.1.1 released.
+
+1999-05-12  Stephen Tse  <stephent@sfu.ca>
+
+       * version 0.1 released.
+       
diff --git a/ChangeLog.d/ChangeLog-0.6.Eicq b/ChangeLog.d/ChangeLog-0.6.Eicq
new file mode 100644 (file)
index 0000000..b5d2f60
--- /dev/null
@@ -0,0 +1,503 @@
+# do not edit -- automatically generated by arch changelog
+# non-id: automatic-ChangeLog--steve@eicq.org--2004/eicq--main--0.6
+#
+
+2004-11-22 21:56:38 GMT        Steve Youngs <steve@eicq.org>   patch-15
+
+    Summary:
+      Minor fix to donation code
+    Revision:
+      eicq--main--0.6--patch-15
+
+    * eicq.el (eicq-donation): Test for featurep 'png and 'jpeg before trying
+      to display the glyphs.
+    
+
+    modified files:
+     eicq.el
+
+
+2004-11-22 16:30:22 GMT        Steve Youngs <steve@eicq.org>   patch-14
+
+    Summary:
+      Attempt to generate some donations
+    Revision:
+      eicq--main--0.6--patch-14
+
+    * eicq.el (eicq-donation-notice): New.  Shameless appeal for cash.
+    (eicq-paypal-glyph): New.  A button to use in the "donation" buffer.
+    (eicq-maybe-later-glyph): Ditto.
+    (eicq-make-donation): New.  For when the user takes pity on us and
+    decides to donate to the project.
+    (eicq-no-donation): New.  For when they don't.
+    (eicq-donation-map): New.  Keymap for the extents in the "donation"
+    buffer. 
+    (eicq-nodonation-map): Ditto.
+    (eicq-donation): New.  Function to create the "donation" buffer.
+    
+    * eicq-menu.el (eicq-main-menu): Add a menu item for `eicq-donation'.
+    
+
+    modified files:
+     eicq-menu.el eicq.el
+
+
+2004-11-21 21:17:55 GMT        Steve Youngs <steve@eicq.org>   patch-13
+
+    Summary:
+      Bitrot removal (20.4 compat code... sheesh)
+    Revision:
+      eicq--main--0.6--patch-13
+
+    * eicq.el (encode-coding-string): Removed.  Compatibility with
+      20.4... you've gotta be kidding!
+      (decode-coding-string): Ditto.
+    
+
+    modified files:
+     eicq.el
+
+
+2004-11-15 15:35:58 GMT        Steve Youngs <steve@eicq.org>   patch-12
+
+    Summary:
+      Minor build fix.
+    Revision:
+      eicq--main--0.6--patch-12
+
+    * eicq.el (eicq-pack-login-a): Removed.  Left over crud from
+      eicq-v8proto.el. 
+      (eicq-pack-login-b): Ditto.
+    
+
+    modified files:
+     eicq.el
+
+
+2004-11-15 15:32:18 GMT        Steve Youngs <steve@eicq.org>   patch-11
+
+    Summary:
+      require eicq-v8 instead of eicq-v8proto
+    Revision:
+      eicq--main--0.6--patch-11
+
+
+    modified files:
+     eicq-comm.el
+
+
+2004-11-15 15:28:14 GMT        Steve Youngs <steve@eicq.org>   patch-10
+
+    Summary:
+      Final sf.net -> eicq.org renaming.
+    Revision:
+      eicq--main--0.6--patch-10
+
+    * .arch-inventory: Make eicq-version.texi precious
+    
+    * INSTALL: Update the URLs mentioned and slightly re-word it.
+    
+    * README: Ditto.
+    
+    * TODO: Update URLs
+    
+    * eicq.texi: Ditto.
+      Include generated file eicq-version.texi
+    
+    * Makefile (texinfo): Add eicq-version.texi
+      (eicq-version.el): Test to see if tla is present and
+      executable before using it to generate version info.
+      (eicq-version.texi): New.  Generated file containing version
+      info for eicq.info.
+      (distclean): Remove eicq-version.texi too.
+      (.PHONY): Add eicq-version.texi.
+    
+    * eicq-v8proto.el: Removed.  Obsolete, replaced by eicq-v8.el
+     
+    
+    This should be the last of the "sf.net -> eicq.org" renaming.  There is
+    also some minor updates to INSTALL/README... slight re-wording and
+    re-organisation.
+    
+    The version string that goes into eicq.info is now generated at build
+    time in the same manner as it is for the lisp.
+
+    removed files:
+     .arch-ids/eicq-v8proto.el.id eicq-v8proto.el
+
+    modified files:
+     .arch-inventory INSTALL Makefile README TODO eicq.texi
+
+
+2004-11-15 05:49:30 GMT        Steve Youngs <steve@eicq.org>   patch-9
+
+    Summary:
+      Fix `eicq-update-world'
+    Revision:
+      eicq--main--0.6--patch-9
+
+    * eicq-world.el (eicq-world-update): Convert UINs to numbers.
+    (world-mode): Remove some old crud about highlighting dates.
+    Don't put it into outline-mode.
+    
+    `world-mode' used to put the rc file (where the contact list is kept)
+    into outline-mode, but for some reason it is throwing a `keymapp nil'
+    error.  So I've disabled that "feature" for the time being.  I've added a
+    "FIXME" comment to eicq-world.el so we can come back to it some time in
+    the future.
+    
+
+    modified files:
+     eicq-world.el
+
+
+2004-11-15 04:47:05 GMT        Steve Youngs <steve@eicq.org>   patch-8
+
+    Summary:
+      Build fixes.
+    Revision:
+      eicq--main--0.6--patch-8
+
+    * eicq-v8.el (eicq-v8-snac-srv-recv-msg): Remove unused variable
+      `test-tlvs'. 
+    
+    * eicq.el: Bump version in file header.
+      (require): eicq-v8 instead of eicq-v8proto.
+      (eicq-login): Remove argument `password'.
+    
+    Remove all of the now useless CVS keyword headers from all files.
+    
+    This patch returns us back to the land of clean builds.
+
+    modified files:
+     eicq-buddy.el eicq-comm.el eicq-convert.el eicq-log.el
+     eicq-menu.el eicq-meta.el eicq-report.el eicq-setup.el
+     eicq-status.el eicq-toolbar.el eicq-v8.el eicq-v8proto.el
+     eicq-wharf.el eicq-world.el eicq.el eicq.texi
+
+
+2004-11-15 02:35:19 GMT        Steve Youngs <steve@eicq.org>   patch-7
+
+    Summary:
+      Update the bug reporter
+    Revision:
+      eicq--main--0.6--patch-7
+
+    * eicq-report.el (eicq-bug-address): Use eicq-bugs@eicq.org as the
+      address to send bug reports to.
+      (eicq-report-pre-hook): Don't include the version string in the bug
+      report subject header because it is way too long now.
+      (eicq-prepare-report): Put the list of altered Eicq variables at the
+      top of the report where they can be seen easily.
+      (eicq-email-salutations): Typo fix.
+      (eicq-prepare-email-author): Update Cc address to be
+      eicq-users@eicq.org.
+      Don't put the version string in the subject header because it is too
+      long now.  Put it in the body instead.
+      (eicq-report-debug): This doesn't need to be interactive.
+    
+
+    modified files:
+     eicq-report.el
+
+
+2004-11-14 02:03:57 GMT        Steve Youngs <steve@eicq.org>   patch-6
+
+    Summary:
+      Build fix -- Work around broken smiley.el 
+    Revision:
+      eicq--main--0.6--patch-6
+
+    * Makefile (PRELOADS): ignore `executable-find'.
+    
+    The "XEmacs-unfriendly" version of smiley.el from gnus.org requires
+    executable-find via nnheader.el via about 6 other libs via
+    gnus-encrypt.el. 
+    
+    The "XEmacs-friendly" version of smiley.el, the one that is in the XEmacs
+    package version of Gnus, the superior-to-the-gnu-version by Wes Hardaker,
+    does not require nnheader and so doesn't need executable-find.
+    
+    This patch makes it possible for the people with the broken smiley.el to
+    build Eicq.
+    
+
+    modified files:
+     Makefile
+
+
+2004-11-12 03:53:23 GMT        Steve Youngs <steve@eicq.org>   patch-5
+
+    Summary:
+      Switch to a tla style version string.
+    Revision:
+      eicq--main--0.6--patch-5
+
+    * Makefile (VER): Bump to 0.6
+    (eicq-version.el): New.
+    (all): Use it.
+    (version): Convenience target - alias for `eicq-version.el'.
+    (distclean): Also remove eicq-version.el.
+    (.PHONY): New.
+    (EXTRA_SRC): Remove `ChangeLog'.
+    
+    * .arch-inventory: New.  Make all the generated files precious.
+    
+    * eicq.el (eicq-version): Removed.  This comes from eicq-version.el now
+      so require that.
+
+    new files:
+     .arch-ids/.arch-inventory.id .arch-inventory
+
+    modified files:
+     Makefile eicq.el
+
+
+2004-11-12 03:14:32 GMT        Steve Youngs <steve@eicq.org>   patch-4
+
+    Summary:
+      Minor build fix
+    Revision:
+      eicq--main--0.6--patch-4
+
+    * eicq.el (eicq-auto-away-timeout): Move this to after
+      `eicq-auto-away-timeout-set'. 
+    
+    I got over zealous and should not have moved this defcustom in the last
+    patch.  This just reverts that part of it.
+
+    modified files:
+     eicq.el
+
+
+2004-11-11 06:56:21 GMT        Steve Youngs <steve@eicq.org>   patch-3
+
+    Summary:
+      Minor fixes/adjustments to Evgeny's previous patch
+    Revision:
+      eicq--main--0.6--patch-3
+
+    Global replace `income' => `incoming'
+    Global replace `outcome' => `outgoing'
+    
+    Fix a couple of typos and move a couple of defcustoms to where the
+    bug-reporter will pick them up.
+
+    modified files:
+     eicq-v8.el eicq.el
+
+
+2004-11-10 12:46:48 GMT        Steve Youngs <steve@eicq.org>   patch-2
+
+    Summary:
+      v8 protocol integration
+    Revision:
+      eicq--main--0.6--patch-2
+
+    2004-11-09  Zajcev Evgeny  <zevlg@yandex.ru>
+    
+       * eicq-v8.el (eicq-v8-version): New.
+       (eicq-FLAP-HELLO): Removed.
+       (eicq-FLAP-SNAC): Removed.
+       (eicq-FLAP-ERRORS): Removed.
+       (eicq-FLAP-LOGOFF): Removed.
+       (eicq-FLAP-PING): Removed.
+       (eicq-FLAP-VER-MAJOR): Removed.
+       (eicq-FLAP-VER-MINOR): Removed.
+       (eicq-FLAP-VER-LESSER): Removed.
+       (eicq-FLAP-VER-BUILD): Removed.
+       (eicq-FLAP-VER-SUBBUILD): Removed.
+       (eicq-v8-FLAP-HELLO): New.
+       (eicq-v8-FLAP-SNAC): New.
+       (eicq-v8-FLAP-ERRORS): New.
+       (eicq-v8-FLAP-LOGOFF): New.
+       (eicq-v8-FLAP-PING): New.
+       (eicq-v8-FLAP-VER-MAJOR): New.
+       (eicq-v8-FLAP-VER-MINOR): New.
+       (eicq-v8-FLAP-VER-LESSER): New.
+       (eicq-v8-FLAP-VER-BUILD): New.
+       (eicq-v8-FLAP-VER-SUBBUILD): New.
+       (eicq-v8-message-types): New.
+       (eicq-v8-valid-income-handlers): New.
+       (eicq-v8-valid-outcome-handlers): New.
+       (eicq-ctx): Removed.
+       (eicq-v8-ctx): New.
+       (eicq-ctx-get-prop): Removed.
+       (eicq-v8-ctx-get-prop): New.
+       (eicq-ctx-put-prop): Removed.
+       (eicq-v8-ctx-put-prop): New.
+       (eicq-ctx-rm-prop): Removed.
+       (eicq-v8-ctx-rm-prop): New.
+       (eicq-v8-ctx-get-income-handlers): New.
+       (eicq-default-ctx): Removed.
+       (eicq-v8-ctx-add-income-handler): New.
+       (eicq-v8-ctx-del-income-handler): New.
+       (eicq-v8-ctx-run-income-handler): New.
+       (eicq-v8-default-ctx): New.
+       (eicq-connections): Removed.
+       (eicq-v8-connections): New.
+       (eicq-v8-debug): New.
+       (eicq-flap-cid): Removed.
+       (eicq-v8-flap-cid): New.
+       (eicq-flap-seq): Removed.
+       (eicq-v8-flap-seq): New.
+       (eicq-flap-data): Removed.
+       (eicq-v8-flap-data): New.
+       (eicq-snac-family): Removed.
+       (eicq-v8-snac-family): New.
+       (eicq-snac-subtype): Removed.
+       (eicq-v8-snac-subtype): New.
+       (eicq-snac-flags0): Removed.
+       (eicq-v8-snac-flags0): New.
+       (eicq-snac-flags1): Removed.
+       (eicq-v8-snac-flags1): New.
+       (eicq-connect): Removed.
+       (eicq-v8-create-ctx): New.
+       (eicq-snacrid): Removed.
+       (eicq-v8-snacrid): New.
+       (eicq-tlv-type): Removed.
+       (eicq-v8-tlv-type): New.
+       (eicq-v8-connect): New.
+       (eicq-tlv-val): Removed.
+       (eicq-v8-tlv-len): New.
+       (eicq-v8-tlv-val): New.
+       (eicq-v8-tlv-str): New.
+       (eicq-v8-tlv-num): New.
+       (eicq-util-encrypt): Removed.
+       (eicq-v8-util-encrypt): New.
+       (eicq-close): Removed.
+       (eicq-v8-close): New.
+       (eicq-send): Removed.
+       (eicq-v8-send): New.
+       (eicq-send-flush): Removed.
+       (eicq-v8-send-flush): New.
+       (eicq-send-recv): Removed.
+       (eicq-v8-send-recv): New.
+       (eicq-proc-find): Removed.
+       (eicq-v8-proc-find): New.
+       (eicq-proc-sentinel): Removed.
+       (eicq-v8-proc-sentinel): New.
+       (eicq-proc-filter): Removed.
+       (eicq-v8-proc-filter): New.
+       (eicq-v8-snacv-list): New.
+       (eicq-v8-snac-list): New.
+       (eicq-v8-recv-message): New.
+       (eicq-v8-snac-srv-fromicqsrv): New.
+       (eicq-v8-snac-srv-set-interval): New.
+       (eicq-v8-snac-srv-reply-icbm): New.
+       (eicq-v8-snac-srv-replyinfo): New.
+       (eicq-v8-snac-srv-reply-buddy): New.
+       (eicq-v8-snac-srv-reply-location): New.
+       (eicq-v8-snac-srv-families): New.
+       (eicq-v8-snac-srv-families2): New.
+       (eicq-v8-snac-srv-rates): New.
+       (eicq-v8-snac-srv-motd): New.
+       (eicq-v8-snac-srv-recv-msg): New.
+       (eicq-v8-snac-srv-err): New.
+       (eicq-v8-snac-srv-reply-bos): New.
+       (eicq-proc-process-incoming): Removed.
+       (eicq-v8-snac-cli-setuserinfo): New.
+       (eicq-v8-status-alist): New.
+       (eicq-v8-snac-cli-setstatus): New.
+       (eicq-v8-snac-cli-add-contact): New.
+       (eicq-v8-snac-cli-keepalive): New.
+       (eicq-v8-create-meta-snac): New.
+       (eicq-v8-snac-cli-reqofflinemsgs): New.
+       (eicq-v8-snac-cli-ready): New.
+       (eicq-v8-snac-cli-families): New.
+       (eicq-v8-snac-cli-ratesrequest): New.
+       (eicq-v8-snac-cli-reqinfo): New.
+       (eicq-v8-snac-cli-reqlocation): New.
+       (eicq-v8-snac-cli-reqbuddy): New.
+       (eicq-v8-snac-cli-reqicbm): New.
+       (eicq-v8-snac-cli-reqbos): New.
+       (eicq-v8-proc-process-incoming): New.
+       (eicq-number->string): Removed.
+       (eicq-v8-number->string): New.
+       (eicq-create-flap): Removed.
+       (eicq-v8-create-flap): New.
+       (eicq-create-message): Removed.
+       (eicq-v8-number->string-swap): New.
+       (eicq-create-snac): Removed.
+       (eicq-v8-create-snac): New.
+       (eicq-v8-create-message): New.
+       (eicq-tlv-types): Removed.
+       (eicq-v8-tlv-types): New.
+       (eicq-tlv-type-value): Removed.
+       (eicq-v8-tlv-type-value): New.
+       (eicq-create-tlv): Removed.
+       (eicq-v8-create-tlv): New.
+       (eicq-parse-message): Removed.
+       (eicq-v8-string->number-le): New.
+       (eicq-v8-string->number): New.
+       (eicq-v8-grab-bytes): New.
+       (eicq-v8-grab-bytes-1): New.
+       (eicq-v8-length-1): New.
+       (eicq-v8-length-2): New.
+       (eicq-v8-length-3): New.
+       (eicq-v8-length-4): New.
+       (eicq-v8-parse-message): New.
+       (eicq-next-flap): Removed.
+       (eicq-v8-next-flap): New.
+       (eicq-next-snac): Removed.
+       (eicq-v8-next-snac): New.
+       (eicq-next-tlv): Removed.
+       (eicq-v8-next-tlv): New.
+       (eicq-v8-tlv-fetch): New.
+       (eicq-v8-tlv-get): New.
+       (eicq-login): Removed.
+       (eicq-v8-login): New.
+    
+       * eicq.el (eicq-ctx): New.
+       (eicq-do-instant-message):
+       (eicq-do-offline-message):
+       (eicq-do-message-helper):
+       (eicq-bin-alias):
+       (eicq-valid-uin-p):
+       (eicq-uin): New.
+       (eicq-server): New.
+       (eicq-port): New.
+       (eicq-do-connected): New.
+       (eicq-login): Modified to use eicq-v8 to login into
+       sever.  Also some custom variables introduced and some message
+       oriented functions modified.
+    
+    
+
+    modified files:
+     eicq-v8.el eicq.el
+
+
+2004-11-10 04:24:56 GMT        Steve Youngs <steve@eicq.org>   patch-1
+
+    Summary:
+      URL and email address updates for eicq.org domain
+    Revision:
+      eicq--main--0.6--patch-1
+
+
+    modified files:
+     README eicq-buddy.el eicq-comm.el eicq-convert.el eicq-log.el
+     eicq-menu.el eicq-meta.el eicq-report.el eicq-setup.el
+     eicq-status.el eicq-toolbar.el eicq-v8.el eicq-v8proto.el
+     eicq-wharf.el eicq-world.el eicq.el eicq.texi
+
+
+2004-11-10 04:22:28 GMT        Steve Youngs <steve@eicq.org>   base-0
+
+    Summary:
+      initial import
+    Revision:
+      eicq--main--0.6--base-0
+
+    
+    (automatically generated log message)
+
+    new files:
+     ChangeLog.SFCVS INSTALL Makefile NEWS README TODO
+     eicq-buddy.el eicq-comm.el eicq-convert.el eicq-log.el
+     eicq-menu.el eicq-meta.el eicq-report.el eicq-setup.el
+     eicq-status.el eicq-toolbar.el eicq-v8.el eicq-v8proto.el
+     eicq-wharf.el eicq-world.el eicq.el eicq.texi
+
+
diff --git a/ChangeLog.d/ChangeLog-0.7.Eicq b/ChangeLog.d/ChangeLog-0.7.Eicq
new file mode 100644 (file)
index 0000000..7f5828c
--- /dev/null
@@ -0,0 +1,1675 @@
+# do not edit -- automatically generated by arch changelog
+# non-id: automatic-ChangeLog--steve@eicq.org--2005/eicq--main--0.7
+#
+
+2005-06-13 14:53:19 GMT        Steve Youngs <steve@eicq.org>   version-0
+
+    Summary:
+      Eicq 0.7 is released!
+    Revision:
+      eicq--main--0.7--version-0
+
+    Just your normal release-day doc updates.
+    
+    * INSTALL: Update to include references to SXEmacs.
+    
+    * Makefile (superupgrade): Remove this target, I don't use it anymore.
+      Also, update copyright notice.
+    
+    * NEWS: Update.
+    
+    * README: Update the "feature" section.  Add some words about eicq-track
+      and eicq-history.
+    
+    * TODO: Put a note in it saying that it is hideously out of date.
+      Deleted a couple of items that have either been implemented or don't
+      make sense anymore.
+    
+    * eicq-track.el: Add my name to copyright notice.
+    
+    * *.el: Update copyright notice.
+
+    modified files:
+     INSTALL Makefile NEWS README TODO eicq-buddy.el
+     eicq-convert.el eicq-history.el eicq-menu.el eicq-meta.el
+     eicq-report.el eicq-setup.el eicq-status.el eicq-toolbar.el
+     eicq-track.el eicq-v8.el eicq-wharf.el eicq-world.el eicq.el
+
+
+2005-06-12 12:02:47 GMT        Steve Youngs <steve@eicq.org>   patch-60
+
+    Summary:
+      Merged from lg@xwem.org--2005 (patch 28) -- auto-reconnect/timeout
+    Revision:
+      eicq--main--0.7--patch-60
+
+    Patches applied:
+    
+     * lg@xwem.org--2005/eicq--lg--0.7--patch-28
+       fixes, fetching flaps changed
+    
+    My additions/tweaks to this changeset:
+    
+    * eicq.el (eicq-do-disconnect): Only attempt reconnect if the user has
+      set `eicq-user-password' and `eicq-delete-offline-messages-flag' is
+      _NOT_ set to "ask".  This is so unattended reconnects won't wait for
+      user input.
+    
+
+    modified files:
+     eicq-v8.el eicq.el
+
+    new patches:
+     lg@xwem.org--2005/eicq--lg--0.7--patch-28
+
+
+2005-06-10 10:19:27 GMT        Steve Youngs <steve@eicq.org>   patch-59
+
+    Summary:
+      Fix Eicq buffer display on a TTY
+    Revision:
+      eicq--main--0.7--patch-59
+
+    * eicq.el (eicq-show-window): Don't try to create frames if we're on a
+      TTY. 
+    
+
+    modified files:
+     eicq.el
+
+
+2005-06-01 01:41:21 GMT        Steve Youngs <steve@eicq.org>   patch-58
+
+    Summary:
+      Searching for ICQ users
+    Revision:
+      eicq--main--0.7--patch-58
+
+    This changeset implements searching.  With this you can now search for
+    ICQ users by: First Name, Last Name, Nick Name, Email Address.  Searching
+    by UIN is supported too, but that was implemented ages ago.
+    
+    There are 3 user search functions:
+    
+      `eicq-search-by-uin'   -- search by UIN
+      `eicq-search-by-email' -- search by email address
+      `eicq-search'          -- search by any of: first name, last name, nick
+                                name, email address
+    
+    * eicq-v8.el (eicq-v8-snac-srv-fromicqsrv): Handle type 2010/subtype 420
+      which is all search matches except the final match.  The final match is
+      subtype 430.
+      (eicq-v8-snac-cli-searchbyemail): Handle SNAC 15,2/2000/1395 searching
+      by email address.
+      (eicq-v8-snac-cli-searchbypersinf): Handle SNAC 15,2/2000/1375
+      searching by first name, last name, nick name, email address.
+      (eicq-v8-pack-llnts): New packer for data type LLNTS.
+    
+    * eicq.el (eicq-do-search-found): Modify to handle search results from
+      subtype 420, ie, all matches except the final match.
+      (eicq-do-search-found-last): New.  Handle search result from subtype
+      430, ie, just the final match.
+      (eicq-login): Add new incoming handler "search-found-last" for subtype
+      430.
+      (eicq-search): Update to new v8 protocol search.
+      (eicq-search-by-email): New.  Search for users by email address.
+    
+    * eicq-toolbar.el (eicq-toolbar-search): Update to use new search function.
+    
+    * eicq-menu.el (eicq-main-map): Bind `F' to `eicq-search'.
+    
+
+    modified files:
+     eicq-menu.el eicq-toolbar.el eicq-v8.el eicq.el
+
+
+2005-05-28 02:21:32 GMT        Steve Youngs <steve@eicq.org>   patch-57
+
+    Summary:
+      Another attempt at fixing eicq-history-directory being void
+    Revision:
+      eicq--main--0.7--patch-57
+
+    Third time lucky?  Hopefully now eicq-history-directory won't be void for
+    people not using eicq-history.
+    
+    * eicq.el (eicq-history): Moved from eicq-history.el to here.
+      (eicq-history-enabled-flag): Ditto.
+      (eicq-history-directory): Ditto.
+      (eicq-history-mode-hook): Ditto.
+    
+    * eicq-history.el: Moved the defcustoms to eicq.el because of the crazy
+      interdepencies of the Eicq libs.
+    
+    * eicq-report.el (eicq-report-debug): Remove eicq-history.el, there are
+      no user configurable things in there anymore.
+    
+
+    modified files:
+     eicq-history.el eicq-report.el eicq.el
+
+
+2005-05-27 08:53:01 GMT        Steve Youngs <steve@eicq.org>   patch-56
+
+    Summary:
+      Whee little doc fix
+    Revision:
+      eicq--main--0.7--patch-56
+
+    * eicq-history.el: Teeny tiny doc fix in commentary section
+    
+
+    modified files:
+     eicq-history.el
+
+
+2005-05-27 08:50:51 GMT        Steve Youngs <steve@eicq.org>   patch-55
+
+    Summary:
+      Fix previous fix for eicq-history
+    Revision:
+      eicq--main--0.7--patch-55
+
+    * eicq-log.el (eicq-history-directory): Revert previous change.
+    
+    * eicq-buddy.el (require): Drag in eicq-history.
+    
+
+    modified files:
+     eicq-buddy.el eicq-log.el
+
+
+2005-05-26 22:12:29 GMT        Steve Youngs <steve@eicq.org>   patch-54
+
+    Summary:
+      Fix eicq-history -- users not using it don't have to require it
+    Revision:
+      eicq--main--0.7--patch-54
+
+    * eicq-log.el (eicq-history-directory): Defvar it to nil so people _not_
+      wanting to use eicq-history don't have to require it in their set up.
+    
+
+    modified files:
+     eicq-log.el
+
+
+2005-05-26 10:12:10 GMT        Steve Youngs <steve@eicq.org>   patch-53
+
+    Summary:
+      Fix prob with extra-buffers var containing killed buffers
+    Revision:
+      eicq--main--0.7--patch-53
+
+    * eicq.el (eicq-exit): Set `eicq-extra-buffers-to-kill' to nil after the
+      extra buffers have been killed.
+    
+
+    modified files:
+     eicq.el
+
+
+2005-05-12 05:40:56 GMT        Steve Youngs <steve@eicq.org>   patch-52
+
+    Summary:
+      Handle "invisible" correctly.
+    Revision:
+      eicq--main--0.7--patch-52
+
+    Up until now, Eicq has not handled the "invisible" status anywhere near
+    correctly.  In reality, "invisible" isn't really a status in it's own
+    right.  It's a "flag" to tack onto other statuses, much like the
+    "web-aware" status is.
+    
+    With that in mind, Eicq now does "invisible" in the same manner as it
+    does "web-aware".  If you want to be "invisible" at login time, set
+    `eicq-user-meta-invisible' to non-nil.  If you want to change your
+    visibility during your ICQ session, rat button2 on "[Invisible on/off]"
+    in the status buffer.  Alternatively, `b' in the log or status buffers.
+    
+    === New User Commands ===
+      eicq-toggle-invisibility
+    
+    === New User Variables ===
+      eicq-user-meta-invisible -- boolean
+      eicq-user-meta-invisibility-indicator -- string
+    
+    === User Variables Changed Defaults ===
+      eicq-user-initial-status -- now defaults to "online"
+    
+    * eicq.el (eicq-login): Possibly set invisible with the initial status.
+    
+    * eicq-log.el (eicq-log-update-modeline): New.  Updates the invisibility
+      indicator in the modeline.
+      (eicq-log-mode): Use it.
+    
+    * eicq-meta.el (eicq-meta): Give the group a prefix "eicq-user-meta-".
+      (eicq-user-meta-invisible): New.  Set to non-nil to be "invisible" at
+      login. 
+      (eicq-user-meta-invisibility-indicator): New.  The value of this, a
+      string, displays in the modeline when you are "invisible". 
+    
+    * eicq-status.el (eicq-valid-statuses): Remove "invisible", it isn't
+      really a status in the truest sense of the word.
+      (eicq-user-initial-status): Default to "online".  If you want to be
+      "invisible" at login, set `eicq-user-meta-invisible' to non-nil instead.
+      (eicq-buddy-update-status): Work^Wkludge around `eicq-user-status'
+      being set to "invisible"... it should never happen.
+      (eicq-turn-on-invisibility): New.  Add invisible to status. 
+      (eicq-turn-off-invisibility): New.  Remove invisible from status.  This
+      is the opposite of `eicq-turn-on-invisibility'.
+      (eicq-toggle-invisibility): Toggle between visible and invisible. 
+      (eicq-change-status): Possibly set invisible.
+      (eicq-status-show-buffer): Use `eicq-toggle-invisibility' for the
+      "Invisible" widget in the status buffer.  Also, change the text in the
+      "Invisible" widget to indicate that it is now a toggle.
+    
+    * eicq-menu.el (eicq-main-map): Bind `b' to `eicq-toggle-invisibility' in
+      the log and status buffers.
+    
+
+    modified files:
+     eicq-log.el eicq-menu.el eicq-meta.el eicq-status.el eicq.el
+
+
+2005-05-04 08:20:40 GMT        Steve Youngs <steve@eicq.org>   patch-51
+
+    Summary:
+      Extract and display `REASON' from SRV_AUTHREQ properly
+    Revision:
+      eicq--main--0.7--patch-51
+
+    * eicq-v8.el (eicq-v8-fetch-bstr): New.  Fetch data type "bstr", as seen
+      in SRV_AUTHREQ.
+      (eicq-v8-snac-srv-authreq): Use it, instead of `eicq-v8-fetch-string'.
+    
+    * eicq.el (eicq-do-message-helper): Don't filter auth-request messages
+      through `substring', the fetch function is DTRT now.
+    
+
+    modified files:
+     eicq-v8.el eicq.el
+
+
+2005-05-03 08:46:12 GMT        Steve Youngs <steve@eicq.org>   patch-50
+
+    Summary:
+      Fix authorisation request reason messages
+    Revision:
+      eicq--main--0.7--patch-50
+
+    * eicq.el (eicq-do-message-helper): Parse authorisation request messages
+      through `substring' to filter out some noise.
+    
+
+    modified files:
+     eicq.el
+
+
+2005-05-02 19:07:10 GMT        Steve Youngs <steve@eicq.org>   patch-49
+
+    Summary:
+      Add SRV_AUTHREQ handler, fix SRV_ADDEDYOU handler
+    Revision:
+      eicq--main--0.7--patch-49
+
+    * eicq.el (eicq-login): Install incoming handlers for SRV_ADDEDYOU and
+      SRV_AUTHREQ. 
+      (eicq-do-added-you): Handler function for SRV_ADDEDYOU.
+      (eicq-do-auth-request): Handler function for SRV_AUTHREQ
+      (eicq-do-message-helper): Log SRV_ADDEDYOU messages as system
+      messages. 
+      (eicq-sound-alist): Add a "system" sound.
+    
+    * eicq-v8.el (eicq-v8-snac-srv-addedyou): Call
+      `eicq-v8-ctx-run-incoming-handler' with the appropriate keyword pairs.
+    
+    * eicq-v8.el (eicq-v8-snac-srv-authreq): New.  For SRV_AUTHREQ.
+    
+
+    modified files:
+     eicq-v8.el eicq.el
+
+
+2005-05-01 16:07:05 GMT        Steve Youngs <steve@eicq.org>   patch-48
+
+    Summary:
+      The case of the disappearing smiley.
+    Revision:
+      eicq--main--0.7--patch-48
+
+    * eicq-log.el (eicq-log): Fill the message _before_ adding smilies.
+      Without this, smilies that are at eol disappear.
+    
+
+    modified files:
+     eicq-log.el
+
+
+2005-05-01 09:26:57 GMT        Steve Youngs <steve@eicq.org>   patch-47
+
+    Summary:
+      Small regex fix in eicq-history
+    Revision:
+      eicq--main--0.7--patch-47
+
+    This fixes a problem in the history buffers when the day portion of the
+    date is a single digit starting in column 2.
+    
+    * eicq-history.el (eicq-history-outline-regexp): Fix regexp to handle the
+      single digit dates of the month.
+      (eicq-history-event-regexp): Ditto.
+    
+
+    modified files:
+     eicq-history.el
+
+
+2005-04-30 13:12:52 GMT        Steve Youngs <steve@eicq.org>   patch-46
+
+    Summary:
+      Add hyperlinks to the log buffer.
+    Revision:
+      eicq--main--0.7--patch-46
+
+    Dust off your rat, because with this change, the Eicq log buffer has
+    plenty of pointy-clicky things in it.  URLs, email addresses, and even
+    Unix manual page topics are all "hot".  With your rat, button2, or with
+    your keyboard, RET, on one of these links will have you browsing,
+    composing, or reading lickedy split.
+    
+    * eicq-emphasis.el (eicq-emphasis-url-regexp): New.  A regexp to match
+      URLs.
+      (eicq-emphasis-email-regexp): New.  A regexp to match email addresses.
+      (eicq-emphasis-man-regexp): New.  A regexp to match Unix manual page
+      topics. 
+      (eicq-emphasis-visit-hyperlink-at-point): New.  Uses `browse-url' or
+      `compose-mail' or `manual-entry' to follow links to URLs, email
+      addresses or man pages.  The links themselves are extents in the log
+      buffer. 
+      (eicq-emphasis-visit-hyperlink-at-mouse): New.  As above, but via a
+      rat.
+      (eicq-emphasis-hyperlink-message): New.  "hyperlink-er-ise" messages in
+      the log buffer.
+    
+    * eicq-log.el (eicq-log): Call `eicq-emphasis-hyperlink-message' on
+      messages in the log buffer as they come in.
+    
+    * eicq-log.el (eicq-log-buddy-url): Use `eicq-hyperlink-map' instead of
+      `eicq-url-map'. 
+    
+    * eicq-menu.el (eicq-hyperlink-map): New.  Replaces `eicq-url-map'.
+      (eicq-url-map): Removed.
+    
+
+    modified files:
+     eicq-emphasis.el eicq-log.el eicq-menu.el
+
+
+2005-04-29 05:51:09 GMT        Steve Youngs <steve@eicq.org>   patch-45
+
+    Summary:
+      Gnus-style text highlighting
+    Revision:
+      eicq--main--0.7--patch-45
+
+    With this change, the log buffer gets sexy!
+    
+      _text_ is underlined
+    
+      *text* is bold
+    
+      /text/ is italic
+    
+      _*text*_ is underlined and bold
+    
+      _*/text/*_ is underlined and bold and italic
+    
+      */text/* is bold and italic
+    
+      _/text/_ is underlined and italic
+    
+    And yes, it is customisable, so you can add others if you wish.  Turn on
+    this magic with:
+    
+      (setq eicq-emphasis-enabled-flag t)
+    
+    * eicq-log.el (eicq-log): Maybe call `eicq-emphasis-treat-message' to do
+      Gnus-style text rendering.
+    
+    * Makefile (SOURCES): Add eicq-emphasis.el
+    
+    * eicq-report.el (eicq-report-debug): Add eicq-emphasis.el
+    
+
+    new files:
+     .arch-ids/eicq-emphasis.el.id eicq-emphasis.el
+
+    modified files:
+     Makefile eicq-log.el eicq-report.el
+
+
+2005-04-28 22:52:03 GMT        Steve Youngs <steve@eicq.org>   patch-44
+
+    Summary:
+      Little tweaks and improvments to `eicq-log'
+    Revision:
+      eicq--main--0.7--patch-44
+
+    * eicq-log.el (eicq-log-buddy-url): Add balloon-help and a face to URLs.
+      (eicq-log-update-history): New.  Updates the history files and makes
+      `eicq-log' shorter and simpler.
+      (eicq-log-update-tracker): New.  Updates the eicq-track modeline
+      indicator and makes `eicq-log' shorter and simpler.
+      (eicq-log-update-balloon): New.  Updates the balloon-help extent
+      property on the contact names in the log buffer and makes `eicq-log'
+      shorter and simpler.
+      (eicq-log): Use `eicq-log-update-{history,tracker,balloon}'.
+    
+
+    modified files:
+     eicq-log.el
+
+
+2005-04-28 05:20:17 GMT        Steve Youngs <steve@eicq.org>   patch-43
+
+    Summary:
+      Add balloon-help coolness to contact names
+    Revision:
+      eicq--main--0.7--patch-43
+
+    * eicq-log.el (eicq-log): Set up balloon-help properties for the alias
+      extents. 
+    
+    * eicq-buddy.el (eicq-buddy-update-face): Set up balloon-help properties
+      for the names in the buddy buffer.
+      (eicq-buddy-show-buffer): Force a `eicq-buddy-update-face' on each name
+      to update its balloon-help extent property.  It it probably a bit of
+      overkill to do it this way, but it works.  Improvements very welcome.
+    
+    * eicq-world.el (eicq-add-new-user-to-buddy-buffer): Add balloon-help
+      properties to the extent.
+    
+    
+
+    modified files:
+     eicq-buddy.el eicq-log.el eicq-world.el
+
+
+2005-04-27 22:59:09 GMT        Steve Youngs <steve@eicq.org>   patch-42
+
+    Summary:
+      Make all calls to play-sound-file consistent througout
+    Revision:
+      eicq--main--0.7--patch-42
+
+    * eicq.el (eicq-do-online): Use `eicq-maybe-play-sound'.
+    
+    * eicq-status.el (eicq-buddy-update-status): Ditto.
+    
+
+    modified files:
+     eicq-status.el eicq.el
+
+
+2005-04-24 06:27:48 GMT        Steve Youngs <steve@eicq.org>   patch-41
+
+    Summary:
+      Add doc string to advice in `eicq-track-init'.
+    Revision:
+      eicq--main--0.7--patch-41
+
+    * eicq-track.el (eicq-track-init): Give the advice a doc string.
+    
+
+    modified files:
+     eicq-track.el
+
+
+2005-04-23 01:38:22 GMT        Steve Youngs <steve@eicq.org>   patch-40
+
+    Summary:
+      Merged from lg@xwem.org--2005 (patch 23)
+    Revision:
+      eicq--main--0.7--patch-40
+
+    Patches applied:
+    
+     * lg@xwem.org--2005/eicq--lg--0.7--patch-23
+       commented buggy and unuseful code
+
+    modified files:
+     eicq-v8.el
+
+    new patches:
+     lg@xwem.org--2005/eicq--lg--0.7--patch-23
+
+
+2005-04-23 01:30:27 GMT        Steve Youngs <steve@eicq.org>   patch-39
+
+    Summary:
+      eicq-track clean up, add "Riece-style" modeline indicator
+    Revision:
+      eicq--main--0.7--patch-39
+
+    This patch cleans up the eicq-track code a bit.  Plus it adds a Riece
+    style modeline indicator for eicq-track.  See
+    `eicq-track-indicator-type'. 
+    
+    The default tracking indicator style is like ERC...
+    
+       [name,name2,name3...]
+    
+    The Riece style is...
+    
+       [E]
+    
+    You can also filter out the debug, error, and system log messages so they
+    don't update the indicator.  See `eicq-track-events-type'.
+    
+    * eicq-track.el: Don't require eicq-log, instead just defvar
+      eicq-log-buffer at compile-time.
+      (eicq-track-visibility): Removed.
+      (eicq-track-events-type): Update doc string.  Add new type, "msg" which
+      is for incoming user messages only.  The "incoming" type also tracks
+      system and debug log entries too.
+      (eicq-track-shorten-to): Set custom type to integer.
+      (eicq-log-buffer-visible-p): Removed.
+      (eicq-track-clear-modeline): Use `redraw-modeline' instead of
+      `force-mode-line-update'. 
+      (eicq-track-init): setq eicq-track-initialized instead of setf.
+      (eicq-track-indicator-type): New.  Choose either ERC style modeline
+      indicator or Riece style.
+      (eicq-short-nick): Rename to `eicq-track-truncate-nick'.
+      (eicq-track-truncate-nick): New.
+      (eicq-track-add-nick): Rewrite to cater for both ERC style and Riece
+      style modeline indicators.  Also, keep lines under 80 columns long.
+    
+    * eicq.el: Don't require eicq-track here.  Do it in eicq-log.el
+      instead.
+    
+    * eicq-log.el: Require eicq-track.
+    
+    * eicq-log.el (eicq-log): Update to allow for 'msg' type from
+      `eicq-track-events-type'. 
+    
+    * eicq-report.el (eicq-report-debug): Add eicq-track.el.
+    
+
+    modified files:
+     eicq-log.el eicq-report.el eicq-track.el eicq.el
+
+
+2005-04-22 20:40:17 GMT        Steve Youngs <steve@eicq.org>   patch-38
+
+    Summary:
+      Merged from karma@sxemacs.org--2005 (patch 4) -- eicq-track
+    Revision:
+      eicq--main--0.7--patch-38
+
+    Patches applied:
+    
+     * karma@sxemacs.org--2005/eicq--karma--0.7--patch-4
+       introduces `eicq-track'feature
+
+    new files:
+     .arch-ids/eicq-track.el.id eicq-track.el
+
+    modified files:
+     Makefile eicq-log.el eicq.el
+
+    new patches:
+     karma@sxemacs.org--2005/eicq--karma--0.7--patch-4
+
+
+2005-04-22 08:16:48 GMT        Steve Youngs <steve@eicq.org>   patch-37
+
+    Summary:
+      History improvements, eicq-setup tweaks, minor build fixes
+    Revision:
+      eicq--main--0.7--patch-37
+
+    This patch makes a few improvements to eicq-history:
+    
+      - uniform `eicq-history-' naming throughout eicq-history.el
+      - history files are only saved on logout
+      - added a user command to explicitly save histories bound to `H' in
+        buddy/log buffers and `s' in history buffers.
+      - entries in history files are filled
+      - minor regexp fix to catch strange nick names in the history files.
+      - `eicq-history-here-other-window' restores the original window config
+        on exit from eicq-history-mode.
+      - the default directory for history files is now ~/.eicq/history/
+    
+    There's also a couple of minor build related changes.
+    
+    * Makefile (SOURCES): List the files explicitly instead of using
+      wildcards so we can control what gets compiled and in which order.
+      (EXTRA_SRC): Add eicq-version.el because it isn't getting included in
+      SOURCES anymore.
+    
+    * eicq-history.el (eicq-history): New custom group.
+    
+    * eicq-history.el (eicq-history-enabled-flag): New custom variable.  This
+      used to be `eicq-log-per-user'.
+    
+    * eicq-history.el (eicq-history-directory): New custom variable.  This
+      used to be `eicq-log-per-user-directory'.
+    
+    * eicq-history.el (eicq-history-mode-hook): Change custom group to
+      eicq-history. 
+    
+    * eicq-history.el (eicq-history-old-window-config): New.  Holds the old
+      window config so when quitting the history buffer things are reset to
+      the state they were before.
+    
+    * eicq-history.el (eicq-history): Add a little error checking.  Stop it
+      from loading a dired buffer if the user just hits RET at the prompt for
+      a user name.
+    
+    * eicq-history.el (eicq-history-here-other-window): Save the window
+      config before doing anyting else so the user comes back to the way
+      things were before he entered eicq-history-mode.
+    
+    * eicq-history.el (eicq-history-event-regexp): Fix regexp to catch weird
+      nick names.
+    
+    * eicq-history.el (eicq-history-mode): Don't set the fill-column.  Add
+      the menu after setting the mode name, but before anything else.
+    
+    * eicq-history.el (eicq-history-bury-buffer): New.  This used to be
+      `eicq-history-kill-buffer'.  By default it buries the buffer, with a
+      prefix arg it kills the buffer.
+    
+    * eicq-history.el (eicq-history-save): New.  Saves all the files in the
+      history directory that are open.
+    
+    * eicq-log.el (eicq-extra-buffers-to-kill): New variable.  Holds a list
+      of extra buffers to be saved/killed.  Primary use is for the history
+      files.  They are saved on logout and killed on exit.
+    
+    * eicq-log.el (eicq-log): Use eicq-history-enabled-flag and
+      eicq-history-directory instead of the old "per-user" vars.
+      Remove an unnecessary let and its local vars.
+      Fill the entries in the history files.
+    
+    * eicq-menu.el (eicq-history-menu): Add menu item for
+      `eicq-history-save'.  Change "Quit" item to use
+      `eicq-history-bury-buffer'. 
+    
+    * eicq-menu.el (eicq-history-mode-map): Ditto.
+    
+    * eicq-menu.el (eicq-main-map): Define `H' to be `eicq-history-save'.
+    
+    * eicq-setup.el (eicq-setup): Require the needed libs if they aren't
+      already loaded.  Check to see if each directory is nonexistent before
+      creating it.  And don't use `format' with `message', it's not
+      necessary. 
+    
+    * eicq.el (eicq-directory): Autoload it.
+    
+    * eicq.el (eicq-exit): Kill all the buffers in
+      `eicq-extra-buffers-to-kill'. 
+    
+    * eicq.el (eicq-logout): Save all the buffers in
+      `eicq-extra-buffers-to-kill'. 
+    
+    
+
+    modified files:
+     Makefile eicq-history.el eicq-log.el eicq-menu.el
+     eicq-setup.el eicq.el
+
+
+2005-04-20 20:48:41 GMT        Steve Youngs <steve@eicq.org>   patch-36
+
+    Summary:
+      Introduce `eicq-directory' and eicq-history improvements
+    Revision:
+      eicq--main--0.7--patch-36
+
+    * eicq-history.el: Pull in eicq so we can use `eicq-directory'.  And add
+      comments about using it.
+      (eicq-log-per-user-directory): Set default with `expand-file-name' and
+      `eicq-directory'.  Set custom type to directory.
+      (eicq-history-mode-hook): New hook.  Run after entering
+      `eicq-history-mode'. 
+      (eicq-history): Simplify.
+      (eicq-history-event-regexp): Use concat and split the regexp to keep
+      the source code under 80 columns.
+      (eicq-history-mode): Move point back one line so it is on the last
+      entry in the buffer.
+      (eicq-history-kill-buffer): Don't try to swich back to the log buffer
+      because it may not exist.  Also make sure the buffer being killed is in
+      `eicq-history-mode'.
+      (eicq-history-timestamp-face): Don't check if it is bound.
+      (eicq-history-event-type-face): Ditto.
+      (eicq-history-nick-face): Ditto.
+    
+    * eicq-log.el (eicq-log-filename): Define with `expand-file-name' and
+      hang it off `eicq-directory'.  Set custom type to file.
+      Defvar `eicq-log-per-user' and `eicq-log-per-user-directory' at compile
+      time.
+      (eicq-log): Use `expand-file-name' to get to the per-user history file.
+    
+    * eicq-report.el (eicq-report-debug): Include eicq-history.el in the list
+      of files to check for changed variables.
+    
+    * eicq-setup.el (eicq-setup): Create the sound and logs directories.
+    
+    * eicq-world.el (eicq-world-rc-filename): Change to a defcustom.
+    
+    * eicq.el (eicq-directory): New custom variable.  All Eicq support files,
+      things like logs, histories, sound files, world file, go into this
+      directory or subdirectories of it.
+      (eicq-sound-directory): Hang it off `eicq-directory'.
+    
+    
+
+    modified files:
+     eicq-history.el eicq-log.el eicq-report.el eicq-setup.el
+     eicq-toolbar.el eicq-world.el eicq.el
+
+
+2005-04-19 21:29:00 GMT        Steve Youngs <steve@eicq.org>   patch-35
+
+    Summary:
+      Merged from karma@sxemacs.org--2005 (patch 1-2) -- history
+    Revision:
+      eicq--main--0.7--patch-35
+
+    This gives us the option of having mICQ-style logging... a log file for
+    each contact.  You can view the history of any contact.  And it makes way
+    for implementing things like `eicq-last-seen' for showing the date/time
+    you last had contact with someone.
+    
+    Patches applied:
+    
+     * karma@sxemacs.org--2005/eicq--karma--0.7--patch-1
+       introduces "per-user" logging and `eicq-history' feature
+    
+     * karma@sxemacs.org--2005/eicq--karma--0.7--patch-2
+       small fix in `eicq-history'
+
+    new files:
+     .arch-ids/eicq-history.el.id eicq-history.el
+
+    modified files:
+     eicq-log.el eicq-menu.el eicq.el
+
+    new patches:
+     karma@sxemacs.org--2005/eicq--karma--0.7--patch-1
+     karma@sxemacs.org--2005/eicq--karma--0.7--patch-2
+
+
+2005-04-11 03:19:33 GMT        Steve Youngs <steve@eicq.org>   patch-34
+
+    Summary:
+      List names in buddy buffer in the same order they are in world
+    Revision:
+      eicq--main--0.7--patch-34
+
+    * eicq-world.el (eicq-world-update): Reverse the list items in
+      `eicq-world' so that the buddy buffer will display the buddies in the
+      same order that they appear in the world file.
+    
+
+    modified files:
+     eicq-world.el
+
+
+2005-04-09 23:58:59 GMT        Steve Youngs <steve@eicq.org>   patch-33
+
+    Summary:
+      Fix auto-online where someone has requested a online notify
+    Revision:
+      eicq--main--0.7--patch-33
+
+    * eicq.el (eicq-idle-reply): Don't set eicq-auto-reply-p here.
+    (eicq-idle-reply-maybe): Set it here instead.
+    
+
+    modified files:
+     eicq.el
+
+
+2005-04-07 05:59:38 GMT        Steve Youngs <steve@eicq.org>   patch-32
+
+    Summary:
+      Add a missing key binding for `eicq-exit' -- `X q'
+    Revision:
+      eicq--main--0.7--patch-32
+
+    * eicq-menu.el (eicq-main-map): Add binding for `eicq-exit', `X q'.
+    
+
+    modified files:
+     eicq-menu.el
+
+
+2005-04-06 13:43:48 GMT        Steve Youngs <steve@eicq.org>   patch-31
+
+    Summary:
+      Remove =partner-version file, it wasn't such a crash hot idea
+    Revision:
+      eicq--main--0.7--patch-31
+
+
+
+2005-04-05 18:15:08 GMT        Steve Youngs <steve@eicq.org>   patch-30
+
+    Summary:
+      Fix bug with forwarding last message in log buffer
+    Revision:
+      eicq--main--0.7--patch-30
+
+    * eicq-log.el (eicq-log-around): If we're on the last message in the
+      buffer, the end of the message is at point-max and not at the start of
+      the next message.  This fixes a bug that meant you couldn't forward the
+      last message in the log buffer.
+    
+
+    modified files:
+     eicq-log.el
+
+
+2005-04-05 16:52:17 GMT        Steve Youngs <steve@eicq.org>   patch-29
+
+    Summary:
+      add missing patch logs
+    Revision:
+      eicq--main--0.7--patch-29
+
+    Patches applied:
+    
+     * dev@xwem.org--2004-w/eicq--ckent--0.7--patch-3
+       merge from main
+    
+     * lg@xwem.org--2005/eicq--lg--0.7--patch-19
+       merge with main
+    
+     * lg@xwem.org--2005/eicq--lg--0.7--patch-20
+       helper fix for simple/normal messaging
+    
+     * lg@xwem.org--2005/eicq--lg--0.7--patch-21
+       merge from main
+    
+
+    new patches:
+     dev@xwem.org--2004-w/eicq--ckent--0.7--patch-3
+     lg@xwem.org--2005/eicq--lg--0.7--patch-19
+     lg@xwem.org--2005/eicq--lg--0.7--patch-20
+     lg@xwem.org--2005/eicq--lg--0.7--patch-21
+
+
+2005-04-02 16:56:11 GMT        Steve Youngs <steve@eicq.org>   patch-28
+
+    Summary:
+      Guard against runaway online notifier registering/cancelling
+    Revision:
+      eicq--main--0.7--patch-28
+
+    * eicq.el (eicq-do-message-helper): Fix regexp in string-match for online
+      notifiers so to Eicq's won't set/cancel notification requests between
+      each other because of auto-response messages.
+    
+
+    modified files:
+     eicq.el
+
+
+2005-04-02 05:03:38 GMT        Steve Youngs <steve@eicq.org>   patch-27
+
+    Summary:
+      Improve the global keybindings -- the prefix is customisable
+    Revision:
+      eicq--main--0.7--patch-27
+
+    This patch introduces a new prefix command, `eicq-prefix'.  The default
+    binding is "M-`".  It is also customisable, see the new variable
+    `eicq-prefix-key'.  If you wish to change its value you _MUST_ do so via
+    `customize-set-variable' and not `setq', otherwise the bindings won't be
+    set.
+    
+    This change means that you will have to (require 'eicq) in your init
+    file.  If you don't you won't have any global bindings, the commands will
+    be there, but no keys.
+    
+    * INSTALL: Add `(require 'eicq)' to the code snippet to go in
+      ~/.sxemacs/init.el 
+    
+    * eicq-menu.el (eicq-prefix): New prefix command
+      Bind eicq-login, eicq-show-window, world-find with this prefix instead
+      of globally binding them all separately.
+    
+    * eicq.el (eicq-install-bindings): New.  Installs a key binding for
+      `eicq-prefix'. 
+      (eicq-prefix-key): New customisable variable.  Key for
+      `eicq-prefix'. 
+    
+
+    modified files:
+     INSTALL eicq-menu.el eicq.el
+
+
+2005-04-01 07:40:21 GMT        Steve Youngs <steve@eicq.org>   patch-26
+
+    Summary:
+      Allow other ICQ users to request online notification
+    Revision:
+      eicq--main--0.7--patch-26
+
+    With this patch if someone sends you a message with ",,notify-me" in the
+    message then Eicq will store their alias and when you go back online send
+    out a "I'm back online" message.  It only happens once.  If the ICQ user
+    wants to be notified the next time, they have to send another
+    "notification request message".  They can also cancel a request by
+    sending you ",,cancel-notify".
+    
+    * eicq.el (eicq-auto-reply-away): Set default response to mention online
+      notify requests.
+      (eicq-auto-reply-occ): Ditto.
+      (eicq-auto-reply-dnd): Ditto.
+      (eicq-auto-reply-na): Ditto.
+      (eicq-idle-reply-away): Ditto.
+      (eicq-idle-reply-na): Ditto.
+      (eicq-online-notifiers): New.  Internal list of aliases who have
+      requested to be notified when we go back online after being away, na,
+      occ, or dnd.
+      (eicq-do-message-helper): Handle setting up and cancelling online
+      notifications. 
+      (eicq-auto-reply): Doc string typo.
+      (eicq-idle-reply): Ditto.
+    
+    * eicq-status.el (eicq-change-status): Send out the online notifications
+      if we are changing to "online".  Then reset `eicq-online-notifiers' so
+      people won't get notified a 2nd time.
+    
+
+    modified files:
+     eicq-status.el eicq.el
+
+
+2005-04-01 04:02:31 GMT        Steve Youngs <steve@eicq.org>   patch-25
+
+    Summary:
+      Fix auto-away timer not being started
+    Revision:
+      eicq--main--0.7--patch-25
+
+    * eicq.el: Make sure the auto-away idle timer is started.
+    
+
+    modified files:
+     eicq.el
+
+
+2005-03-31 12:46:50 GMT        Steve Youngs <steve@eicq.org>   patch-24
+
+    Summary:
+      Custom and keymap fixes
+    Revision:
+      eicq--main--0.7--patch-24
+
+    * eicq-menu.el (eicq-global-map-set): Remove.  Not used anymore.
+      (eicq-global-key-prefix): Ditto.  These were removed so we don't pollute
+      the global keymap with commands that really have no business having
+      globally bound keys.  What is needed globally has been set via a couple
+      of calls to `global-set-key'.
+      (eicq-main-menu): Add item for `eicq-change-idle-timeout'.
+    
+      Remove a stack of autoload cookies from this file.
+    
+    * eicq-report.el (eicq-report-debug): Don't look in eicq-menu.el, there
+      are no customisable variables there.
+    
+    * eicq.el (eicq-auto-away-timeout): Fix custom type.
+      (eicq-change-idle-timeout): New.  To interactively change the
+      auto-away timeout for the current session.
+      (eicq-about-fields): Move to above the "Internal variables"
+      marker so it is included in bug reports.
+      (eicq-about-more-fields): Ditto.
+    
+
+    modified files:
+     eicq-menu.el eicq-report.el eicq.el
+
+
+2005-03-31 06:54:46 GMT        Steve Youngs <steve@eicq.org>   patch-23
+
+    Summary:
+      Fix bug with incoming messages containing `%' chars
+    Revision:
+      eicq--main--0.7--patch-23
+
+    If someone sent you a message that contained a `%', eg "we have 80% of
+    the work done", `format' would complain bitterly.  This patch fixes
+    that. 
+    
+    * eicq-log.el (eicq-log-buddy-message): Add extra arg, FMT, for the
+      format message to pass directly to `format'.
+    
+    * eicq.el (eicq-do-message-helper): Use FMT arg to
+      eicq-log-buddy-message. 
+    
+
+    modified files:
+     eicq-log.el eicq.el
+
+
+2005-03-30 05:53:13 GMT        Steve Youngs <steve@eicq.org>   patch-22
+
+    Summary:
+      Improve auto-response message sending
+    Revision:
+      eicq--main--0.7--patch-22
+
+    With this, the auto-response messages are only sent once per contact per
+    period of being not "online".  It is also possible to define a list of
+    contacts that never get sent the auto-response messages.  See the new
+    customisable variable: eicq-auto-response-never-send-to.
+    
+    
+    * eicq.el (eicq-auto-response-never-send-to): New.  Holds a list of alias
+      names of people you don't want auto-response messages being sent to.
+      (eicq-auto-reply-never): New.  Internal list of people not to send
+      auto-responses to.
+      (eicq-auto-reply-maybe): New.  Only send auto-response if the person
+      isn't in `eicq-auto-reply-never'.
+      (eicq-idle-reply-maybe): Ditto.
+      (eicq-do-message-helper): Use `eicq-auto-reply-maybe' and
+      `eicq-idle-reply-maybe'. 
+      (eicq-send-message-helper): Remove a nested `if' and change the outer
+      `if' to a `when'.  Just makes things a bit cleaner. :-)
+    
+    * eicq-status.el (eicq-change-status): Reset `eicq-auto-reply-never' when
+      coming back online.
+    
+
+    modified files:
+     eicq-status.el eicq.el
+
+
+2005-03-29 10:01:41 GMT        Steve Youngs <steve@eicq.org>   patch-21
+
+    Summary:
+      Prevent echo to stdout on (S)XEmacs start up.
+    Revision:
+      eicq--main--0.7--patch-21
+
+    * eicq.el (eicq-auto-away-timeout): Remove autoload cookie.
+    
+    * eicq-menu.el (eicq-global-key-prefix): Ditto.
+    
+    This stops things from echo'ing to stdout on (S)XEmacs start up.  It is
+    not really a problem, it just stops paranoid people from complaining.
+    
+
+    modified files:
+     eicq-menu.el eicq.el
+
+
+2005-03-29 07:11:18 GMT        Steve Youngs <steve@eicq.org>   patch-20
+
+    Summary:
+      Improve typed message sending
+    Revision:
+      eicq--main--0.7--patch-20
+
+    * eicq-v8.el (eicq-v8-send-typed-message): Get the user's UIN from the
+      etcx thing.
+    
+
+    modified files:
+     eicq-v8.el
+
+
+2005-03-29 00:36:56 GMT        Steve Youngs <steve@eicq.org>   patch-19
+
+    Summary:
+      Fix bug in message sending
+    Revision:
+      eicq--main--0.7--patch-19
+
+    * eicq-v8.el (eicq-v8-send-typed-message): A "typed" message must contain
+      the _sender's_ UIN in the packet.
+    
+    * eicq.el (eicq-send-message-helper): For "normal" messages use
+      `eicq-v8-send-simple-message', and for "typed" messages use
+      `eicq-v8-send-typed-message'. 
+    
+
+    modified files:
+     eicq-v8.el eicq.el
+
+
+2005-03-28 07:34:01 GMT        Steve Youngs <steve@eicq.org>   patch-18
+
+    Summary:
+      Remove unnecessary advice on `display-buffer'
+    Revision:
+      eicq--main--0.7--patch-18
+
+    * eicq-buddy.el: Don't advise `display-buffer'.
+    
+    
+    
+
+    modified files:
+     eicq-buddy.el
+
+
+2005-03-26 16:05:46 GMT        Steve Youngs <steve@sxemacs.org>        patch-17
+
+    Summary:
+      Merged from lg@xwem.org--2005 (patch 18) -- URL msg sending
+    Revision:
+      eicq--main--0.7--patch-17
+
+    With this patch it is possible to send URL "type 4" messages.  Command
+    `u' and `U'.
+    
+    Patches applied:
+    
+     * lg@xwem.org--2005/eicq--lg--0.7--patch-18
+       Functionality to send typed messages added.
+
+    modified files:
+     eicq-log.el eicq-v8.el eicq.el
+
+    new patches:
+     lg@xwem.org--2005/eicq--lg--0.7--patch-18
+
+
+2005-03-25 03:54:25 GMT        Steve Youngs <steve@eicq.org>   patch-16
+
+    Summary:
+      Merged from lg@xwem.org--2005 (patch 14, 16) status fixes
+    Revision:
+      eicq--main--0.7--patch-16
+
+    
+    Patches applied:
+    
+     * lg@xwem.org--2005/eicq--lg--0.7--patch-14
+       fixes, searching by uin, etc
+    
+     * lg@xwem.org--2005/eicq--lg--0.7--patch-16
+       web-awareness, initial state fixes
+    
+    My additions/tweaks:
+    
+    * eicq-status.el (eicq-webaware-p): Removed.  It already exists as
+      `eicq-user-meta-web-aware'.
+      (eicq-status-v8): Update doc string. 
+      (eicq-change-status): Use `eicq-user-meta-web-aware'
+      instead of `eicq-webaware-p'.
+    
+    * eicq.el (eicq-login): Ditto.
+      (eicq-status-v8): Autoload it.
+
+    modified files:
+     eicq-status.el eicq-v8.el eicq-world.el eicq.el
+
+    new patches:
+     lg@xwem.org--2005/eicq--lg--0.7--patch-14
+     lg@xwem.org--2005/eicq--lg--0.7--patch-16
+
+
+2005-03-22 01:45:16 GMT        Steve Youngs <steve@eicq.org>   patch-15
+
+    Summary:
+      itimer fixes
+    Revision:
+      eicq--main--0.7--patch-15
+
+    * eicq.el (eicq-keep-alive-stop): You can't call `delete-itimer' on just
+      an itimer name, you have to do it via `get-itimer'.
+      (eicq-auto-away-timeout-set): Ditto.
+    
+
+    modified files:
+     eicq.el
+
+
+2005-03-20 06:59:21 GMT        Steve Youngs <steve@eicq.org>   patch-14
+
+    Summary:
+      Merged from lg@xwem.org--2005 (patch 12-13)
+    Revision:
+      eicq--main--0.7--patch-14
+
+    Patches applied:
+    
+     * lg@xwem.org--2005/eicq--lg--0.7--patch-12
+       More support for advanced messages
+    
+     * lg@xwem.org--2005/eicq--lg--0.7--patch-13
+       Making eicq-about-fields and eicq-about-more-fields customizable
+
+    modified files:
+     eicq-v8.el eicq.el
+
+    new patches:
+     lg@xwem.org--2005/eicq--lg--0.7--patch-12
+     lg@xwem.org--2005/eicq--lg--0.7--patch-13
+
+
+2005-03-19 06:37:58 GMT        Steve Youngs <steve@eicq.org>   patch-13
+
+    Summary:
+      Toolbar fix, compiler warning fixes, Improve info queries.
+    Revision:
+      eicq--main--0.7--patch-13
+
+    * eicq-toolbar.el (eicq-toolbar-query-info-here): Call
+      `eicq-query-info-alias-around' instead of
+      `eicq-query-info-alias-here'. 
+    
+    * eicq-log.el (eicq-log-show-buffer): Change the initial content of the
+      log buffer... plug `eicq-donation'
+    
+    * eicq-v8.el (eicq-v8-snac-srv-replyinfo): setq count to itself to avoid
+      a compiler warning.  Ugly hack, fix properly later.
+      (eicq-v8-snac-srv-recv-msg): Add a FIXME comment.  This
+      defun is spewing a "variable bound but not referenced" warning.  The
+      variable in question is `mrec'.  I can't see why it is causing the
+      warning because it it bound AND referenced.  I think the byte-compiler
+      is on drugs.
+    
+    * eicq.el (eicq-do-alist): Comment out the `eicq-do-info-*' they don't
+      appear to be used anymore.
+      (eicq-do-info-not-available): Comment out... not used.
+      (eicq-do-info-ext-not-available): Ditto.
+      (eicq-do-search-found): Ditto.
+      (eicq-do-about-about): Set format width to 15.
+      (eicq-do-about-more): Set format width to 15 and update to use
+      `eicq-about-more-fields' being a simple alist instead of a complicated
+      broken customisable variable.
+      (eicq-do-about-general): Set format width to 15 and update to use
+      `eicq-about-fields' being a simple alist instead of a complicated
+      broken customisable variable.
+      (eicq-format-field): Set format width to 15 and update to use
+      `eicq-about-*-fields' being simple alists instead of a complicated
+      broken customisable variables.
+      (eicq-about-more-fields): Change to a simple alist instead of a
+      complicated and badly broken customisable variable.
+      (eicq-about-fields): Ditto.
+    
+    The major noticable change here is that the info query fields are no
+    longer customisable.  The defcustoms were totally screwed.  They are now
+    simple defconst alists.  I'll make them customisable if anyone bitches
+    about it, but I really can't see that happening.
+
+    modified files:
+     eicq-log.el eicq-toolbar.el eicq-v8.el eicq.el
+
+
+2005-03-19 00:42:16 GMT        Steve Youngs <steve@eicq.org>   patch-12
+
+    Summary:
+      Merged from lg@xwem.org--2005 (patch 9)
+    Revision:
+      eicq--main--0.7--patch-12
+
+    With this patch, the info query commands `i' & `I' now work.
+    
+    Patches applied:
+    
+     * lg@xwem.org--2005/eicq--lg--0.7--patch-9
+       about info fetching done, some fixes
+
+    modified files:
+     eicq-v8.el eicq.el
+
+    new patches:
+     lg@xwem.org--2005/eicq--lg--0.7--patch-9
+
+
+2005-03-16 23:14:14 GMT        Steve Youngs <steve@eicq.org>   patch-11
+
+    Summary:
+      Merged from lg@xwem.org--2005 (patch 8)
+    Revision:
+      eicq--main--0.7--patch-11
+
+    
+    Fixes the "Invalid len" error on status change.  And partially implements
+    info queries.  The info query code is far from finished, it doesn't
+    actually do any querying yet. :-P
+    
+    
+    Patches applied:
+    
+     * lg@xwem.org--2005/eicq--lg--0.7--patch-8
+       Fixes, addons
+
+    modified files:
+     eicq-v8.el eicq.el
+
+    new patches:
+     lg@xwem.org--2005/eicq--lg--0.7--patch-8
+
+
+2005-03-06 06:21:18 GMT        Steve Youngs <steve@eicq.org>   patch-10
+
+    Summary:
+      Code clean up, fix bug in exit stopping Eicq frame deletion. 
+    Revision:
+      eicq--main--0.7--patch-10
+
+    * eicq.el (eicq-icq-client-id-string): Moved to eicq-v8.el where it is
+      called `eicq-v8-client-id-string'.
+      (eicq-disconnect): Only logout if we're connected. And don't try to
+      kill the non-existent eicq-network-buffer.  This was stopping the Eicq
+      frame from being deleted if you start in a new frame.
+      (eicq-connected-p): New.
+      (eicq-disconnect): Rename it to `eicq-exit'.
+    
+    * eicq-v8.el (eicq-v8-client-id-string): New.
+      (eicq-v8-login): Use it.
+    
+    * eicq-toolbar.el (eicq-exit): Autoload this instead of `eicq-disconnect'.
+      (eicq-disconnect-icon): Rename to `eicq-exit-icon'.
+      (eicq-toolbar-disconnect): Rename to `eicq-toolbar-disconnect'.
+      (eicq-log-toolbar): disconnect -> exit.  Move help icon
+      to right side of frame.
+    
+    * eicq-menu.el (eicq-main-menu): Rename "disconnect" to "exit".
+    
+    * eicq-log.el (eicq-log-show-buffer): Change the header in log files to
+      say (S)XEmacs.
+    
+
+    modified files:
+     eicq-log.el eicq-menu.el eicq-toolbar.el eicq-v8.el eicq.el
+
+
+2005-03-06 04:03:48 GMT        Steve Youngs <steve@eicq.org>   patch-9
+
+    Summary:
+      Fix statuses and auto/idle responses
+    Revision:
+      eicq--main--0.7--patch-9
+
+    This fixes a bug that was causing Eicq to send the wrong auto-response
+    message when you had "idle'd" away/na.
+    
+    * eicq-status.el (eicq-statuses): Lets just call "na99" "na" and
+      "occ-mac" "occ".
+      (eicq-status-idle-reply): Make it return idle responses instead of auto
+      responses like it was.
+    
+
+    modified files:
+     eicq-status.el eicq.el
+
+
+2005-03-06 02:57:19 GMT        Steve Youngs <steve@eicq.org>   patch-8
+
+    Summary:
+      General tidy up.
+    Revision:
+      eicq--main--0.7--patch-8
+
+    General all-purpose tidy up.  Most of the stuff here is internal and
+    should go pretty much unnoticed.
+    
+    One user-visible change is that `h', `eicq-hide-window', now hides _all_
+    Eicq windows.  So when the boss walks in, hit `h' and all traces of Eicq
+    will vanish from view. :-)  `M-` w' brings it all back.
+    
+    The file eicq-comm.el has been removed.  I'm not sure if make upgrade
+    will delete it from the install dir, so you might have to rm it manually
+    from the install dir.
+    
+    * eicq.el (eicq-logout): Remove KILL arg, it isn't used anymore.
+    (eicq-disconnect): Call `eicq-logout' without any args.
+    (eicq-do-kicked-out): Ditto.  Hmm, does this function get used anymore?
+    (eicq-hide-window): Don't try hiding eicq-network-buffer, it doesn't exist.
+    Make it hide the buffers properly.  It used to leave the log or buddy,
+    whichever was current, now it hides em all!
+    (eicq-dropped-packet-counter): Moved here from the old eicq-comm.el
+    (eicq-resend-packet-counter): Ditto.
+    (eicq-recent-packet): Ditto.
+    (eicq-trimmed-packet-counter): Ditto.
+    (eicq-error-packets): Ditto.
+    (eicq-send-internal): Removed.  Not used anymore.
+    (eicq-user-password): Moved here from the old eicq-comm.el.
+    (eicq-send-queue-start): Removed.
+    (eicq-send-queue-stop): Removed.
+    (eicq-logout): Don't try to stop the send queue, it doesn't exist.
+    (eicq-disconnect): Don't call nonexistent `eicq-network-kill'.
+    (eicq-auto-reply-away): Eicq is the _(S)XEmacs_ ICQ client!
+    (eicq-auto-reply-occ): Ditto.
+    (eicq-auto-reply-dnd): Ditto.
+    (eicq-idle-reply-away): Ditto.
+    (eicq-idle-reply-na): Ditto.
+    
+    
+    * eicq-v8.el (eicq-debug-buffer): New.
+    
+    * eicq-v8.el (eicq-v8-debug): Use it.
+    
+    * eicq-menu.el (eicq-main-map): Don't define a key to switch to the
+      "network" buffer... there is none.
+    
+    * eicq-menu.el (eicq-main-menu): No menu entry for switching to network
+      buffer. 
+    
+    * *: Remove all the "Last-Modified" headers and local variables section
+      on all files.  They were the source of too many merge conflicts.
+    
+
+    removed files:
+     .arch-ids/eicq-comm.el.id eicq-comm.el
+
+    modified files:
+     eicq-buddy.el eicq-convert.el eicq-log.el eicq-menu.el
+     eicq-meta.el eicq-report.el eicq-setup.el eicq-status.el
+     eicq-toolbar.el eicq-v8.el eicq-wharf.el eicq-world.el eicq.el
+     eicq.texi
+
+
+2005-03-03 06:28:43 GMT        Steve Youngs <steve@eicq.org>   patch-7
+
+    Summary:
+      Automatically mark incoming msg's read on reply
+    Revision:
+      eicq--main--0.7--patch-7
+
+    * eicq.el (eicq-send-message-alias-around): Mark incoming messages
+      automatically when you reply to them with `m'.
+      (eicq-send-url-alias-around): Same here with replying with `u'.
+    
+
+    modified files:
+     eicq.el
+
+
+2005-03-03 02:26:34 GMT        Steve Youngs <steve@eicq.org>   patch-6
+
+    Summary:
+      Merged from lg@xwem.org--2005 (patch 5)
+    Revision:
+      eicq--main--0.7--patch-6
+
+    Patches applied:
+    
+     * lg@xwem.org--2005/eicq--lg--0.7--patch-5
+       merge from ckent, bug fixes, mark as read addon
+    
+    My additions...
+    
+    * eicq-toolbar.el (eicq-toolbar-disconnect): Don't call `eicq-logout'
+      here because `eicq-disconnect' calls it anyway.
+    
+    * eicq.el (eicq-logout): Make sure we run `eicq-v8-close'
+    
+
+    modified files:
+     eicq-log.el eicq-toolbar.el eicq-v8.el eicq.el
+
+    new patches:
+     lg@xwem.org--2005/eicq--lg--0.7--patch-5
+
+
+2005-03-02 00:56:28 GMT        Steve Youngs <steve@eicq.org>   patch-5
+
+    Summary:
+      log buffer fixes -- faces, fill-column, smilies.
+    Revision:
+      eicq--main--0.7--patch-5
+
+    * eicq-log.el (eicq-log-fill-column): Set to zero and make the custom
+      type integer.  The fill-column in the log buffer is now computed based
+      on the width of the frame, but it can be overridden if this in
+      non-zero. 
+      (eicq-log-mode): Calculate the fill-column based on the frame width.
+      If `eicq-log-fill-column' is non-zero, use that instead.
+      Also improve the modeline format for the log buffer.
+      (eicq-log): Set the extent face for buddy names in the log buffer
+      according to their status.
+      Smilify messages here instead of in `eicq-log-buddy-message' and use
+      `smiley-region' on the individual message rather than `smiley-buffer'.
+      This gives a considerable speed up when you have huge log buffers.
+      (eicq-log-buddy-message): Don't set smilies here.  Do it in
+      `eicq-log'. 
+    
+    * eicq-status.el (eicq-face-invisible): New face.
+      (eicq-face-offline): Removed.
+    
+    * eicq-status.el (eicq-statuses): Set the face for invisible to
+      `eicq-face-invisible' and the face for offline to nil.
+    
+    * eicq-status.el (eicq-buddy-update-status): Set the status before
+      logging it to ensure the correct face is used in the log buffer.
+    
+    * eicq-status.el (eicq-status-show-buffer): Use `eicq-log-face-invisible'
+      for the "[Invisible]" widget.
+    
+
+    modified files:
+     eicq-log.el eicq-status.el
+
+
+2005-02-28 00:01:58 GMT        Steve Youngs <steve@eicq.org>   patch-4
+
+    Summary:
+      Merged from lg@xwem.org--2005 (patch 2)
+    Revision:
+      eicq--main--0.7--patch-4
+
+    Patches applied:
+    
+     * lg@xwem.org--2005/eicq--lg--0.7--patch-2
+       send/recv fixes, world-update
+
+    modified files:
+     eicq-v8.el eicq-world.el eicq.el
+
+    new patches:
+     lg@xwem.org--2005/eicq--lg--0.7--patch-2
+
+
+2005-02-27 07:35:24 GMT        Steve Youngs <steve@eicq.org>   patch-3
+
+    Summary:
+      Remove the need to set `eicq-uin'
+    Revision:
+      eicq--main--0.7--patch-3
+
+    * eicq.el (eicq-login): Get eicq-uin from the world file like we did in
+      the old days.  This removes the requirement of setting eicq-uin.
+      (eicq-uin): Remove.  It isn't needed.
+    
+
+    modified files:
+     eicq.el
+
+
+2005-02-27 01:30:31 GMT        Steve Youngs <steve@eicq.org>   patch-2
+
+    Summary:
+      Merged from dev@xwem.org--2004-w (patch 1-2), lg@xwem.org--2005 (patch 1)
+    Revision:
+      eicq--main--0.7--patch-2
+
+    This change should mean that Eicq is once again usable!  You should be
+    able to log in and send/receive at least basic messages.
+    
+    You _will_ need to (setq eicq-uin 123456789) for your UIN at this stage.
+    That requirement will be removed in the very near future.
+    
+    Looks like we're back in business. :-)
+    
+    
+    Patches applied:
+    
+     * dev@xwem.org--2004-w/eicq--ckent--0.7--patch-1
+       eicq-v8 addons and fixes
+    
+     * dev@xwem.org--2004-w/eicq--ckent--0.7--patch-2
+       minor fixes
+    
+     * lg@xwem.org--2005/eicq--lg--0.7--patch-1
+       fixes, little restructurisation
+
+    modified files:
+     Makefile eicq-log.el eicq-status.el eicq-v8.el eicq-world.el
+     eicq.el
+
+    new patches:
+     dev@xwem.org--2004-w/eicq--ckent--0.7--patch-1
+     dev@xwem.org--2004-w/eicq--ckent--0.7--patch-2
+     lg@xwem.org--2005/eicq--lg--0.7--patch-1
+
+
+2004-12-31 22:51:52 GMT        Steve Youngs <steve@eicq.org>   patch-1
+
+    Summary:
+      Add ChangeLog from prev version, bump VER in Makefile
+    Revision:
+      eicq--main--0.7--patch-1
+
+
+    new files:
+     ChangeLog.d/.arch-ids/=id
+     ChangeLog.d/.arch-ids/ChangeLog-0.6.id
+     ChangeLog.d/ChangeLog-0.6
+
+    modified files:
+     Makefile
+
+    new directories:
+     ChangeLog.d ChangeLog.d/.arch-ids
+
+
+2004-12-31 21:39:09 GMT        Steve Youngs <steve@eicq.org>   base-0
+
+    Summary:
+      tag of steve@eicq.org--2004/eicq--main--0.6--patch-15
+    Revision:
+      eicq--main--0.7--base-0
+
+    (automatically generated log message)
+
+    new patches:
+     steve@eicq.org--2004/eicq--main--0.6--base-0
+     steve@eicq.org--2004/eicq--main--0.6--patch-1
+     steve@eicq.org--2004/eicq--main--0.6--patch-2
+     steve@eicq.org--2004/eicq--main--0.6--patch-3
+     steve@eicq.org--2004/eicq--main--0.6--patch-4
+     steve@eicq.org--2004/eicq--main--0.6--patch-5
+     steve@eicq.org--2004/eicq--main--0.6--patch-6
+     steve@eicq.org--2004/eicq--main--0.6--patch-7
+     steve@eicq.org--2004/eicq--main--0.6--patch-8
+     steve@eicq.org--2004/eicq--main--0.6--patch-9
+     steve@eicq.org--2004/eicq--main--0.6--patch-10
+     steve@eicq.org--2004/eicq--main--0.6--patch-11
+     steve@eicq.org--2004/eicq--main--0.6--patch-12
+     steve@eicq.org--2004/eicq--main--0.6--patch-13
+     steve@eicq.org--2004/eicq--main--0.6--patch-14
+     steve@eicq.org--2004/eicq--main--0.6--patch-15
+
+
diff --git a/ChangeLog.d/ChangeLog-0.8.Eicq b/ChangeLog.d/ChangeLog-0.8.Eicq
new file mode 100644 (file)
index 0000000..57da933
--- /dev/null
@@ -0,0 +1,773 @@
+# do not edit -- automatically generated by arch changelog
+# non-id: automatic-ChangeLog--steve@eicq.org--2005/eicq--main--0.8
+#
+
+2005-12-26 04:40:03 GMT        Steve Youngs <steve@eicq.org>   versionfix-1
+
+    Summary:
+      Oops, forgot to update the NEWS file.
+    Revision:
+      eicq--main--0.8--versionfix-1
+
+    * NEWS: Update.
+    
+
+    modified files:
+     NEWS
+
+
+2005-12-26 03:13:24 GMT        Steve Youngs <steve@eicq.org>   version-0
+
+    Summary:
+      Eicq 0.8 is released!
+    Revision:
+      eicq--main--0.8--version-0
+
+
+
+2005-11-20 13:40:16 GMT        Steve Youngs <steve@eicq.org>   patch-23
+
+    Summary:
+      Merged from lg (patch 3) -- BBDB build fix
+    Revision:
+      eicq--main--0.8--patch-23
+
+    This fixes a problem with trying to autoload `bbdb-records'.  My addition
+    to it is...
+    
+    * eicq-buddy.el: autoload `regexp-opt' at compile time.
+    
+    
+    
+    Patches applied:
+    
+     * lg@xwem.org--2005/eicq--lg--0.8--patch-3
+       eicq-buddy bbdb requirements fix
+
+    modified files:
+     eicq-buddy.el
+
+    new patches:
+     lg@xwem.org--2005/eicq--lg--0.8--patch-3
+
+
+2005-11-20 02:44:05 GMT        Steve Youngs <steve@eicq.org>   patch-22
+
+    Summary:
+      Merged from lg (patch 4) -- key bind fix
+    Revision:
+      eicq--main--0.8--patch-22
+
+    Unbind the old prefix key when you change it.
+    
+    Patches applied:
+    
+     * lg@xwem.org--2005/eicq--lg--0.8--patch-4
+       eicq-prefix-key customisation fix
+
+    modified files:
+     eicq.el
+
+    new patches:
+     lg@xwem.org--2005/eicq--lg--0.8--patch-4
+
+
+2005-11-20 01:30:13 GMT        Steve Youngs <steve@eicq.org>   patch-21
+
+    Summary:
+      Merged from lg (patch 1-2) -- Support Russian out of the box.
+    Revision:
+      eicq--main--0.8--patch-21
+
+    Patches applied:
+    
+     * lg@xwem.org--2005/eicq--lg--0.8--patch-1
+       Encoding translation added
+    
+     * lg@xwem.org--2005/eicq--lg--0.8--patch-2
+       track typo fix, encodings mess
+
+    modified files:
+     eicq-log.el eicq-track.el eicq.el
+
+    new patches:
+     lg@xwem.org--2005/eicq--lg--0.8--patch-1
+     lg@xwem.org--2005/eicq--lg--0.8--patch-2
+
+
+2005-10-20 03:20:12 GMT        Steve Youngs <steve@eicq.org>   patch-20
+
+    Summary:
+      Don't call `eicq-show-window' if auto-reconnecting.
+    Revision:
+      eicq--main--0.8--patch-20
+
+    I've been seeing this for a while.  If you lost your connection to ICQ
+    for some reason and Eicq does an auto-reconnect, `current-buffer' was
+    being left at `eicq-log-buffer' instead of the displayed buffer.
+    
+    This fairly trivial changes fixes that.
+    
+    * eicq.el (eicq-is-auto-reconnecting): New.  This is non-nil when Eicq is
+      in the process of performing an auto-reconnect.
+      (eicq-do-disconnect): Set `eicq-is-auto-reconnecting' to non-nil.
+      (eicq-do-login-confirm): Only call `eicq-show-window' if
+      `eicq-is-auto-reconnecting' is nil.
+    
+
+    modified files:
+     eicq.el
+
+
+2005-10-15 07:06:28 GMT        Steve Youngs <steve@eicq.org>   patch-19
+
+    Summary:
+      Eicq activity indicator in XWEM
+    Revision:
+      eicq--main--0.8--patch-19
+
+    This change means that XWEM users can put a sexy little activity
+    indicator in the XWEM systray.  See the top of eicq-xwem.el for the
+    no-brainer instructions on how to use it.
+    
+    * eicq-track.el (eicq-track-activity-hook): New hook.  It's called when
+      eicq-track adds to the modeline.
+      (eicq-track-clear-hook): New hook.  It's called when eicq-track clears
+      the modeline.
+      (eicq-track-add-nick): Run the `eicq-track-activity-hook' hooks.
+      (eicq-track-clear-modeline): Run the `eicq-track-clear-hook' hooks.
+    
+    * eicq-xwem.el: New file!  Put a sexy indicator icon into the XWEM
+      systray. 
+    
+    * Makefile (SOURCES): Add eicq-xwem.el
+    
+    * eicq-report.el: Something happened to one of the libs this needs... now
+      we need regexp-opt too.
+    
+    
+
+    new files:
+     .arch-ids/eicq-xwem.el.id eicq-xwem.el
+
+    modified files:
+     Makefile eicq-report.el eicq-track.el
+
+
+2005-09-20 17:04:17 GMT        Steve Youngs <steve@eicq.org>   patch-18
+
+    Summary:
+      Gutter updates -- "Online" button logs in if needed
+    Revision:
+      eicq--main--0.8--patch-18
+
+    * eicq-status.el (eicq-status-maybe-login): New.  For use with the
+      "Online" gutter button.  If you are offline, it'll log you in, if you
+      are online but set to another status like "away" it'll change your
+      status to "online".
+    
+    Also don't update the gutter every time there's a status change.  The
+    gutter wasn't updating properly anyway.  Once the gutter bugs are sorted
+    this will probably be put back in.
+    
+
+    modified files:
+     eicq-status.el
+
+
+2005-09-14 05:33:35 GMT        Steve Youngs <steve@eicq.org>   patch-17
+
+    Summary:
+      The Doctor is in!
+    Revision:
+      eicq--main--0.8--patch-17
+
+    This change means you can let your ICQ contact pyscho-analyze
+    themselves.  To enable it, set `eicq-doctor-enabled-flag' to `t'.  Then
+    when somebody sends you a message with ",,doctor" the doctor will begin
+    the therapy session.
+    
+    * eicq-doctor.el: New file.  Let your contacts pyscho-analyze
+      themselves. 
+    
+    * eicq-report.el (eicq-report-debug): Add eicq-doctor.el.
+    
+    * eicq.el (eicq-do-message-helper): Handle doctor messages.
+    
+    * Makefile (SOURCES): Add eicq-doctor.el.
+    
+    * TODO: Remove item about adding eicq-doctor.  The doctor is in!
+    
+
+    new files:
+     .arch-ids/eicq-doctor.el.id eicq-doctor.el
+
+    modified files:
+     Makefile TODO eicq-report.el eicq.el
+
+
+2005-09-13 04:18:18 GMT        Steve Youngs <steve@eicq.org>   patch-16
+
+    Summary:
+      Add an "oops" function
+    Revision:
+      eicq--main--0.8--patch-16
+
+    How many times have you `m some message here RET' only to discover that
+    it went to the wrong person?  Here is `eicq-oops'.  It sends the message
+    to the right person and a "oops" message to the wrong person.
+    
+    It is bound to `O' in the log buffer and you can customise the "oops"
+    message, see `eicq-oops-msg-wrong-recipient'.
+    
+    * eicq.el (eicq-oops-msg-wrong-recipient): New.  When you send a message
+      to the wrong person and then invoke `eicq-oops', this gets sent to the
+      original person as an explanation.
+      (eicq-oops): New.  Send an "oops" message to the wrong person and send
+      the original message to the right person.
+    
+    * eicq-menu.el (eicq-log-mode-map): Bind `O' to `eicq-oops'.
+      (eicq-log-menu): Add menu item for `eicq-oops'.
+    
+    * TODO: Remove item about implementing an `eicq-oops' function.
+    
+
+    modified files:
+     TODO eicq-menu.el eicq.el
+
+
+2005-09-10 17:17:50 GMT        Steve Youngs <steve@eicq.org>   patch-15
+
+    Summary:
+      Stop the status gutter appearing after `eicq-hide-windows'
+    Revision:
+      eicq--main--0.8--patch-15
+
+    This fixes a bug in the status gutter that was causing the gutter to
+    display when Eicq was supposedly hidden.
+    
+    * eicq.el (eicq-window-hidden-p): New.  Return non-nil if the Eicq
+      buffers are hidden.
+    
+    * eicq-status.el: Only run `eicq-update-tab-in-gutter' from
+      `eicq-status-update-hook' if the Eicq buffers aren't hidden.
+    
+
+    modified files:
+     eicq-status.el eicq.el
+
+
+2005-09-10 16:42:16 GMT        Steve Youngs <steve@eicq.org>   patch-14
+
+    Summary:
+      Better handling of switching between log and buddy buffers
+    Revision:
+      eicq--main--0.8--patch-14
+
+    * eicq.el (eicq-switch-buffer): New.  For switching between the log and
+      buddy buffers.
+      (eicq-show-window): Use it.
+      (eicq-switch-to-buddy-buffer): Moved here from eicq-buddy.el, uses
+      `eicq-switch-buffer'. 
+      (eicq-switch-to-log-buffer): New.
+    
+    * eicq-buddy.el (eicq-switch-to-buddy-buffer): Removed.  This is now in
+      eicq.el. 
+    
+    * eicq-menu.el (eicq-buddy-mode-map): Bind `o' to
+      `eicq-switch-to-log-buffer' instead of `other-window'.
+    
+
+    modified files:
+     eicq-buddy.el eicq-menu.el eicq.el
+
+
+2005-09-10 09:10:48 GMT        Steve Youngs <steve@eicq.org>   patch-13
+
+    Summary:
+      Fix `eicq-switch-to-buddy-buffer' when using status gutter
+    Revision:
+      eicq--main--0.8--patch-13
+
+    * eicq-buddy.el (eicq-switch-to-buddy-buffer): Allow for the possibility
+      of there being no status buffer.
+    
+
+    modified files:
+     eicq-buddy.el
+
+
+2005-09-10 04:04:22 GMT        Steve Youngs <steve@eicq.org>   patch-12
+
+    Summary:
+      Status gutter update
+    Revision:
+      eicq--main--0.8--patch-12
+
+    * eicq-status.el (eicq-status-tabs): Simplify a little, but it still
+      isn't doing the right thing. :-(
+    
+
+    modified files:
+     eicq-status.el
+
+
+2005-09-10 03:07:14 GMT        Steve Youngs <steve@eicq.org>   patch-11
+
+    Summary:
+      Status gutter updates.
+    Revision:
+      eicq--main--0.8--patch-11
+
+    This change fixes the problem of gutters showing up in other frames once
+    the Eicq status gutter was set.  It also adds an "Offline" tab and allows
+    the user to set the gutter to the top or bottom of the frame.  Setting
+    the gutter to the right or left is currently broken.
+    
+    * eicq-status.el (eicq-status-gutter-orientation): New user customisable
+      variable.  For setting the location of the status gutter.  Currently
+      only `top' and `bottom' work, while `right' and `left' are broken.
+      (eicq-status-tabs): Add a "Offline" tab.
+      (eicq-add-tab-to-gutter): New.
+      (eicq-update-tab-in-gutter): Use it.
+      Take out references to the global-buffers-tab stuff.
+    
+
+    modified files:
+     eicq-status.el
+
+
+2005-09-09 04:21:48 GMT        Steve Youngs <steve@eicq.org>   patch-10
+
+    Summary:
+      Make `eicq-hide-window' hide the status gutter too.
+    Revision:
+      eicq--main--0.8--patch-10
+
+    * eicq.el (eicq-show-window): Make the gutter visible if it's being
+      used. 
+      (eicq-hide-window): Hide the Eicq status gutter if it is being used.
+    
+
+    modified files:
+     eicq.el
+
+
+2005-09-09 01:30:15 GMT        Steve Youngs <steve@eicq.org>   patch-9
+
+    Summary:
+      Display status buffer info in a gutter
+    Revision:
+      eicq--main--0.8--patch-9
+
+    This allows you to have the info that is normally displayed in the
+    status buffer displayed in the gutter area instead.  Take care with this,
+    it is definitely "experimental" code and is still broken in a number of
+    ways. 
+    
+    To enable this, set `eicq-status-use-gutter' to `t'.
+    
+    * eicq-status.el (eicq-do-status-update): Run `eicq-status-update-hook'
+      _after_ the status has been changed.
+      (eicq-status-use-gutter): New.  When non-nil, display status switching
+      widgets in the gutter instead of in a buffer.
+      (eicq-status-gutter-tab): New.
+      (eicq-status-tabs): New.
+      (eicq-update-tab-in-gutter): New.
+    
+    * eicq.el (eicq-show-window): Use new status gutter code.
+    
+
+    modified files:
+     eicq-status.el eicq.el
+
+
+2005-09-04 02:10:32 GMT        Steve Youngs <steve@eicq.org>   patch-8
+
+    Summary:
+      Don't use Gnus for displaying Face colour glyphs
+    Revision:
+      eicq--main--0.8--patch-8
+
+    This takes away the need to have Gnus just to display those cute sexy
+    colour face glyphs.
+    
+    * eicq-buddy.el (eicq-face-to-png): New.
+      (eicq-buddy-show-xface): Use it.
+      Also, minor tweak to logic.
+    
+
+    modified files:
+     eicq-buddy.el
+
+
+2005-09-03 01:48:54 GMT        Steve Youngs <steve@eicq.org>   patch-7
+
+    Summary:
+      Update TODO
+    Revision:
+      eicq--main--0.8--patch-7
+
+    * TODO: Remove item about X-Face... it's done!
+    
+
+    modified files:
+     TODO
+
+
+2005-09-03 01:27:06 GMT        Steve Youngs <steve@eicq.org>   patch-6
+
+    Summary:
+      Display colour face images or X-Face images in buddy buffer
+    Revision:
+      eicq--main--0.8--patch-6
+
+    With this change, if a contact in your buddy buffer has a `cface' field
+    in their BBDB record, that image will be displayed.  If a contact has
+    both a `cface' and a X-Face, the cface will be displayed.  You can
+    reverse that preference by setting `eicq-buddy-prefer-cface-to-xface' to
+    nil. 
+    
+    * eicq-buddy.el (eicq-buddy-show-xface): Teeny tiny doc update.
+      (eicq-buddy-prefer-cface-to-xface): New.  If this is non-nil and a
+      contact has both an X-Face and a colour PNG face image, the colour one
+      will be displayed in the buddy buffer.
+      (eicq-buddy-show-xface): Possibly display colour face images.
+      Put some whitespace between the face image and the contact name.
+    
+    * README: Mention setting up X-Face and colour Face image display.
+    
+
+    modified files:
+     README eicq-buddy.el
+
+
+2005-09-02 06:33:51 GMT        Steve Youngs <steve@eicq.org>   patch-5
+
+    Summary:
+      Display X-Face images in buddy buffer
+    Revision:
+      eicq--main--0.8--patch-5
+
+    With this change you can optionally display X-Face images for the
+    contacts in the buddy buffer.  The data for the image comes from the
+    `face' field of the contact's BBDB record.
+    
+    To use this you have to add a new field to your BBDB records.  The new
+    field is called "icqnick" and its value is the alias/buddy name that is
+    used in the buddy buffer.
+    
+    As yet, there is no way to update your BBDB from within Eicq.  Maybe
+    later. :-)
+    
+    Once you have BBDB set up correctly, enable this new eye-candy in Eicq
+    with: 
+    
+         (setq eicq-buddy-show-xface t)
+    
+    * eicq-buddy.el (eicq-buddy-show-xface): New.  When non-nil, display
+      X-Face images in the buddy buffer.
+      (eicq-buddy-show-xface): New function for displaying X-Face images in
+      the buddy buffer.
+      (eicq-buddy-show-buffer): Use them.
+    
+
+    modified files:
+     eicq-buddy.el
+
+
+2005-07-09 22:01:22 GMT        Steve Youngs <steve@eicq.org>   patch-4
+
+    Summary:
+      Fix bug of trying to play undefined sounds
+    Revision:
+      eicq--main--0.8--patch-4
+
+    * eicq.el (eicq-maybe-play-sound): Check to see if sound TYPE is actually
+      defined before trying to play it.
+    
+
+    modified files:
+     eicq.el
+
+
+2005-06-22 13:31:54 GMT        Steve Youngs <steve@eicq.org>   patch-3
+
+    Summary:
+      Cleaner UI
+    Revision:
+      eicq--main--0.8--patch-3
+
+    This looks a bit nicer, so says my wife. :-)
+    
+    * eicq-status.el (eicq-status-window-height): Set to 8.  The status
+      buffer not having a modeline means we can make the buffer a little
+      smaller. 
+      (eicq-status-show-buffer): Turn off the modeline and don't set the
+      modeline format.
+    
+    * eicq-buddy.el (eicq-buddy-mode): Turn off the modeline and the
+      horizontal scrollbar.
+    
+
+    modified files:
+     eicq-buddy.el eicq-status.el
+
+
+2005-06-20 03:00:40 GMT        Steve Youngs <steve@eicq.org>   patch-2
+
+    Summary:
+      Old v5 protocol bitrot removal
+    Revision:
+      eicq--main--0.8--patch-2
+
+    This gets rid of hopefully all of the old stagnating v5 protocol code.
+    I've also added lots of "FIXME" comments, so if you're looking for
+    something to do... :-)
+    
+    * eicq.el (eicq-pretty-hex): Removed.
+      (eicq-bin-pretty-hex): Removed.
+      (eicq-redo-hex): Removed.
+      (eicq-hex-bin): Removed.
+      (eicq-byte-int): Removed.
+      (eicq-pack-contact-list): Removed.
+      (eicq-int-byte): Removed.
+      (eicq-pack-send-message): Removed.
+      (eicq-alias-bin): Removed.
+      (eicq-uin-bin): Removed.
+      (eicq-bin-uin): Removed.
+      (eicq-do-online): Commented out.  See FIXME comment about why I didn't
+      just nuke it entirely.
+      (eicq-do-new-account-uin): Ditto.
+      (eicq-do-search-random-user-found): Ditto.
+      (eicq-bin-ip): Removed.
+      (eicq-pack-v5): Removed.
+      (eicq-pack-keep-alive): Removed.
+      (eicq-pack-logout): Removed.
+      (eicq-pack-delete-offline-messages): Removed.
+      (eicq-pack-invisible-list): Removed.
+      (eicq-pack-visible-list): Removed.
+      (eicq-pack-register-new-user): Commented out.  See FIXME comment about
+      why I didn't just nuke it entirely.
+      (eicq-pack-search): Removed.
+      (eicq-pack-set-random-group): Commented out.  See FIXME comment about
+      why I didn't just nuke it entirely.
+      (eicq-pack-search-random-user): Ditto.
+      (eicq-pack-request-authorization): Ditto.
+      (eicq-pack-query-servers): Removed.
+      (eicq-pack-query-addons): Removed.
+      (eicq-pack-new-account-permission): Removed.
+      (eicq-pack-new-account-register): Removed.
+      (eicq-pack-cmd-x1): Removed.
+      (eicq-pack-send-message-to-foreigner): Removed.
+      (eicq-do-alist): Removed.
+      (eicq-do): Removed.
+      (eicq-do-ack): Removed.
+      (eicq-do-unknown): Commented out.  See FIXME comment about why I didn't
+      just nuke it entirely.
+      (eicq-do-wrong-password): Ditto.
+      (eicq-do-already-logged-in): Ditto.
+      (eicq-do-offline-message-complete): Removed.
+      (eicq-do-offline): Removed.
+      (eicq-do-system-message): Commented out.  See FIXME comment.
+      (eicq-do-update-info-confirm): Ditto.
+      (eicq-do-update-info-fail): Ditto.
+      (eicq-do-update-authorization-confirm): Ditto.
+      (eicq-do-update-authorization-fail): Ditto.
+      (eicq-do-update-info-ext-confirm): Ditto.
+      (eicq-do-query-servers-reply): Removed.
+      (eicq-do-multi): Removed.
+      (eicq-bin-alias): Removed.
+      (eicq-authorize): Add FIXME comment.
+      (eicq-register-new-user): Comment out.  Add FIXME comment.
+      (eicq-change-password): Ditto.
+      (eicq-search-random-user): Ditto.
+      (eicq-set-random-group): Ditto.
+      (eicq-delete-offline-messages-flag): Removed.  Doesn't look like v8
+      protocol gives you the choice to delete from the server or not.  Once
+      they are sent and acknowledged, that's it.
+      (eicq-do-disconnect): No need to test for whether the user wants to be
+      asked about deleting offline messages... he isn't.
+      (eicq-delete-offline-messages): Removed.  v8 doesn't do this.
+      (eicq-bin-hex): Removed.
+      (eicq-session-id): Removed.
+      (eicq-int-bin): Removed.
+      (eicq-send): Removed.
+      (eicq-network-filter): Removed.
+      (eicq-network-separator): Removed.
+      (eicq-bin-int): Removed.
+    
+    * eicq-meta.el (eicq-pack-meta-user-change-password): Removed.
+      (eicq-pack-meta-user-query): Removed.
+      (eicq-country-code): Removed.
+      (eicq-pack-meta-user-update-general): Commented out.  FIXME comment
+      added.
+      (eicq-pack-meta-user-security): Ditto.
+      (eicq-pack-meta-user-update-work): Ditto.
+      (eicq-pack-meta-user-update-more): Ditto.
+      (eicq-pack-meta-user-update-about): Ditto.
+      (eicq-do-meta-alist): Ditto.
+      (eicq-do-meta-user): Ditto.
+      (eicq-do-meta-user-unknown): Ditto.
+      (eicq-do-meta-user-general): Removed.
+      (eicq-do-meta-user-work): Removed.
+      (eicq-do-meta-user-more): Removed.
+      (eicq-do-meta-user-about): Removed.
+      (eicq-do-meta-user-interest): Removed.
+      (eicq-do-meta-user-background): Removed.
+      (eicq-do-meta-user-picture): Removed.
+      (eicq-do-meta-user-found): Removed.
+      (eicq-do-meta-user-update-general-confirm): Removed.
+      (eicq-do-meta-user-update-work-confirm): Removed.
+      (eicq-do-meta-user-update-more-confirm): Removed.
+      (eicq-do-meta-user-update-about-confirm): Removed.
+      (eicq-do-meta-user-update-security-confirm): Removed.
+      (eicq-do-meta-user-password): Removed.
+      (eicq-update-meta-info): Commented out.  FIXME comment
+      added. 
+    
+    * eicq-world.el (eicq-world-update): Don't setq eicq-user-bin.  Not used
+      anymore. 
+      (eicq-toolbar-update-info): Display a message stating this feature
+      isn't implemented yet.
+    
+
+    modified files:
+     eicq-meta.el eicq-toolbar.el eicq-world.el eicq.el
+
+
+2005-06-13 15:43:49 GMT        Steve Youngs <steve@eicq.org>   patch-1
+
+    Summary:
+      Prepare for 0.8 cycle, add previous ChangeLog file
+    Revision:
+      eicq--main--0.8--patch-1
+
+    * Makefile (VER): Bump to 0.8
+    
+    * NEWS: Prepare for 0.8
+    
+    * eicq.el: Mark version in file's header as 0.8
+    
+    * ChangeLog.d/ChangeLog-0.7: New.
+    
+
+    new files:
+     ChangeLog.d/.arch-ids/ChangeLog-0.7.id
+     ChangeLog.d/ChangeLog-0.7
+
+    modified files:
+     Makefile NEWS eicq.el
+
+
+2005-06-13 14:57:06 GMT        Steve Youngs <steve@eicq.org>   base-0
+
+    Summary:
+      tag of steve@eicq.org--2005/eicq--main--0.7--version-0
+    Revision:
+      eicq--main--0.8--base-0
+
+    (automatically generated log message)
+
+    new patches:
+     dev@xwem.org--2004-w/eicq--ckent--0.7--patch-1
+     dev@xwem.org--2004-w/eicq--ckent--0.7--patch-2
+     dev@xwem.org--2004-w/eicq--ckent--0.7--patch-3
+     karma@sxemacs.org--2005/eicq--karma--0.7--patch-1
+     karma@sxemacs.org--2005/eicq--karma--0.7--patch-2
+     karma@sxemacs.org--2005/eicq--karma--0.7--patch-4
+     lg@xwem.org--2005/eicq--lg--0.7--patch-1
+     lg@xwem.org--2005/eicq--lg--0.7--patch-2
+     lg@xwem.org--2005/eicq--lg--0.7--patch-5
+     lg@xwem.org--2005/eicq--lg--0.7--patch-8
+     lg@xwem.org--2005/eicq--lg--0.7--patch-9
+     lg@xwem.org--2005/eicq--lg--0.7--patch-12
+     lg@xwem.org--2005/eicq--lg--0.7--patch-13
+     lg@xwem.org--2005/eicq--lg--0.7--patch-14
+     lg@xwem.org--2005/eicq--lg--0.7--patch-16
+     lg@xwem.org--2005/eicq--lg--0.7--patch-18
+     lg@xwem.org--2005/eicq--lg--0.7--patch-19
+     lg@xwem.org--2005/eicq--lg--0.7--patch-20
+     lg@xwem.org--2005/eicq--lg--0.7--patch-21
+     lg@xwem.org--2005/eicq--lg--0.7--patch-23
+     lg@xwem.org--2005/eicq--lg--0.7--patch-28
+     steve@eicq.org--2004/eicq--main--0.6--base-0
+     steve@eicq.org--2004/eicq--main--0.6--patch-1
+     steve@eicq.org--2004/eicq--main--0.6--patch-2
+     steve@eicq.org--2004/eicq--main--0.6--patch-3
+     steve@eicq.org--2004/eicq--main--0.6--patch-4
+     steve@eicq.org--2004/eicq--main--0.6--patch-5
+     steve@eicq.org--2004/eicq--main--0.6--patch-6
+     steve@eicq.org--2004/eicq--main--0.6--patch-7
+     steve@eicq.org--2004/eicq--main--0.6--patch-8
+     steve@eicq.org--2004/eicq--main--0.6--patch-9
+     steve@eicq.org--2004/eicq--main--0.6--patch-10
+     steve@eicq.org--2004/eicq--main--0.6--patch-11
+     steve@eicq.org--2004/eicq--main--0.6--patch-12
+     steve@eicq.org--2004/eicq--main--0.6--patch-13
+     steve@eicq.org--2004/eicq--main--0.6--patch-14
+     steve@eicq.org--2004/eicq--main--0.6--patch-15
+     steve@eicq.org--2005/eicq--main--0.7--base-0
+     steve@eicq.org--2005/eicq--main--0.7--patch-1
+     steve@eicq.org--2005/eicq--main--0.7--patch-2
+     steve@eicq.org--2005/eicq--main--0.7--patch-3
+     steve@eicq.org--2005/eicq--main--0.7--patch-4
+     steve@eicq.org--2005/eicq--main--0.7--patch-5
+     steve@eicq.org--2005/eicq--main--0.7--patch-6
+     steve@eicq.org--2005/eicq--main--0.7--patch-7
+     steve@eicq.org--2005/eicq--main--0.7--patch-8
+     steve@eicq.org--2005/eicq--main--0.7--patch-9
+     steve@eicq.org--2005/eicq--main--0.7--patch-10
+     steve@eicq.org--2005/eicq--main--0.7--patch-11
+     steve@eicq.org--2005/eicq--main--0.7--patch-12
+     steve@eicq.org--2005/eicq--main--0.7--patch-13
+     steve@eicq.org--2005/eicq--main--0.7--patch-14
+     steve@eicq.org--2005/eicq--main--0.7--patch-15
+     steve@eicq.org--2005/eicq--main--0.7--patch-16
+     steve@eicq.org--2005/eicq--main--0.7--patch-17
+     steve@eicq.org--2005/eicq--main--0.7--patch-18
+     steve@eicq.org--2005/eicq--main--0.7--patch-19
+     steve@eicq.org--2005/eicq--main--0.7--patch-20
+     steve@eicq.org--2005/eicq--main--0.7--patch-21
+     steve@eicq.org--2005/eicq--main--0.7--patch-22
+     steve@eicq.org--2005/eicq--main--0.7--patch-23
+     steve@eicq.org--2005/eicq--main--0.7--patch-24
+     steve@eicq.org--2005/eicq--main--0.7--patch-25
+     steve@eicq.org--2005/eicq--main--0.7--patch-26
+     steve@eicq.org--2005/eicq--main--0.7--patch-27
+     steve@eicq.org--2005/eicq--main--0.7--patch-28
+     steve@eicq.org--2005/eicq--main--0.7--patch-29
+     steve@eicq.org--2005/eicq--main--0.7--patch-30
+     steve@eicq.org--2005/eicq--main--0.7--patch-31
+     steve@eicq.org--2005/eicq--main--0.7--patch-32
+     steve@eicq.org--2005/eicq--main--0.7--patch-33
+     steve@eicq.org--2005/eicq--main--0.7--patch-34
+     steve@eicq.org--2005/eicq--main--0.7--patch-35
+     steve@eicq.org--2005/eicq--main--0.7--patch-36
+     steve@eicq.org--2005/eicq--main--0.7--patch-37
+     steve@eicq.org--2005/eicq--main--0.7--patch-38
+     steve@eicq.org--2005/eicq--main--0.7--patch-39
+     steve@eicq.org--2005/eicq--main--0.7--patch-40
+     steve@eicq.org--2005/eicq--main--0.7--patch-41
+     steve@eicq.org--2005/eicq--main--0.7--patch-42
+     steve@eicq.org--2005/eicq--main--0.7--patch-43
+     steve@eicq.org--2005/eicq--main--0.7--patch-44
+     steve@eicq.org--2005/eicq--main--0.7--patch-45
+     steve@eicq.org--2005/eicq--main--0.7--patch-46
+     steve@eicq.org--2005/eicq--main--0.7--patch-47
+     steve@eicq.org--2005/eicq--main--0.7--patch-48
+     steve@eicq.org--2005/eicq--main--0.7--patch-49
+     steve@eicq.org--2005/eicq--main--0.7--patch-50
+     steve@eicq.org--2005/eicq--main--0.7--patch-51
+     steve@eicq.org--2005/eicq--main--0.7--patch-52
+     steve@eicq.org--2005/eicq--main--0.7--patch-53
+     steve@eicq.org--2005/eicq--main--0.7--patch-54
+     steve@eicq.org--2005/eicq--main--0.7--patch-55
+     steve@eicq.org--2005/eicq--main--0.7--patch-56
+     steve@eicq.org--2005/eicq--main--0.7--patch-57
+     steve@eicq.org--2005/eicq--main--0.7--patch-58
+     steve@eicq.org--2005/eicq--main--0.7--patch-59
+     steve@eicq.org--2005/eicq--main--0.7--patch-60
+     steve@eicq.org--2005/eicq--main--0.7--version-0
+
+
diff --git a/ChangeLog.d/ChangeLog-0.9.1.Eicq b/ChangeLog.d/ChangeLog-0.9.1.Eicq
new file mode 100644 (file)
index 0000000..7087b55
--- /dev/null
@@ -0,0 +1,1168 @@
+# do not edit -- automatically generated by arch changelog
+# arch-tag: automatic-ChangeLog--steve@eicq.org--2007/eicq--main--0.9.1
+#
+
+2007-11-13 05:30:37 GMT        Steve Youngs <steve@eicq.org>   version-0
+
+    Summary:
+      End of an era -- Last Eicq Release
+    Revision:
+      eicq--main--0.9.1--version-0
+
+    Sadly, this will be the last Eicq release.  But don't worry, because
+    we'll be back very soon in the form of EMchat.
+
+
+2007-11-07 02:39:45 GMT        Steve Youngs <steve@eicq.org>   patch-43
+
+    Summary:
+      Build chain fixes/improvements
+    Revision:
+      eicq--main--0.9.1--patch-43
+
+    This changeset improves the build chain, with most things now being
+    handled in build.el.
+    
+    * .arch-inventory: Add custom-defines.el and prepsrc.el to precious, also
+      make all .rej files unrecognized.
+    
+    * Makefile (GENERATED_SRC): New.  Lists the generated lisp.
+     (EXTRA_OBJ): Removed, in favour of $GENERATED_OBJ
+     (GENERATED_OBJ): New.  Lists the byte-compiled generated
+      lisp. 
+     (PRELOADS): Removed, now incorporated in build.el.
+     (all): Rewrite.
+     (compile): Rewrite.
+     (prepsrc.el): New target.
+     (prepsrc): New target.
+     (autoloads,customloads,auto-autoloads.el,custom-load.el): Removed.
+     (install): Use $GENERATED vars.
+     (pkg): Ditto.
+     (clean): Ditto.
+     (distclean): Also remove prepsrc.el
+    
+    * build.el: Incorporate the old Makefile $PRELOADS
+      Remove the hard-coded list of files to compile, this is now
+      auto-generated from the Makefile.
+
+    modified files:
+     .arch-inventory Makefile build.el
+
+
+2007-11-06 07:16:34 GMT        Steve Youngs <steve@sxemacs.org>        patch-42
+
+    Summary:
+      Fix the build, add some more error packets
+    Revision:
+      eicq--main--0.9.1--patch-42
+
+    This changeset fixes, and by "fixes" I of course mean "work around" a bug
+    in current SXEmacs that prevents Eicq from being built.
+    
+    Also here are some more error packets.
+    
+    * eicq-v8.el (eicq-v8-snac-srv-privacy-err): New packet, SNAC 9,1
+      (eicq-v8-snac-list): Add it.
+      (eicq-v8-valid-incoming-handlers): Add new handler type `srv-error'.
+      (eicq-v8-snac-list): Reorganise, throw in some comments.
+      (eicq-v8-snac-srv-err): Run an incoming handler and get the error
+      message in front of the user where it belongs.
+    
+    * eicq.el (eicq-do-srv-general-err): Handle SRV_GEN_ERR.
+      (eicq-login): Add srv-error handler type.
+    
+    * eicq-log.el: Autoload #'smiley-region instead of requiring smiley.
+      This works around a problem in current SXEmacs where you can't build
+      lisp with -batch.
+    
+
+    modified files:
+     eicq-log.el eicq-v8.el eicq.el
+
+
+2007-11-05 08:56:31 GMT        Steve Youngs <steve@sxemacs.org>        patch-41
+
+    Summary:
+      New packet (SNAC 3,1) and build chain tweaks
+    Revision:
+      eicq--main--0.9.1--patch-41
+
+    This changeset adds a new packet SRV_CONTACTERR (SNAC 3,1).  And it also
+    tweaks the build chain a bit, moving to a more pure elisp based chain.
+    
+    * eicq-v8.el (eicq-v8-fetch-uinlist): New fetcher.
+      (eicq-v8-snac-srv-contact-err): New packet.
+    
+    * eicq.el (eicq-do-srv-contact-err): New.
+    
+    * eicq.el (eicq-login): Add srv-contacterr handler.
+    
+    * build.el: New file to handle the build. elisp is easier to work with
+      for me than makefiles are.
+    
+    * eicq-curl.el (eicq-curl-post-hook): Use `t' instead of `otherwise' in
+      the #'cond call.  `otherwise' is broken in SXEmacs atm.
+    
+    * Makefile (all): Let the new build.el handle it.
+    
+    * Makefile (autoloads): Ditto.
+    
+
+    new files:
+     .arch-ids/build.el.id build.el
+
+    modified files:
+     Makefile eicq-curl.el eicq-v8.el eicq.el
+
+
+2007-09-21 23:19:35 GMT        Steve Youngs <steve@eicq.org>   patch-40
+
+    Summary:
+      Fix sloppy text emphasis
+    Revision:
+      eicq--main--0.9.1--patch-40
+
+    * eicq-log.el (eicq-log-mode-syntax-table): Don't include the emphasis
+      tags as word-constituents.
+    
+
+    modified files:
+     eicq-log.el
+
+
+2007-09-05 01:51:02 GMT        Steve Youngs <steve@eicq.org>   patch-39
+
+    Summary:
+      Humanise eicq-curl output
+    Revision:
+      eicq--main--0.9.1--patch-39
+
+    This changeset makes the output from eicq-curl a bit nicer.  File sizes
+    and transfer speeds are shown in gigabytes, megabytes, kilobytes, bytes,
+    depending on size/speed.
+    
+    * eicq-curl.el (eicq-curl-post-hook): Show size and speed in a more human
+      readable form.
+    
+
+    modified files:
+     eicq-curl.el
+
+
+2007-09-03 10:09:33 GMT        Steve Youngs <steve@eicq.org>   patch-38
+
+    Summary:
+      More history tweaks plus nuke insane keybindings
+    Revision:
+      eicq--main--0.9.1--patch-38
+
+    * eicq-log.el (eicq-log-update-history): Make sure !debug, !error, !info,
+      !debug histories are still tracked.
+    
+    * eicq-menu.el (eicq-main-map): Remove the silly `1' and `2' keybindings.
+    
+
+    modified files:
+     eicq-log.el eicq-menu.el
+
+
+2007-09-03 07:37:42 GMT        Steve Youngs <steve@eicq.org>   patch-37
+
+    Summary:
+      Block more boring stuff from the history files.
+    Revision:
+      eicq--main--0.9.1--patch-37
+
+    This and the previous changeset should reduce the amount of useless crap
+    spamming your history files.  Status changes aren't tracked in the
+    history files and no history is saved for people you should be invisible
+    to. 
+    
+    * eicq-log.el (eicq-log-update-history): Don't save histories for people
+      you should be invisible to.
+    
+
+    modified files:
+     eicq-log.el
+
+
+2007-09-03 07:05:24 GMT        Steve Youngs <steve@eicq.org>   patch-36
+
+    Summary:
+      Don't log status changes in the history files
+    Revision:
+      eicq--main--0.9.1--patch-36
+
+    * eicq-log.el (eicq-log-update-history): Don't notice status changes and
+      other boring things in the history files.
+    
+
+    modified files:
+     eicq-log.el
+
+
+2007-09-01 12:08:04 GMT        Steve Youngs <steve@eicq.org>   patch-35
+
+    Summary:
+      Fix a byte-compiler warning
+    Revision:
+      eicq--main--0.9.1--patch-35
+
+    * eicq-curl.el: Fix byte-compiler warning.
+    
+
+    modified files:
+     eicq-curl.el
+
+
+2007-09-01 12:03:44 GMT        Steve Youngs <steve@eicq.org>   patch-34
+
+    Summary:
+      Enhance eicq-curl output
+    Revision:
+      eicq--main--0.9.1--patch-34
+
+    This changeset takes advantage of the brand new `worker job plists' just
+    introduced into SXEmacs.  It gives the output to the log buffer a little
+    more verbosity.  Gotta love eye-candy.
+    
+    * eicq-curl.el (eicq-curl-post-hook): Make the output more verbose using
+      data from the job's plist.
+      (eicq-curl-filename-regexp): Make it a defregexp if in SXEmacs.
+      (eicq-curl-url-at-point): No need to set a global var for the url, it
+      is now accessible via the job's plist.
+      (eicq-curl-url-at-mouse): Ditto.
+    
+
+    modified files:
+     eicq-curl.el
+
+
+2007-09-01 03:00:30 GMT        Steve Youngs <steve@eicq.org>   patch-33
+
+    Summary:
+      _Really_ fix emphasis
+    Revision:
+      eicq--main--0.9.1--patch-33
+
+    This changeset hopefully completely fixes emphasis, and makes it a lot
+    better.  Emphasising text that includes punctuation will now work.
+    
+    
+    * eicq-log.el (eicq-log-mode-syntax-table): New.  Same as
+      `text-mode-syntax-table' except all the punctuation chars are word
+      constituents.  This lets emphasis work when punctuation is used within
+      the emphasised tags.
+      (eicq-log-mode): Use it.
+      (eicq-log-update-tracker): Allow for the informational messages now
+      being prefixed with `***|' instead of `***'.
+    
+    * eicq-status.el (eicq-buddy-update-status): Prefix messages with `***|'
+      instead of `***' to cater for the emphasis changes.
+      (eicq-turn-on-invisibility): Ditto.
+      (eicq-turn-off-invisibility): Ditto.
+    
+
+    modified files:
+     eicq-log.el eicq-status.el
+
+
+2007-09-01 01:47:51 GMT        Steve Youngs <steve@eicq.org>   patch-32
+
+    Summary:
+      Fix log eye-candy.
+    Revision:
+      eicq--main--0.9.1--patch-32
+
+    This changeset fixes the bug where if you emphasised some text that
+    contained punctuation... the emphasis would not be added.
+    
+    * eicq-log.el (eicq-log-mode): Use text-mode's syntax-table
+    
+
+    modified files:
+     eicq-log.el
+
+
+2007-09-01 00:29:32 GMT        Steve Youngs <steve@eicq.org>   patch-31
+
+    Summary:
+      Forgot to actually add the new files :-(
+    Revision:
+      eicq--main--0.9.1--patch-31
+
+
+    new files:
+     .arch-ids/eicq-curl.el.id .arch-ids/eicq-utils.el.id
+     eicq-curl.el eicq-utils.el
+
+
+2007-09-01 00:10:14 GMT        Steve Youngs <steve@eicq.org>   patch-30
+
+    Summary:
+      Fix upgrade Makefile target.
+    Revision:
+      eicq--main--0.9.1--patch-30
+
+    * Makefile (upgrade): Do a distclean here first.
+    
+
+    modified files:
+     Makefile
+
+
+2007-08-31 23:56:33 GMT        Steve Youngs <steve@eicq.org>   patch-29
+
+    Summary:
+      Implement URL downloading from log buffer + minor build tweaks
+    Revision:
+      eicq--main--0.9.1--patch-29
+
+    This changeset allows for downloading URLs in the log buffer to files
+    locally via #'curl:download&.  OK, that means you need SXEmacs for this
+    to work.
+    
+    There are also some minor build tweaks and rearrangements.
+    
+    * Makefile (SOURCES): Add eicq-utils.el, eicq-curl.el.
+    
+    * eicq-emphasis.el (eicq-emphasis-alist): Hide the `*' bold tags.
+    
+    * eicq-log.el: Require eicq-curl.
+      (eicq-log-system): Run the eicq-system-message hooks here.
+    
+    * eicq-menu.el: Require eicq-utils, change all define-keys to use #'func
+      naming syntax.
+      (eicq-hyperlink-map): Add bindings for eicq-curl.
+    
+    * eicq-report.el (eicq-report-debug): Add eicq-curl.el.
+    
+    * eicq-xwem.el: Add our secret bug-reporter "cookie".
+    
+    * eicq.el: Require eicq-utils.
+      (eicq-do-in-xemacs): Moved to eicq-utils.el
+      (eicq-do-in-sxemacs): Ditto.
+      (eicq-completing-read): Ditto.
+      (eicq-numeric-uin): Ditto.
+      (eicq-stringular-uin): Ditto.
+      (eicq-valid-uin-p): Ditto.
+      (eicq-completing-aliases): Ditto.
+      (eicq-completing-alias): Ditto.
+      (eicq-switch-buffer): Ditto.
+    
+    * eicq-curl.el: New.  Download URLs from the log buffer.
+    
+    * eicq-utils.el: New.  Where any general utils should go.
+
+    modified files:
+     Makefile eicq-emphasis.el eicq-log.el eicq-menu.el
+     eicq-report.el eicq-xwem.el eicq.el
+
+
+2007-08-18 06:44:07 GMT        Steve Youngs <steve@eicq.org>   patch-28
+
+    Summary:
+      Stop server from dropping parts of large outgoing msgs
+    Revision:
+      eicq--main--0.9.1--patch-28
+
+    This changeset makes it possible to send very long messages without the
+    server dropping part or all of the message.
+    
+    * eicq.el (eicq-message-max-size): Increase to 500.
+      (eicq-splitter):  This was renamed from `eicq-spliter'.
+      (eicq-send-message): Add a delay between message parts of a large
+      message so that the server doesn't drop part or all of the sent
+      message. 
+    
+
+    modified files:
+     eicq.el
+
+
+2007-08-17 22:13:52 GMT        Steve Youngs <steve@eicq.org>   patch-27
+
+    Summary:
+      Guard against empty slots creeping into eicq-(in)visible-contacts list
+    Revision:
+      eicq--main--0.9.1--patch-27
+
+    * eicq.el (eicq-remove-from-visible-list): Don't leave empty slots in the
+      list.
+      (eicq-remove-from-invisible-list): Ditto.
+    
+
+    modified files:
+     eicq.el
+
+
+2007-08-16 14:43:32 GMT        Steve Youngs <steve@eicq.org>   patch-26
+
+    Summary:
+      Add some sexiness to the balloon-help buffers.
+    Revision:
+      eicq--main--0.9.1--patch-26
+
+    Pure eye-candy!
+    
+    * eicq-buddy.el (eicq-buddy-show-xface-in-balloon): New.  For displaying
+      X-Face images in balloon-help.
+      (balloon-help-display-help): Advised to insert the X-Face image.
+      (eicq-buddy-update-face): Slightly modify the balloon-help text to
+      cater for X-Face images.  Basically add a bit of whitespace at the
+      end. 
+    
+    * eicq-log.el (eicq-log-update-balloon): Ditto.
+    
+
+    modified files:
+     eicq-buddy.el eicq-log.el
+
+
+2007-08-14 02:47:23 GMT        Steve Youngs <steve@eicq.org>   patch-25
+
+    Summary:
+      Improve automatic/idle messages
+    Revision:
+      eicq--main--0.9.1--patch-25
+
+    This changeset improves and enhances the automatic messages, stuff like
+    the auto response you send out when you receive a msg while you are away,
+    na, dnd, or occ.
+    
+    These outgoing messages are now sent as `automatic' message type.  Care
+    has been taken to ensure that only people who are on your visible list or
+    not on your invisible list will ever get these messages.
+    
+    We now handle incoming `automatic' messages, as well as incoming requests
+    for your away, na, dnd, occ message.
+    
+    Also, you can now request that an ICQ user's client send you its away,
+    na, dnd, or occ message.
+    
+    New user functions:
+    ==================
+    
+        #'eicq-request-away -- Request a user's away message.
+        #'eicq-request-na   -- Request a user's na message.
+        #'eicq-request-dnd  -- Request a user's dnd message.
+        #'eicq-request-occ  -- Request a user's occ message.
+    
+    
+    * eicq.el (eicq-message-types): Removed.  Obsolete.
+      (eicq-pack-add-user-to-contact-list): Ditto.
+      (eicq-idle-reply-maybe): Ensure idle replies don't go out to members of
+      your invisible list or those not on your visible list.
+      (eicq-do-message-helper): Add `automatic', `get-away', `get-na',
+      `get-occ', `get-dnd' message types.
+      (eicq-auto-reply): Send as `automatic' message type.
+      (eicq-idle-reply): Ditto.
+      (eicq-request-away): New.  Request a contact's "away" message.
+      (eicq-request-na): Ditto, "na" message.
+      (eicq-request-dnd): Ditto. "dnd" message.
+      (eicq-request-occ): Ditto. "occ" message.
+    
+
+    modified files:
+     eicq.el
+
+
+2007-08-12 23:54:55 GMT        Steve Youngs <steve@eicq.org>   patch-24
+
+    Summary:
+      Sound enhancement... customisable media driver
+    Revision:
+      eicq--main--0.9.1--patch-24
+
+    This changeset gives SXEmacs users the option of specifying a driver to
+    use for creating the media streams.  It also gives me a way to work
+    around a problem I currently have with ffmpeg. :-)
+    
+    * eicq.el (eicq-media-driver): New.  To specify the driver to use when
+      creating the streams.
+      (eicq-load-media-streams): Use it.
+    
+
+    modified files:
+     eicq.el
+
+
+2007-08-11 15:03:41 GMT        Steve Youngs <steve@eicq.org>   patch-23
+
+    Summary:
+      Fix auto reply message sending in regards to visible/invisible lists.
+    Revision:
+      eicq--main--0.9.1--patch-23
+
+    * eicq.el (eicq-auto-reply-maybe): Don't send auto replies to people who
+      should be unable to see you on the network.
+    
+
+    modified files:
+     eicq.el
+
+
+2007-08-11 14:03:51 GMT        Steve Youngs <steve@sxemacs.org>        patch-22
+
+    Summary:
+      Introduce visible/invisible lists
+    Revision:
+      eicq--main--0.9.1--patch-22
+
+    This changeset introduces "visible" and "invisible" lists to Eicq.  If
+    you have contacts on a visible list, then anyone who _isn't_ on the list
+    will not be able to see you on the ICQ network.  Likewise for a invisible
+    list, anyone _not_ on the list _can_ see you.
+    
+    The default setting is to have no invisible list, and to have all of your
+    contacts in eicq-world on your visible list.  This means that only people
+    on your contact list will be able to see you.  If you want to be
+    invisible to someone in your contact list, just add them to your
+    invisible list.  They can remain on your visible list without causing any
+    problems because the invisible list is sent _after_ the visible.
+    
+    New user-customisable variables...
+    
+        eicq-visible-contacts   -- Defaults to all contacts in eicq-world, most
+                                   users probably won't need to change this.
+    
+        eicq-invisible-contacts -- Defaults to nil.  Put your idiots here.
+    
+    New user commands...
+    
+        #'eicq-add-to-visible-list
+        #'eicq-add-to-invisible-list
+        #'eicq-remove-from-visible-list
+        #'eicq-remove-from-invisible-list
+    
+    * eicq-v8.el (eicq-v8-snac-cli-addvisible): New.  Add contacts to visible
+      list.
+      (eicq-v8-snac-cli-remvisible): New.  Remove contacts from visible list.
+      (eicq-v8-snac-cli-addinvisible): New.  Add contacts to invisible list.
+      (eicq-v8-snac-cli-reminvisible): New.  Remove contacts from invisible
+      list. 
+      (eicq-v8-snac-list): Add visible/invisible packets.
+    
+    * eicq.el (eicq-visible-contacts): New.  List of contacts that are added
+      to the "visible" list at login.  Default is everyone on your contact
+      list.
+      (eicq-invisible-contacts): New.  As above, but for the "invisible"
+      list.
+      (eicq-send-contact-list): Send visible/invisible lists.
+      (eicq-init-visible-list): Used to initialise `eicq-visible-contacts'.
+      (eicq-add-to-visible-list): New.  Interactively add contacts to visible
+      list.
+      (eicq-add-to-invisible-list): New.  As above, but for invisible list.
+      (eicq-remove-from-visible-list): New.  Interactively remove contacts
+      from visible list.
+      (eicq-remove-from-invisible-list): New.  As above, but for invisible
+      list.
+    
+    
+
+    modified files:
+     eicq-v8.el eicq.el
+
+
+2007-08-09 09:29:30 GMT        Steve Youngs <steve@eicq.org>   patch-21
+
+    Summary:
+      Fix type 4 messages
+    Revision:
+      eicq--main--0.9.1--patch-21
+
+    This changeset fixes type 4 messages... things like URL messages and auth
+    request/accept/reject.  The TLVs in these messages are now coming from
+    the server in reverse order.  Gotta love them AOL lunatics.
+    
+    * eicq-v8.el (eicq-v8-snac-srv-recv-msg): Reverse the tlv list for type 4
+      messages.
+    
+
+    modified files:
+     eicq-v8.el
+
+
+2007-08-08 15:14:10 GMT        Steve Youngs <steve@eicq.org>   patch-20
+
+    Summary:
+      Protect uninitialised defvar's
+    Revision:
+      eicq--main--0.9.1--patch-20
+
+    This changeset protects all the uninitialised defvar's from the
+    interpreter by wrapping them in a #'eval-when-compile.
+    
+    * eicq.el: Move all uninitialised defvar's under a #'eval-when-compile.
+    
+    * eicq-log.el: Ditto.
+    
+    * eicq-world.el: Ditto.
+    
+
+    modified files:
+     eicq-log.el eicq-world.el eicq.el
+
+
+2007-08-08 01:08:58 GMT        Steve Youngs <steve@eicq.org>   patch-19
+
+    Summary:
+      Sound fix... make sure the stream symbols get created
+    Revision:
+      eicq--main--0.9.1--patch-19
+
+    This changeset fixes a problem introduced with Sebastian's last change.
+    If the media stream symbols did not already exist, they would never be
+    created. 
+    
+    * eicq.el (eicq-load-media-streams): Use #'intern instead of
+      #'intern-soft.  This time we _want_ the symbol to be created.
+    
+
+    modified files:
+     eicq.el
+
+
+2007-08-08 00:02:56 GMT        Steve Youngs <steve@eicq.org>   patch-18
+
+    Summary:
+      Minor tweak to the sound.
+    Revision:
+      eicq--main--0.9.1--patch-18
+
+    * eicq.el (eicq-login): Don't call #'eicq-load-media-streams
+      interactively.
+
+    modified files:
+     eicq.el
+
+
+2007-08-07 22:26:53 GMT        Steve Youngs <steve@eicq.org>   patch-17
+
+    Summary:
+      Merged from hrop (patch 4) -- sound fix
+    Revision:
+      eicq--main--0.9.1--patch-17
+
+    Patches applied:
+    
+     * hroptatyr@eicq.org--eicq/eicq--hrop--0.9.1--patch-4
+       fix, bind stream symbol rather than the stream object
+
+    modified files:
+     eicq.el
+
+    new patches:
+     hroptatyr@eicq.org--eicq/eicq--hrop--0.9.1--patch-4
+
+
+2007-08-07 14:12:02 GMT        Steve Youngs <steve@eicq.org>   patch-16
+
+    Summary:
+      Sound fixes/improvements
+    Revision:
+      eicq--main--0.9.1--patch-16
+
+    This changeset fixes hopefully the last of the sound issues.  It also
+    allows SXEmacs users to specify a separate audio device for Eicq.  For
+    example, a SXEmacs user with PulseAudio might...
+    
+    ,----[ example ]
+    | (setq eicq-audio-device
+    |       (make-audio-device 'pulse :server "some.remote.host"
+    |                                 :client "SXEmacs::Eicq" 
+    |                                 :stream "Eicq::Stream"
+    |                                 :force t))
+    `----
+    
+    * eicq.el (eicq-audio-device): New.  The audio device where we play
+      sounds in SXEmacs.  Defaults to `default-audio-device'.
+      (eicq-play-sound-maybe): Use it.  Plus, guard against unbound symbols.
+      (eicq-load-media-streams): Guard against unbound symbols.
+    
+
+    modified files:
+     eicq.el
+
+
+2007-08-07 04:40:09 GMT        Steve Youngs <steve@eicq.org>   patch-15
+
+    Summary:
+      More sound fixes fixing the last fix.
+    Revision:
+      eicq--main--0.9.1--patch-15
+
+    This changeset some minor fixes to the new sound stuff, and we stop
+    getting the user's home directory from the environment, instead we use
+     #'user-home-directory. 
+    
+    * eicq.el (eicq-directory): Use #'user-home-directory instead of env var
+      $HOME. 
+      (eicq-load-media-streams): Use #'intern-soft when testing if the stream
+      exists so we don't create the symbol unneccessarily.
+      (eicq-play-sound-maybe): Use #'intern-soft instead of #'intern for the
+      same reason.
+      (eicq-login): Load the media streams.
+    
+    * eicq-convert.el (eicq-import-from-micq): Use #'user-home-directory
+      instead of env var $HOME.
+    
+    * Makefile: Nuke a stupid comment.
+    
+
+    modified files:
+     Makefile eicq-convert.el eicq.el
+
+
+2007-08-07 02:40:08 GMT        Steve Youngs <steve@eicq.org>   patch-14
+
+    Summary:
+      Sound improvements/fixes
+    Revision:
+      eicq--main--0.9.1--patch-14
+
+    This changeset vastly improves the sound code for Eicq on SXEmacs.  In
+    days of olde we'd create each media stream on the fly, _every_ time a
+    sound was played.  Not only was that incredibly inefficient, but it was
+    possible for SXEmacs to dump core if too many sounds were played
+    simultaneously because the garbage collector was getting in a tizzy over
+    it.
+    
+    What we do now is create all the needed media streams _once_ and save
+    them for future use.  This reduces the amount of processing required
+    because we're only creating each stream once instead of every time a
+    sound is played.  But more importantly, saving the streams prevents them
+    from being gc'd away.
+    
+    There's also a couple of minor build time fixes.
+    
+    * eicq.el (eicq-use-sound-flag): Switch it to a normal boolean var.
+      (eicq-play-sound-maybe): New.  Renamed from `eicq-maybe-play-sound'.
+      This version doesn't create media streams on the fly in SXEmacs as they
+      are already created/loaded.
+      (eicq-do-message-helper): Use #'eicq-play-sound-maybe instead of
+      #'eicq-maybe-play-sound. 
+      (eicq-load-media-streams): New.  Loads/saves the media streams in
+      SXEmacs.  This lets the streams be created once or when you explicitly
+      want them recreated.  Saves us a truck load of processing time, and is
+      a hell of a lot safer.
+    
+    * eicq-status.el (eicq-buddy-update-status): Use #'eicq-play-sound-maybe
+      instead of #'eicq-maybe-play-sound.
+    
+    * eicq-xwem.el: Add some missing autoloads at compile time.
+    
+
+    modified files:
+     eicq-status.el eicq-xwem.el eicq.el
+
+
+2007-07-21 15:00:23 GMT        Steve Youngs <steve@eicq.org>   patch-13
+
+    Summary:
+      Merged from lg (patch 9) -- couple of minor fixes
+    Revision:
+      eicq--main--0.9.1--patch-13
+
+    Patches applied:
+    
+     * lg@xwem.org--2007/eicq--lg--0.9--patch-9
+       small fixes
+
+    modified files:
+     eicq-v8.el eicq.el
+
+    new patches:
+     lg@xwem.org--2007/eicq--lg--0.9--patch-9
+
+
+2007-07-09 13:38:07 GMT        Steve Youngs <steve@eicq.org>   patch-12
+
+    Summary:
+      Fix unnecessary spamming of log buffer during login
+    Revision:
+      eicq--main--0.9.1--patch-12
+
+    This changeset fixes a problem AOL introduced today that was causing
+    every contact in your contact list to be logged as "offline" when you
+    logged in.  Reasonably harmless, but very annoying.
+    
+    * eicq-status.el (eicq-buddy-update-status): Work around the latest
+      protocol change.
+    
+
+    modified files:
+     eicq-status.el
+
+
+2007-06-30 15:54:21 GMT        Steve Youngs <steve@eicq.org>   patch-11
+
+    Summary:
+      Improve explanation of world syntax
+    Revision:
+      eicq--main--0.9.1--patch-11
+
+    * eicq-setup.el (eicq-world-user-file-template): Improve wording and
+      syntax explanation.
+    
+    * INSTALL: Include a copy of the template world file from eicq-setup.el
+    
+
+    modified files:
+     INSTALL eicq-setup.el
+
+
+2007-05-01 16:03:40 GMT        Steve Youngs <steve@eicq.org>   patch-10
+
+    Summary:
+      Merged from lg (patch 5) - XWEM OSD update
+    Revision:
+      eicq--main--0.9.1--patch-10
+
+    Patches applied:
+    
+     * lg@xwem.org--2007/eicq--lg--0.9--patch-5
+       more features for OSD, dock now optional
+
+    modified files:
+     eicq-xwem.el
+
+    new patches:
+     lg@xwem.org--2007/eicq--lg--0.9--patch-5
+
+
+2007-04-24 23:34:26 GMT        Steve Youngs <steve@eicq.org>   patch-9
+
+    Summary:
+      Merged from lg (patch 4) -- XWEM dock update.
+    Revision:
+      eicq--main--0.9.1--patch-9
+
+    Patches applied:
+    
+     * lg@xwem.org--2007/eicq--lg--0.9--patch-4
+       Adds keymap to dock and creates messages OSD.
+
+    modified files:
+     eicq-v8.el eicq-xwem.el
+
+    new patches:
+     lg@xwem.org--2007/eicq--lg--0.9--patch-4
+
+
+2007-02-08 09:44:40 GMT        Steve Youngs <steve@eicq.org>   patch-8
+
+    Summary:
+      Fix alias selection/deselection
+    Revision:
+      eicq--main--0.9.1--patch-8
+
+    This changeset fixes alias/buddy selection, making it possible to
+    deselect a selected alias
+    
+    * eicq-world.el (eicq-group-select-aliases): Fix select/deselect
+      aliases. 
+    
+
+    modified files:
+     eicq-world.el
+
+
+2007-02-05 01:16:24 GMT        Steve Youngs <steve@eicq.org>   patch-7
+
+    Summary:
+      Play system sound when SRV_MISSED_ICBM comes in.
+    Revision:
+      eicq--main--0.9.1--patch-7
+
+    * eicq.el (eicq-do-message-helper): Play a sound for missed messages.
+    
+
+    modified files:
+     eicq.el
+
+
+2007-02-05 00:52:42 GMT        Steve Youngs <steve@eicq.org>   patch-6
+
+    Summary:
+      Tweak missed message handling, call the hook with args.
+    Revision:
+      eicq--main--0.9.1--patch-6
+
+    This changeset improves the handling of missed messages a bit.  The hook,
+    `eicq-missed-message-hook' is now called with ALIAS, NUM, REASON as args
+    using `run-hook-with-args'.
+    
+    * eicq.el (eicq-do-missed-message): Rename local var UIN -> ALIAS, makes
+      more sense to me.
+      Call `eicq-missed-message-hook' using `run-hook-with-args' and pass
+      along ALIAS, NUM, and REASON.
+      (eicq-missed-message-hook): Document the args passed.
+    
+
+    modified files:
+     eicq.el
+
+
+2007-02-04 23:23:32 GMT        Steve Youngs <steve@eicq.org>   patch-5
+
+    Summary:
+      Merged from lg (patch 2-3) -- Handle SRV_MISSED_ICBM SNAC(4, 10)
+    Revision:
+      eicq--main--0.9.1--patch-5
+
+    This changeset implements SRV_MISSED_ICBM SNAC(4, 10).  This is the
+    packet you get if incoming messages exceed your rate limit.  It also
+    runs a `eicq-missed-messages-hook' which can be used to send a "please
+    resend" back to the sender if you want.
+    
+    * eicq.el (eicq-do-missed-message): Add message type arg to
+      `eicq-do-message-helper' call.
+      Send a "please resend" message back to the sender.
+      (eicq-do-message-helper): Handle SRV_MISSED_ICBM SNAC 4, 10.
+      (eicq-missed-message-hook): New hook run from
+      `eicq-do-missed-message'. 
+    
+    Patches applied:
+    
+     * lg@xwem.org--2007/eicq--lg--0.9--patch-2
+       SNAC(4, 10), however needs review and fix by Steve
+    
+     * lg@xwem.org--2007/eicq--lg--0.9--patch-3
+       fix fetching tlvs in snac 4, 10
+
+    modified files:
+     eicq-v8.el eicq.el
+
+    new patches:
+     lg@xwem.org--2007/eicq--lg--0.9--patch-2
+     lg@xwem.org--2007/eicq--lg--0.9--patch-3
+
+
+2007-02-04 03:48:50 GMT        Steve Youngs <steve@eicq.org>   patch-4
+
+    Summary:
+      Better default for eicq-coding-system
+    Revision:
+      eicq--main--0.9.1--patch-4
+
+    This changeset should make the Russians, Europeans, and Aussies happy.
+    Apparently, `cyrillic' in ICQ speak is `windows-1251'...
+    
+    * eicq.el (eicq-coding-system): If default buffer coding is cyrillic, use
+      'windows-1251.
+    
+
+    modified files:
+     eicq.el
+
+
+2007-01-26 15:36:19 GMT        Steve Youngs <steve@eicq.org>   patch-3
+
+    Summary:
+      Fix coding system bug
+    Revision:
+      eicq--main--0.9.1--patch-3
+
+    This changeset fixes a coding-system bug which was stuffing up accented
+    characters in messages.  Especially characters with umlauts found in most
+    European languages.
+    
+    * eicq.el (eicq-coding-system): Default to
+      `default-buffer-file-coding-system' if mule or file-coding is
+      available, otherwise default to `nil'.
+    
+
+    modified files:
+     eicq.el
+
+
+2007-01-17 15:47:22 GMT        Steve Youngs <steve@eicq.org>   patch-2
+
+    Summary:
+      bump version in Makefile
+    Revision:
+      eicq--main--0.9.1--patch-2
+
+
+    modified files:
+     Makefile
+
+
+2007-01-17 15:02:33 GMT        Steve Youngs <steve@eicq.org>   patch-1
+
+    Summary:
+      Add previous version's ChangeLog
+    Revision:
+      eicq--main--0.9.1--patch-1
+
+    OK, so I never intended to have a minor minor release, but I do want Eicq
+    to have a complete implementation of the ICQ protocol before 1.0.  So
+    here we are at 0.9.1
+    
+    * ChangeLog.d/ChangeLog-0.9: Added from previous version.
+    
+
+    new files:
+     ChangeLog.d/.arch-ids/ChangeLog-0.9.id
+     ChangeLog.d/ChangeLog-0.9
+
+
+2007-01-17 14:33:26 GMT        Steve Youngs <steve@eicq.org>   base-0
+
+    Summary:
+      tag of steve@eicq.org--2006/eicq--main--0.9--patch-15
+    Revision:
+      eicq--main--0.9.1--base-0
+
+    (automatically generated log message)
+
+    new patches:
+     dev@xwem.org--2004-w/eicq--ckent--0.7--patch-1
+     dev@xwem.org--2004-w/eicq--ckent--0.7--patch-2
+     dev@xwem.org--2004-w/eicq--ckent--0.7--patch-3
+     karma@sxemacs.org--2005/eicq--karma--0.7--patch-1
+     karma@sxemacs.org--2005/eicq--karma--0.7--patch-2
+     karma@sxemacs.org--2005/eicq--karma--0.7--patch-4
+     lg@xwem.org--2005/eicq--lg--0.7--patch-1
+     lg@xwem.org--2005/eicq--lg--0.7--patch-2
+     lg@xwem.org--2005/eicq--lg--0.7--patch-5
+     lg@xwem.org--2005/eicq--lg--0.7--patch-8
+     lg@xwem.org--2005/eicq--lg--0.7--patch-9
+     lg@xwem.org--2005/eicq--lg--0.7--patch-12
+     lg@xwem.org--2005/eicq--lg--0.7--patch-13
+     lg@xwem.org--2005/eicq--lg--0.7--patch-14
+     lg@xwem.org--2005/eicq--lg--0.7--patch-16
+     lg@xwem.org--2005/eicq--lg--0.7--patch-18
+     lg@xwem.org--2005/eicq--lg--0.7--patch-19
+     lg@xwem.org--2005/eicq--lg--0.7--patch-20
+     lg@xwem.org--2005/eicq--lg--0.7--patch-21
+     lg@xwem.org--2005/eicq--lg--0.7--patch-23
+     lg@xwem.org--2005/eicq--lg--0.7--patch-28
+     lg@xwem.org--2005/eicq--lg--0.8--patch-1
+     lg@xwem.org--2005/eicq--lg--0.8--patch-2
+     lg@xwem.org--2005/eicq--lg--0.8--patch-3
+     lg@xwem.org--2005/eicq--lg--0.8--patch-4
+     lg@xwem.org--2007/eicq--lg--0.9--patch-1
+     steve@eicq.org--2004/eicq--main--0.6--base-0
+     steve@eicq.org--2004/eicq--main--0.6--patch-1
+     steve@eicq.org--2004/eicq--main--0.6--patch-2
+     steve@eicq.org--2004/eicq--main--0.6--patch-3
+     steve@eicq.org--2004/eicq--main--0.6--patch-4
+     steve@eicq.org--2004/eicq--main--0.6--patch-5
+     steve@eicq.org--2004/eicq--main--0.6--patch-6
+     steve@eicq.org--2004/eicq--main--0.6--patch-7
+     steve@eicq.org--2004/eicq--main--0.6--patch-8
+     steve@eicq.org--2004/eicq--main--0.6--patch-9
+     steve@eicq.org--2004/eicq--main--0.6--patch-10
+     steve@eicq.org--2004/eicq--main--0.6--patch-11
+     steve@eicq.org--2004/eicq--main--0.6--patch-12
+     steve@eicq.org--2004/eicq--main--0.6--patch-13
+     steve@eicq.org--2004/eicq--main--0.6--patch-14
+     steve@eicq.org--2004/eicq--main--0.6--patch-15
+     steve@eicq.org--2005/eicq--main--0.7--base-0
+     steve@eicq.org--2005/eicq--main--0.7--patch-1
+     steve@eicq.org--2005/eicq--main--0.7--patch-2
+     steve@eicq.org--2005/eicq--main--0.7--patch-3
+     steve@eicq.org--2005/eicq--main--0.7--patch-4
+     steve@eicq.org--2005/eicq--main--0.7--patch-5
+     steve@eicq.org--2005/eicq--main--0.7--patch-6
+     steve@eicq.org--2005/eicq--main--0.7--patch-7
+     steve@eicq.org--2005/eicq--main--0.7--patch-8
+     steve@eicq.org--2005/eicq--main--0.7--patch-9
+     steve@eicq.org--2005/eicq--main--0.7--patch-10
+     steve@eicq.org--2005/eicq--main--0.7--patch-11
+     steve@eicq.org--2005/eicq--main--0.7--patch-12
+     steve@eicq.org--2005/eicq--main--0.7--patch-13
+     steve@eicq.org--2005/eicq--main--0.7--patch-14
+     steve@eicq.org--2005/eicq--main--0.7--patch-15
+     steve@eicq.org--2005/eicq--main--0.7--patch-16
+     steve@eicq.org--2005/eicq--main--0.7--patch-17
+     steve@eicq.org--2005/eicq--main--0.7--patch-18
+     steve@eicq.org--2005/eicq--main--0.7--patch-19
+     steve@eicq.org--2005/eicq--main--0.7--patch-20
+     steve@eicq.org--2005/eicq--main--0.7--patch-21
+     steve@eicq.org--2005/eicq--main--0.7--patch-22
+     steve@eicq.org--2005/eicq--main--0.7--patch-23
+     steve@eicq.org--2005/eicq--main--0.7--patch-24
+     steve@eicq.org--2005/eicq--main--0.7--patch-25
+     steve@eicq.org--2005/eicq--main--0.7--patch-26
+     steve@eicq.org--2005/eicq--main--0.7--patch-27
+     steve@eicq.org--2005/eicq--main--0.7--patch-28
+     steve@eicq.org--2005/eicq--main--0.7--patch-29
+     steve@eicq.org--2005/eicq--main--0.7--patch-30
+     steve@eicq.org--2005/eicq--main--0.7--patch-31
+     steve@eicq.org--2005/eicq--main--0.7--patch-32
+     steve@eicq.org--2005/eicq--main--0.7--patch-33
+     steve@eicq.org--2005/eicq--main--0.7--patch-34
+     steve@eicq.org--2005/eicq--main--0.7--patch-35
+     steve@eicq.org--2005/eicq--main--0.7--patch-36
+     steve@eicq.org--2005/eicq--main--0.7--patch-37
+     steve@eicq.org--2005/eicq--main--0.7--patch-38
+     steve@eicq.org--2005/eicq--main--0.7--patch-39
+     steve@eicq.org--2005/eicq--main--0.7--patch-40
+     steve@eicq.org--2005/eicq--main--0.7--patch-41
+     steve@eicq.org--2005/eicq--main--0.7--patch-42
+     steve@eicq.org--2005/eicq--main--0.7--patch-43
+     steve@eicq.org--2005/eicq--main--0.7--patch-44
+     steve@eicq.org--2005/eicq--main--0.7--patch-45
+     steve@eicq.org--2005/eicq--main--0.7--patch-46
+     steve@eicq.org--2005/eicq--main--0.7--patch-47
+     steve@eicq.org--2005/eicq--main--0.7--patch-48
+     steve@eicq.org--2005/eicq--main--0.7--patch-49
+     steve@eicq.org--2005/eicq--main--0.7--patch-50
+     steve@eicq.org--2005/eicq--main--0.7--patch-51
+     steve@eicq.org--2005/eicq--main--0.7--patch-52
+     steve@eicq.org--2005/eicq--main--0.7--patch-53
+     steve@eicq.org--2005/eicq--main--0.7--patch-54
+     steve@eicq.org--2005/eicq--main--0.7--patch-55
+     steve@eicq.org--2005/eicq--main--0.7--patch-56
+     steve@eicq.org--2005/eicq--main--0.7--patch-57
+     steve@eicq.org--2005/eicq--main--0.7--patch-58
+     steve@eicq.org--2005/eicq--main--0.7--patch-59
+     steve@eicq.org--2005/eicq--main--0.7--patch-60
+     steve@eicq.org--2005/eicq--main--0.7--version-0
+     steve@eicq.org--2005/eicq--main--0.8--base-0
+     steve@eicq.org--2005/eicq--main--0.8--patch-1
+     steve@eicq.org--2005/eicq--main--0.8--patch-2
+     steve@eicq.org--2005/eicq--main--0.8--patch-3
+     steve@eicq.org--2005/eicq--main--0.8--patch-4
+     steve@eicq.org--2005/eicq--main--0.8--patch-5
+     steve@eicq.org--2005/eicq--main--0.8--patch-6
+     steve@eicq.org--2005/eicq--main--0.8--patch-7
+     steve@eicq.org--2005/eicq--main--0.8--patch-8
+     steve@eicq.org--2005/eicq--main--0.8--patch-9
+     steve@eicq.org--2005/eicq--main--0.8--patch-10
+     steve@eicq.org--2005/eicq--main--0.8--patch-11
+     steve@eicq.org--2005/eicq--main--0.8--patch-12
+     steve@eicq.org--2005/eicq--main--0.8--patch-13
+     steve@eicq.org--2005/eicq--main--0.8--patch-14
+     steve@eicq.org--2005/eicq--main--0.8--patch-15
+     steve@eicq.org--2005/eicq--main--0.8--patch-16
+     steve@eicq.org--2005/eicq--main--0.8--patch-17
+     steve@eicq.org--2005/eicq--main--0.8--patch-18
+     steve@eicq.org--2005/eicq--main--0.8--patch-19
+     steve@eicq.org--2005/eicq--main--0.8--patch-20
+     steve@eicq.org--2005/eicq--main--0.8--patch-21
+     steve@eicq.org--2005/eicq--main--0.8--patch-22
+     steve@eicq.org--2005/eicq--main--0.8--patch-23
+     steve@eicq.org--2005/eicq--main--0.8--version-0
+     steve@eicq.org--2005/eicq--main--0.8--versionfix-1
+     steve@eicq.org--2006/eicq--main--0.9--base-0
+     steve@eicq.org--2006/eicq--main--0.9--patch-1
+     steve@eicq.org--2006/eicq--main--0.9--patch-2
+     steve@eicq.org--2006/eicq--main--0.9--patch-3
+     steve@eicq.org--2006/eicq--main--0.9--patch-4
+     steve@eicq.org--2006/eicq--main--0.9--patch-5
+     steve@eicq.org--2006/eicq--main--0.9--patch-6
+     steve@eicq.org--2006/eicq--main--0.9--patch-7
+     steve@eicq.org--2006/eicq--main--0.9--patch-8
+     steve@eicq.org--2006/eicq--main--0.9--patch-9
+     steve@eicq.org--2006/eicq--main--0.9--patch-10
+     steve@eicq.org--2006/eicq--main--0.9--patch-11
+     steve@eicq.org--2006/eicq--main--0.9--patch-12
+     steve@eicq.org--2006/eicq--main--0.9--patch-13
+     steve@eicq.org--2006/eicq--main--0.9--patch-14
+     steve@eicq.org--2006/eicq--main--0.9--patch-15
+
+
diff --git a/ChangeLog.d/ChangeLog-0.9.2 b/ChangeLog.d/ChangeLog-0.9.2
new file mode 100644 (file)
index 0000000..c86f424
--- /dev/null
@@ -0,0 +1,929 @@
+# do not edit -- automatically generated by arch changelog
+# non-id: automatic-ChangeLog--steve@emchat.org--2007/emchat--main--0.9.2
+#
+
+2008-03-25 14:06:52 GMT        Steve Youngs <steve@emchat.org> patch-20
+
+    Summary:
+      Unsuccessful attempt to implement adding users to SSI
+    Revision:
+      emchat--main--0.9.2--patch-20
+
+    This changeset tries to implement adding new users to your server side
+    contact lists.  The bad news is that it isn't working.  I'm committing so
+    that a) my work doesn't get lost, and b) so others can look at it and
+    possibly help me fix it.
+    
+    * emchat.el (emchat-add-user-ssi): New.
+      (emchat-do-search-found-last): Update for new add-user stuff
+      (emchat-login): Add a `new-user' message type
+      (emchat-add-user): New.
+    
+    * emchat-v8.el (emchat-v8-snac-srv-ssi-mod-ack): Update return codes.
+      (emchat-v8-snac-cli-ssi-add): Rewrite.  But still not working yet
+      unfortunately.
+    
+    * emchat-world.el (emchat-world-ssi-grp): New.
+      (emchat-world-next-ssi-id): New.
+      (emchat-world-add-new-user): New.
+    
+
+    modified files:
+     emchat-v8.el emchat-world.el emchat.el
+
+
+2008-02-20 03:29:22 GMT        Steve Youngs <steve@emchat.org> patch-19
+
+    Summary:
+      Fix emphasis face definitions
+    Revision:
+      emchat--main--0.9.2--patch-19
+
+    This changeset defines the faces used in emchat-emphasis in a different
+    way.  Instead of using #'defface, they are now created with #'make-face.
+    They inherit from parent faces via #'set-face-parent and special
+    properties from #'set-face-property.
+    
+    The old defface'd faces are now defcustom's (:type 'face) with the
+    default value set to the face from the #'make-face call.
+    
+    This ixes a problem I was seeing when the default font isn't used for
+    other faces like italic and you don't get any emphasis happening in your
+    log buffer.
+    
+    * emchat-emphasis.el (emchat-emphasis-bold): Migrate from defface to
+      defcustom plus the appropriate #'make-face and #'set-face-foo calls
+      (emchat-emphasis-italic): Ditto.
+      (emchat-emphasis-underline): Ditto.
+      (emchat-emphasis-underline-bold): Ditto.
+      (emchat-emphasis-underline-italic): Ditto.
+      (emchat-emphasis-bold-italic): Ditto.
+      (emchat-emphasis-underline-bold-italic): Ditto.
+      (emchat-emphasis-strikethru): Ditto.
+    
+
+    modified files:
+     emchat-emphasis.el
+
+
+2008-02-10 07:21:54 GMT        Steve Youngs <steve@emchat.org> patch-18
+
+    Summary:
+      Add a 48x48 png to use as frame icon
+    Revision:
+      emchat--main--0.9.2--patch-18
+
+    * images/emchat-icon.png: New.
+
+    new files:
+     images/.arch-ids/emchat-icon.png.id images/emchat-icon.png
+
+
+2007-12-27 17:27:49 GMT        Steve Youngs <steve@emchat.org> patch-17
+
+    Summary:
+      Integrate EMchat world with SSI more closely
+    Revision:
+      emchat--main--0.9.2--patch-17
+
+    This changeset brings us a few steps closer to dealing with SSI
+    properly.  We can now build up the world file almost entirely from SSI.
+    Your own UIN/Alias must exist in world for it to work.  And obviously,
+    SSI has absolutely no idea about EMchat "groups".
+    
+    Each entry in world now has SSI group and entry ID fields.  These are
+    automatically added/maintained so no user intervention is required.  We
+    need these ID numbers to add/del/modify SSI entries.
+    
+    Also, #'emchat-add-user has been disabled.  It is not yet working.
+    
+    * emchat-v8.el (emchat-v8-get-ssi-mod-time): Removed.  Moved to
+      emchat-world.el. 
+      (emchat-v8-ssi-count): New.  Temp storage for SSI entry count.
+      (emchat-v8-snac-srv-ssi-reply): Use it.
+      Also, update the local `world' from SSI.
+      (emchat-v8-snac-srv-ssi-up-to-date): Tell the user we're up to date.
+      (emchat-v8-snac-srv-replyinfo): Add missing FLAGS arg.
+      (emchat-v8-snac-cli-ssi-checkout): Fix.
+      (emchat-v8-pack-time): Now takes a cons cell of high/low ints as arg,
+      just like any other emacs time/date function.
+    
+    * emchat.el (emchat-check-contact-list): New.  Checks to see if the local
+      world is up to date.
+      (emchat-do-login-confirm): Use it.
+    
+    * emchat-world.el (emchat-world-ssi-LastUpdateTime-regexp): New.  Regexp
+      matching the LastUpdateTime in world.
+      (emchat-world-ssi-count-regexp): New.  Regexp matching the entries
+      count in world.
+      (emchat-world-ssi-id-regexp): New.  Regexp matching the SSI group and
+      entry ID's in world.
+      (emchat-world-rc-regexp): Improve the regexp.
+      (emchat-world-ssi-mod-time): New.  Return, as a cons of high/low ints
+      the LastUpdateTime in world.
+      (emchat-world-ssi-count): New.  Return the entries count in world.
+      (emchat-world-update-world-count): New.  Update LastUpdateTime and
+      entries count in world from SSI.
+      (emchat-world-sync-ssi-maybe): New.  Add contacts that exist in SSI but
+      not in world to world, and update/add SSI group ID info where/when
+      necessary.
+      (emchat-add-user): Disable.  Not working, I'll reenable it when it's
+      fixed.
+      (emchat-world-update): Add a dirty horrible ugly hack to get around my
+      total lack of ability to write a decent regular expression.  Or, to put
+      it another way... cope with SSI data in world.
+      (emchat-add-new-user-to-buddy-buffer): Whitespace touch-up in the
+      balloon-help transient.  And don't try to add to SSI unless the new
+      contact is being added by the user.
+    
+
+    modified files:
+     emchat-v8.el emchat-world.el emchat.el
+
+
+2007-12-22 07:45:59 GMT        Steve Youngs <steve@emchat.org> patch-16
+
+    Summary:
+      SNAC #x13/#x06 almost complete!
+    Revision:
+      emchat--main--0.9.2--patch-16
+
+    This changeset gives us a working SNAC #x13/#x06 (roster reply) handler.
+    We are now getting all of the data, we're just not doing anything with it
+    apart from fill up your debug buffer.
+    
+    Also, all incoming SNAC handling functions now take up to 3 args.  We can
+    now do something with the SNAC flags.
+    
+    BTW, this changeset would not be possible without the tremendous help I
+    got from Sebastian Freundt.  Thanks VERY much, Sebastian for your SNAC
+    decoding skills. :-)
+    
+    * emchat-v8.el (emchat-v8-snac-flags): New.  Replaces the flags0 and
+      flags1 functions.
+      (emchat-v8-snac-rid): Renamed from `emchat-v8-snacrid'.
+      (emchat-v8-snac-srv-*): Add optional FLAGS arg.
+      (emchat-v8-snac-srv-ssi-reply): Rewritten.  It is now working, we just
+      don't do anything with the results yet.  But it's a good log
+      filler. :-) 
+      (emchat-v8-handle-flap): Call the SNAC functions with 3 args, the extra
+      one being the SNAC flags.
+      (emchat-v8-fetch-time): Fix.  Make it return something we can parse
+      with #'format-time-string and friends.
+      (emchat-v8-fetch-snac): Combine flags0 and flags1 into a single flags
+      element. 
+      (emchat-v8-pack-snac): Ditto.
+      (emchat-v8-fetch-n-tlvs): New.  For fetching a specific number of
+      TLV's. 
+    
+
+    modified files:
+     emchat-v8.el
+
+
+2007-12-21 00:45:05 GMT        Steve Youngs <steve@emchat.org> patch-15
+
+    Summary:
+      Merged from hrop (patch 4) -- optimisations
+    Revision:
+      emchat--main--0.9.2--patch-15
+
+    Patches applied:
+    
+     * hroptatyr@emchat.org--emchat/emchat--hrop--0.9.2--patch-4
+       minor, optimise packet reading using ENT if available
+
+    modified files:
+     emchat-v8.el
+
+    new patches:
+     hroptatyr@emchat.org--emchat/emchat--hrop--0.9.2--patch-4
+
+
+2007-12-20 15:45:06 GMT        Steve Youngs <steve@emchat.org> patch-14
+
+    Summary:
+      Minor fixes to auth code
+    Revision:
+      emchat--main--0.9.2--patch-14
+
+    This changeset has some minor fixes to the authorisation code.  It now
+    uses the family #x13 SSI packets.  Plus a couple of other tiny tweaks not
+    worth mentioning. 
+    
+    * emchat.el (emchat-remove-yourself-from-buddy): I had my logic backwards
+      for the completion.
+      (emchat-authorize): Fix for SSI
+      (emchat-auth-request): Send this via family #x13 SSI
+      (emchat-auth-accept-reason): New.  Self-explanatory
+    
+    * emchat-v8.el (emchat-v8-snac-srv-ssi-reply): Comment out the guts and
+      just save the data to a variable.  This is _ONLY_ for testing/debugging
+      purposes, untill I get this thing figured out.
+    
+    * emchat-v8.el (emchat-v8-snac-cli-ssi-add): Use the new bstr packer.
+    
+    * emchat-world.el (emchat-add-new-user-to-buddy-buffer): This is not yet
+      working.  The change here was simply: don't try to add someone who is
+      already on your list.  Which takes care of a TODO from lg. :-)
+    
+
+    modified files:
+     emchat-v8.el emchat-world.el emchat.el
+
+
+2007-12-18 07:12:50 GMT        Steve Youngs <steve@emchat.org> patch-13
+
+    Summary:
+      Fix a couple of byte-compiler warnings that crept in
+    Revision:
+      emchat--main--0.9.2--patch-13
+
+    * build.el (needed): Add `font'.
+      Autoload a macro from emchat-emphasis when compiling
+      custom-defines.el. 
+    
+    * emchat-emphasis.el (emchat-emphasis-alist): Use #'func notation in the
+      :set and :get keyword functions
+    
+
+    modified files:
+     build.el emchat-emphasis.el
+
+
+2007-12-18 06:35:42 GMT        Steve Youngs <steve@emchat.org> patch-12
+
+    Summary:
+      Fix contact list error during login
+    Revision:
+      emchat--main--0.9.2--patch-12
+
+    This changeset takes care of the last contact list related login bug.
+    Local-only contact lists are not supported anymore, so don't attempt to
+    send one to the server.
+    
+    * emchat-v8.el (emchat-v8-snac-srv-reply-bos): Don't try to send the
+      contact list.  It is all server-side lists now.
+    
+
+    modified files:
+     emchat-v8.el
+
+
+2007-12-17 14:39:52 GMT        Steve Youngs <steve@emchat.org> patch-11
+
+    Summary:
+      Fix last fix
+    Revision:
+      emchat--main--0.9.2--patch-11
+
+    * emchat.el (emchat-remove-yourself-from-buddy): Add missing arg to a
+      #'emchat-numeric-uin call.
+    
+
+    modified files:
+     emchat.el
+
+
+2007-12-17 14:36:17 GMT        Steve Youngs <steve@emchat.org> patch-10
+
+    Summary:
+      Add completion to #'emchat-remove-yourself-from-buddy
+    Revision:
+      emchat--main--0.9.2--patch-10
+
+    This changeset adds completion of UIN's when you are removing yourself
+    from somebody else's contact list.  It will complete only the UIN's that
+    aren't in _your_ contact list unless you are tracking adds from everyone
+    regardless of them being on your list or not.
+    
+    Also, the list of adds for the current session is pre-loaded from the
+    saved adds in ~/.emchat/recent-adds.
+    
+    Once you have removed yourself from a person's contact list, both the
+    session list of adds and the on-disc list of adds are updated.  The UIN
+    in question is removed.
+    
+    * emchat.el (emchat-remove-yourself-from-buddy): Add completion.
+      Also pre-set `emchat-world-recently-added-by' from the save file on
+      disc. 
+    
+
+    modified files:
+     emchat.el
+
+
+2007-12-17 12:50:20 GMT        Steve Youngs <steve@emchat.org> patch-9
+
+    Summary:
+      Make foreign add tracking a little more customisable
+    Revision:
+      emchat--main--0.9.2--patch-9
+
+    This changeset lets you choose if you'll track the UIN's of people adding
+    you to their contact list if they aren't on your list (default), or just
+    track every add regardless if they are on your list or not.
+    
+    * emchat.el (emchat-do-added-you): Only keep track of people who add you
+      to your contact list if they are not already in _your_ contact list,
+      unless you set `emchat-world-track-all-adds'.
+    
+    * emchat-world.el (emchat-world-track-all-adds): New.  When non-nil, keep
+      track of _all_ people adding you to their contact list.  Otherwise just
+      track people who aren't on _your_ list.
+    
+
+    modified files:
+     emchat-world.el emchat.el
+
+
+2007-12-17 12:02:34 GMT        Steve Youngs <steve@emchat.org> patch-8
+
+    Summary:
+      Fix/improve keeping track of people who add you to their list
+    Revision:
+      emchat--main--0.9.2--patch-8
+
+    * emchat.el (emchat-do-added-you): Fix a silly bug where an #'insert was
+      given a symbol instead of a string as an arg.
+      Also, ensure that a UIN is only added once to the list of
+      recent-added-bys. 
+    
+
+    modified files:
+     emchat.el
+
+
+2007-12-17 00:34:24 GMT        Steve Youngs <steve@emchat.org> patch-7
+
+    Summary:
+      Keep track of people adding you to their contact lists
+    Revision:
+      emchat--main--0.9.2--patch-7
+
+    This changeset lets you keep track of anyone who adds you to their
+    contact list.  For the current session, the info is a list
+    `emchat-world-recently-added-by'.  For keeping track more permanently, it
+    is also saved to a file `emchat-recently-added-by-filename'.
+    
+    * emchat-world.el (emchat-recently-added-by-filename): New.  Keeps track
+      of people who add you to their list.
+      (emchat-world-recently-added-by): New.  Same as above, but a variable
+      for this info in the current session.
+    
+    * emchat.el (emchat-do-added-you): Keep track of people adding you to
+      their contact lists.
+    
+
+    modified files:
+     emchat-world.el emchat.el
+
+
+2007-12-17 00:12:26 GMT        Steve Youngs <steve@emchat.org> patch-6
+
+    Summary:
+      Typo fix
+    Revision:
+      emchat--main--0.9.2--patch-6
+
+    * emchat.el (emchat-remove-yourself-from-buddy): Typo in docstring.
+    
+
+    modified files:
+     emchat.el
+
+
+2007-12-17 00:02:54 GMT        Steve Youngs <steve@emchat.org> patch-5
+
+    Summary:
+      More SSI fixes/additions
+    Revision:
+      emchat--main--0.9.2--patch-5
+
+    This changeset has more SSI (Server Side Info) fixes and additions.
+    We're still not completely there yet, but getting closer.
+    
+    There is one new user command:
+    
+       #'emchat-remove-yourself-from-buddy
+    
+    * emchat.el (emchat-remove-yourself-from-buddy): New.  Use this to remove
+      yourself from _somebody else's_ contact list.
+    
+    * emchat-v8.el (emchat-v8-snac-list): Mostly whitespace changes, plus the
+      currently broken family #x13 packets have been noted.
+      The rest of the #x13 packet functions have been added, but not all are
+      working yet.  The ones that aren't are marked.
+
+    modified files:
+     emchat-v8.el emchat.el
+
+
+2007-12-14 23:59:57 GMT        Steve Youngs <steve@emchat.org> patch-4
+
+    Summary:
+      Begin implementing SSI (server-side contact lists)
+    Revision:
+      emchat--main--0.9.2--patch-4
+
+    This changeset begins EMchat's migration to using SSI.  SSI is Server
+    Side Info.  We have to do this because AOL has dropped support for the
+    old Mirabilis ICQ protocol and now ICQ is totally OSCAR protocol.  One of
+    the "features", and I use that term loosely, of OSCAR is that it doesn't
+    support local contact lists.
+    
+    As yet, EMchat can't add/modify server-side contact lists.  Until we get
+    that working, you can use a client that does, I used ICQ2go, to add all
+    your contacts to the server list.  Then you can switch back to EMchat and
+    things will work.  You'll see status updates etc.
+    
+    Another thing this changeset does is to convert all of emchat-v8.el to
+    using hex everywhere.  It used to be hex in some places and dec in
+    others.  This keeps it all consistant.  C-x C-f emchat-v8.el and think in
+    hex! :-)
+    
+    Beware, this is nowhere near a complete implementation.  I simply used a
+    fooking big hammer to get it usable.  More changesets will follow that
+    will iron out the bugs.
+    
+    * emchat.el (emchat-do-login-confirm): Use `emchat-activate-contact-list'
+      instead of `emchat-send-contact-list'.
+      (emchat-activate-contact-list): New.  It tells the server that we want
+      to use server-side contact lists.
+    
+    * emchat-v8.el (emchat-v8-snacv-list): Convert to hex and tidy it up.
+      (emchat-v8-snac-list): Convert all to hex, add function items for all
+      the SSI packets.  Not all these functions have been written yet, but at
+      least now when an as yet unimplemented packet comes in, you'll get a
+      name to the func def void error. :-)
+      (emchat-v8-snac-srv-ssi-reply): New.  Currently no-op.  This is the
+      packet the server sends when we ask for the server-side contact list to
+      be transferred.
+      (emchat-v8-snac-srv-ssi-rights-reply): New.  The packet the server
+      sends when we request rights/limits info for SSI.  Currently we don't
+      do anything with this, but it is logged to the emchat-debug buffer.
+      (emchat-v8-snac-srv-rates): Use hex.
+      (emchat-v8-snac-srv-pause): Use hex.
+      (emchat-v8-snac-cli-ssi-add): New.  Add a contact to server-side contact
+      list.  BROKEN.
+      (emchat-v8-snac-cli-ssi-edit-end): New.  Send this packet to signal the
+      end of modifying SSI lists.
+      (emchat-v8-snac-cli-ssi-edit-begin): New.  Send this packet to begin
+      modifying SSI lists.
+      (emchat-v8-snac-cli-ssi-activate): New.  Tells the server that you want
+      to use SSI contact lists.
+      (emchat-v8-snac-cli-ssi-right-request): New.  Request rate/limit info
+      for SSI.
+      (emchat-v8-snac-cli-ssi-request): New.  Request that the server-side
+      contact list be sent to you.
+      (emchat-v8-snac-cli-setstatus): Use hex.
+      (emchat-v8-snac-cli-add-contact): Use hex.
+      (emchat-v8-snac-cli-addvisible): Use hex.
+      (emchat-v8-snac-cli-remvisible): Use hex.
+      (emchat-v8-snac-cli-addinvisible): Use hex.
+      (emchat-v8-snac-cli-reminvisible): Use hex.
+      (emchat-v8-pack-meta-snac): Use hex.
+      (emchat-v8-snac-cli-ready): Use hex.
+      (emchat-v8-snac-cli-families): Use hex.
+      (emchat-v8-snac-cli-ratesrequest): Use hex.
+      (emchat-v8-snac-cli-reqinfo): Use hex.
+      (emchat-v8-snac-cli-reqlocation): Use hex.
+      (emchat-v8-snac-cli-reqbuddy): Use hex.
+      (emchat-v8-snac-cli-reqicbm): Use hex.
+      (emchat-v8-snac-cli-sendmsg): Use hex.
+      (emchat-v8-snac-cli-reqbos): Use hex.
+    
+
+    modified files:
+     emchat-v8.el emchat.el
+
+
+2007-11-20 04:13:43 GMT        Steve Youngs <steve@emchat.org> patch-3
+
+    Summary:
+      Add logos and externalise toolbar glyphs
+    Revision:
+      emchat--main--0.9.2--patch-3
+
+    This changeset adds our logo to the top of the log buffer.  It also adds
+    a button to the default-toolbar, and takes all the "inline" xpm's out of
+    emchat-toolbar.el. 
+    
+    * Makefile (DATA_DIR): New.  Where the logos and icons go.
+      (DATA_FILES): New.  The logos and icons.
+      (install): Install the $DATA_FILES
+    
+    * emchat-utils.el (emchat-glyph-dir): New.  So EMchat can find
+      logo/icon files.
+    
+    * emchat-toolbar.el (emchat-password-icon): Data exported to external
+      file.
+      (emchat-send-message-here-icon): Ditto.
+      (emchat-send-message-around-icon): Ditto.
+      (emchat-send-url-here-icon): Ditto.
+      (emchat-send-url-around-icon): Ditto.
+      (emchat-query-info-here-icon): Ditto.
+      (emchat-query-info-around-icon): Ditto.
+      (emchat-update-info-icon): Ditto.
+      (emchat-search-icon): Ditto.
+      (emchat-authorize-here-icon): Ditto.
+      (emchat-login-icon): Ditto.
+      (emchat-logout-icon): Ditto.
+      (emchat-exit-icon): Ditto.
+      (emchat-new-log-icon): Ditto.
+      (emchat-help-icon): Ditto.
+    
+    * emchat-log.el (emchat-log-logo): Sexy logo for the top of the log.
+      (emchat-log-header): The old log intro as an xbm.  Done this way so we
+      can align it nicely with the logo.
+      (emchat-log-show-buffer): Use them.
+    
+    * emchat.el (emchat-toolbar-login): Command run from default-toolbar.
+      (emchat-toolbar-icon): Icon for default-toolbar.
+      (emchat-toolbar-spec): Button spec for default-toolbar.
+      (emchat-add-to-toolbar): Adds our button to default-toolbar.
+    
+
+    new files:
+     images/.arch-ids/=id images/.arch-ids/auth-here.xpm.id
+     images/.arch-ids/exit.xpm.id images/.arch-ids/help.xpm.id
+     images/.arch-ids/info-around.xpm.id
+     images/.arch-ids/info-here.xpm.id
+     images/.arch-ids/log-header.xbm.id
+     images/.arch-ids/login.xpm.id images/.arch-ids/logo.png.id
+     images/.arch-ids/logout.xpm.id
+     images/.arch-ids/mini-logo.png.id
+     images/.arch-ids/msg-around.xpm.id
+     images/.arch-ids/msg-here.xpm.id
+     images/.arch-ids/new-log.xpm.id
+     images/.arch-ids/password.xpm.id
+     images/.arch-ids/search.xpm.id
+     images/.arch-ids/upd-info.xpm.id
+     images/.arch-ids/url-around.xpm.id
+     images/.arch-ids/url-here.xpm.id images/auth-here.xpm
+     images/exit.xpm images/help.xpm images/info-around.xpm
+     images/info-here.xpm images/log-header.xbm images/login.xpm
+     images/logo.png images/logout.xpm images/mini-logo.png
+     images/msg-around.xpm images/msg-here.xpm images/new-log.xpm
+     images/password.xpm images/search.xpm images/upd-info.xpm
+     images/url-around.xpm images/url-here.xpm
+
+    modified files:
+     Makefile emchat-log.el emchat-toolbar.el emchat-utils.el
+     emchat.el
+
+    new directories:
+     images images/.arch-ids
+
+
+2007-11-16 16:50:33 GMT        Steve Youngs <steve@emchat.org> patch-2
+
+    Summary:
+      Update the donation glyphs/code
+    Revision:
+      emchat--main--0.9.2--patch-2
+
+    * emchat.el (emchat-make-donation): Update donation URL.
+      (emchat-paypal-glyph): Use newer, sexier glyph.
+      (emchat-maybe-later-glyph): Ditto.
+    
+
+    modified files:
+     emchat.el
+
+
+2007-11-15 01:49:45 GMT        Steve Youngs <steve@emchat.org> patch-1
+
+    Summary:
+      The Great Eicq -> EMchat Renaming
+    Revision:
+      emchat--main--0.9.2--patch-1
+
+    Waaaaay too much stuff to log each and every change.  But it was all
+    simply renaming from Eicq to EMchat and eicq to emchat.
+
+    new files:
+     ChangeLog.d/.arch-ids/ChangeLog-0.9.1.Eicq.id
+     ChangeLog.d/ChangeLog-0.9.1.Eicq
+
+    modified files:
+     .arch-inventory INSTALL Makefile NEWS README TODO build.el
+     emchat-buddy.el emchat-convert.el emchat-curl.el
+     emchat-doctor.el emchat-emphasis.el emchat-history.el
+     emchat-log.el emchat-menu.el emchat-meta.el emchat-report.el
+     emchat-setup.el emchat-status.el emchat-toolbar.el
+     emchat-track.el emchat-utils.el emchat-v8.el emchat-wharf.el
+     emchat-world.el emchat-xwem.el emchat.el emchat.texi
+
+    renamed files:
+     .arch-ids/eicq-buddy.el.id
+       ==> .arch-ids/emchat-buddy.el.id
+     .arch-ids/eicq-convert.el.id
+       ==> .arch-ids/emchat-convert.el.id
+     .arch-ids/eicq-curl.el.id
+       ==> .arch-ids/emchat-curl.el.id
+     .arch-ids/eicq-doctor.el.id
+       ==> .arch-ids/emchat-doctor.el.id
+     .arch-ids/eicq-emphasis.el.id
+       ==> .arch-ids/emchat-emphasis.el.id
+     .arch-ids/eicq-history.el.id
+       ==> .arch-ids/emchat-history.el.id
+     .arch-ids/eicq-log.el.id
+       ==> .arch-ids/emchat-log.el.id
+     .arch-ids/eicq-menu.el.id
+       ==> .arch-ids/emchat-menu.el.id
+     .arch-ids/eicq-meta.el.id
+       ==> .arch-ids/emchat-meta.el.id
+     .arch-ids/eicq-report.el.id
+       ==> .arch-ids/emchat-report.el.id
+     .arch-ids/eicq-setup.el.id
+       ==> .arch-ids/emchat-setup.el.id
+     .arch-ids/eicq-status.el.id
+       ==> .arch-ids/emchat-status.el.id
+     .arch-ids/eicq-toolbar.el.id
+       ==> .arch-ids/emchat-toolbar.el.id
+     .arch-ids/eicq-track.el.id
+       ==> .arch-ids/emchat-track.el.id
+     .arch-ids/eicq-utils.el.id
+       ==> .arch-ids/emchat-utils.el.id
+     .arch-ids/eicq-v8.el.id
+       ==> .arch-ids/emchat-v8.el.id
+     .arch-ids/eicq-wharf.el.id
+       ==> .arch-ids/emchat-wharf.el.id
+     .arch-ids/eicq-world.el.id
+       ==> .arch-ids/emchat-world.el.id
+     .arch-ids/eicq-xwem.el.id
+       ==> .arch-ids/emchat-xwem.el.id
+     .arch-ids/eicq.el.id
+       ==> .arch-ids/emchat.el.id
+     .arch-ids/eicq.texi.id
+       ==> .arch-ids/emchat.texi.id
+     ChangeLog.d/.arch-ids/ChangeLog-0.6.id
+       ==> ChangeLog.d/.arch-ids/ChangeLog-0.6.Eicq.id
+     ChangeLog.d/.arch-ids/ChangeLog-0.7.id
+       ==> ChangeLog.d/.arch-ids/ChangeLog-0.7.Eicq.id
+     ChangeLog.d/.arch-ids/ChangeLog-0.8.id
+       ==> ChangeLog.d/.arch-ids/ChangeLog-0.8.Eicq.id
+     ChangeLog.d/.arch-ids/ChangeLog-0.9.id
+       ==> ChangeLog.d/.arch-ids/ChangeLog-0.9.Eicq.id
+     ChangeLog.d/ChangeLog-0.6
+       ==> ChangeLog.d/ChangeLog-0.6.Eicq
+     ChangeLog.d/ChangeLog-0.7
+       ==> ChangeLog.d/ChangeLog-0.7.Eicq
+     ChangeLog.d/ChangeLog-0.8
+       ==> ChangeLog.d/ChangeLog-0.8.Eicq
+     ChangeLog.d/ChangeLog-0.9
+       ==> ChangeLog.d/ChangeLog-0.9.Eicq
+     eicq-buddy.el
+       ==> emchat-buddy.el
+     eicq-convert.el
+       ==> emchat-convert.el
+     eicq-curl.el
+       ==> emchat-curl.el
+     eicq-doctor.el
+       ==> emchat-doctor.el
+     eicq-emphasis.el
+       ==> emchat-emphasis.el
+     eicq-history.el
+       ==> emchat-history.el
+     eicq-log.el
+       ==> emchat-log.el
+     eicq-menu.el
+       ==> emchat-menu.el
+     eicq-meta.el
+       ==> emchat-meta.el
+     eicq-report.el
+       ==> emchat-report.el
+     eicq-setup.el
+       ==> emchat-setup.el
+     eicq-status.el
+       ==> emchat-status.el
+     eicq-toolbar.el
+       ==> emchat-toolbar.el
+     eicq-track.el
+       ==> emchat-track.el
+     eicq-utils.el
+       ==> emchat-utils.el
+     eicq-v8.el
+       ==> emchat-v8.el
+     eicq-wharf.el
+       ==> emchat-wharf.el
+     eicq-world.el
+       ==> emchat-world.el
+     eicq-xwem.el
+       ==> emchat-xwem.el
+     eicq.el
+       ==> emchat.el
+     eicq.texi
+       ==> emchat.texi
+
+
+2007-11-13 05:34:39 GMT        Steve Youngs <steve@eicq.org>   base-0
+
+    Summary:
+      tag of steve@eicq.org--2007/eicq--main--0.9.1--version-0
+    Revision:
+      emchat--main--0.9.2--base-0
+
+    (automatically generated log message)
+
+    new patches:
+     dev@xwem.org--2004-w/eicq--ckent--0.7--patch-1
+     dev@xwem.org--2004-w/eicq--ckent--0.7--patch-2
+     dev@xwem.org--2004-w/eicq--ckent--0.7--patch-3
+     hroptatyr@eicq.org--eicq/eicq--hrop--0.9.1--patch-4
+     karma@sxemacs.org--2005/eicq--karma--0.7--patch-1
+     karma@sxemacs.org--2005/eicq--karma--0.7--patch-2
+     karma@sxemacs.org--2005/eicq--karma--0.7--patch-4
+     lg@xwem.org--2005/eicq--lg--0.7--patch-1
+     lg@xwem.org--2005/eicq--lg--0.7--patch-2
+     lg@xwem.org--2005/eicq--lg--0.7--patch-5
+     lg@xwem.org--2005/eicq--lg--0.7--patch-8
+     lg@xwem.org--2005/eicq--lg--0.7--patch-9
+     lg@xwem.org--2005/eicq--lg--0.7--patch-12
+     lg@xwem.org--2005/eicq--lg--0.7--patch-13
+     lg@xwem.org--2005/eicq--lg--0.7--patch-14
+     lg@xwem.org--2005/eicq--lg--0.7--patch-16
+     lg@xwem.org--2005/eicq--lg--0.7--patch-18
+     lg@xwem.org--2005/eicq--lg--0.7--patch-19
+     lg@xwem.org--2005/eicq--lg--0.7--patch-20
+     lg@xwem.org--2005/eicq--lg--0.7--patch-21
+     lg@xwem.org--2005/eicq--lg--0.7--patch-23
+     lg@xwem.org--2005/eicq--lg--0.7--patch-28
+     lg@xwem.org--2005/eicq--lg--0.8--patch-1
+     lg@xwem.org--2005/eicq--lg--0.8--patch-2
+     lg@xwem.org--2005/eicq--lg--0.8--patch-3
+     lg@xwem.org--2005/eicq--lg--0.8--patch-4
+     lg@xwem.org--2007/eicq--lg--0.9--patch-1
+     lg@xwem.org--2007/eicq--lg--0.9--patch-2
+     lg@xwem.org--2007/eicq--lg--0.9--patch-3
+     lg@xwem.org--2007/eicq--lg--0.9--patch-4
+     lg@xwem.org--2007/eicq--lg--0.9--patch-5
+     lg@xwem.org--2007/eicq--lg--0.9--patch-9
+     steve@eicq.org--2004/eicq--main--0.6--base-0
+     steve@eicq.org--2004/eicq--main--0.6--patch-1
+     steve@eicq.org--2004/eicq--main--0.6--patch-2
+     steve@eicq.org--2004/eicq--main--0.6--patch-3
+     steve@eicq.org--2004/eicq--main--0.6--patch-4
+     steve@eicq.org--2004/eicq--main--0.6--patch-5
+     steve@eicq.org--2004/eicq--main--0.6--patch-6
+     steve@eicq.org--2004/eicq--main--0.6--patch-7
+     steve@eicq.org--2004/eicq--main--0.6--patch-8
+     steve@eicq.org--2004/eicq--main--0.6--patch-9
+     steve@eicq.org--2004/eicq--main--0.6--patch-10
+     steve@eicq.org--2004/eicq--main--0.6--patch-11
+     steve@eicq.org--2004/eicq--main--0.6--patch-12
+     steve@eicq.org--2004/eicq--main--0.6--patch-13
+     steve@eicq.org--2004/eicq--main--0.6--patch-14
+     steve@eicq.org--2004/eicq--main--0.6--patch-15
+     steve@eicq.org--2005/eicq--main--0.7--base-0
+     steve@eicq.org--2005/eicq--main--0.7--patch-1
+     steve@eicq.org--2005/eicq--main--0.7--patch-2
+     steve@eicq.org--2005/eicq--main--0.7--patch-3
+     steve@eicq.org--2005/eicq--main--0.7--patch-4
+     steve@eicq.org--2005/eicq--main--0.7--patch-5
+     steve@eicq.org--2005/eicq--main--0.7--patch-6
+     steve@eicq.org--2005/eicq--main--0.7--patch-7
+     steve@eicq.org--2005/eicq--main--0.7--patch-8
+     steve@eicq.org--2005/eicq--main--0.7--patch-9
+     steve@eicq.org--2005/eicq--main--0.7--patch-10
+     steve@eicq.org--2005/eicq--main--0.7--patch-11
+     steve@eicq.org--2005/eicq--main--0.7--patch-12
+     steve@eicq.org--2005/eicq--main--0.7--patch-13
+     steve@eicq.org--2005/eicq--main--0.7--patch-14
+     steve@eicq.org--2005/eicq--main--0.7--patch-15
+     steve@eicq.org--2005/eicq--main--0.7--patch-16
+     steve@eicq.org--2005/eicq--main--0.7--patch-17
+     steve@eicq.org--2005/eicq--main--0.7--patch-18
+     steve@eicq.org--2005/eicq--main--0.7--patch-19
+     steve@eicq.org--2005/eicq--main--0.7--patch-20
+     steve@eicq.org--2005/eicq--main--0.7--patch-21
+     steve@eicq.org--2005/eicq--main--0.7--patch-22
+     steve@eicq.org--2005/eicq--main--0.7--patch-23
+     steve@eicq.org--2005/eicq--main--0.7--patch-24
+     steve@eicq.org--2005/eicq--main--0.7--patch-25
+     steve@eicq.org--2005/eicq--main--0.7--patch-26
+     steve@eicq.org--2005/eicq--main--0.7--patch-27
+     steve@eicq.org--2005/eicq--main--0.7--patch-28
+     steve@eicq.org--2005/eicq--main--0.7--patch-29
+     steve@eicq.org--2005/eicq--main--0.7--patch-30
+     steve@eicq.org--2005/eicq--main--0.7--patch-31
+     steve@eicq.org--2005/eicq--main--0.7--patch-32
+     steve@eicq.org--2005/eicq--main--0.7--patch-33
+     steve@eicq.org--2005/eicq--main--0.7--patch-34
+     steve@eicq.org--2005/eicq--main--0.7--patch-35
+     steve@eicq.org--2005/eicq--main--0.7--patch-36
+     steve@eicq.org--2005/eicq--main--0.7--patch-37
+     steve@eicq.org--2005/eicq--main--0.7--patch-38
+     steve@eicq.org--2005/eicq--main--0.7--patch-39
+     steve@eicq.org--2005/eicq--main--0.7--patch-40
+     steve@eicq.org--2005/eicq--main--0.7--patch-41
+     steve@eicq.org--2005/eicq--main--0.7--patch-42
+     steve@eicq.org--2005/eicq--main--0.7--patch-43
+     steve@eicq.org--2005/eicq--main--0.7--patch-44
+     steve@eicq.org--2005/eicq--main--0.7--patch-45
+     steve@eicq.org--2005/eicq--main--0.7--patch-46
+     steve@eicq.org--2005/eicq--main--0.7--patch-47
+     steve@eicq.org--2005/eicq--main--0.7--patch-48
+     steve@eicq.org--2005/eicq--main--0.7--patch-49
+     steve@eicq.org--2005/eicq--main--0.7--patch-50
+     steve@eicq.org--2005/eicq--main--0.7--patch-51
+     steve@eicq.org--2005/eicq--main--0.7--patch-52
+     steve@eicq.org--2005/eicq--main--0.7--patch-53
+     steve@eicq.org--2005/eicq--main--0.7--patch-54
+     steve@eicq.org--2005/eicq--main--0.7--patch-55
+     steve@eicq.org--2005/eicq--main--0.7--patch-56
+     steve@eicq.org--2005/eicq--main--0.7--patch-57
+     steve@eicq.org--2005/eicq--main--0.7--patch-58
+     steve@eicq.org--2005/eicq--main--0.7--patch-59
+     steve@eicq.org--2005/eicq--main--0.7--patch-60
+     steve@eicq.org--2005/eicq--main--0.7--version-0
+     steve@eicq.org--2005/eicq--main--0.8--base-0
+     steve@eicq.org--2005/eicq--main--0.8--patch-1
+     steve@eicq.org--2005/eicq--main--0.8--patch-2
+     steve@eicq.org--2005/eicq--main--0.8--patch-3
+     steve@eicq.org--2005/eicq--main--0.8--patch-4
+     steve@eicq.org--2005/eicq--main--0.8--patch-5
+     steve@eicq.org--2005/eicq--main--0.8--patch-6
+     steve@eicq.org--2005/eicq--main--0.8--patch-7
+     steve@eicq.org--2005/eicq--main--0.8--patch-8
+     steve@eicq.org--2005/eicq--main--0.8--patch-9
+     steve@eicq.org--2005/eicq--main--0.8--patch-10
+     steve@eicq.org--2005/eicq--main--0.8--patch-11
+     steve@eicq.org--2005/eicq--main--0.8--patch-12
+     steve@eicq.org--2005/eicq--main--0.8--patch-13
+     steve@eicq.org--2005/eicq--main--0.8--patch-14
+     steve@eicq.org--2005/eicq--main--0.8--patch-15
+     steve@eicq.org--2005/eicq--main--0.8--patch-16
+     steve@eicq.org--2005/eicq--main--0.8--patch-17
+     steve@eicq.org--2005/eicq--main--0.8--patch-18
+     steve@eicq.org--2005/eicq--main--0.8--patch-19
+     steve@eicq.org--2005/eicq--main--0.8--patch-20
+     steve@eicq.org--2005/eicq--main--0.8--patch-21
+     steve@eicq.org--2005/eicq--main--0.8--patch-22
+     steve@eicq.org--2005/eicq--main--0.8--patch-23
+     steve@eicq.org--2005/eicq--main--0.8--version-0
+     steve@eicq.org--2005/eicq--main--0.8--versionfix-1
+     steve@eicq.org--2006/eicq--main--0.9--base-0
+     steve@eicq.org--2006/eicq--main--0.9--patch-1
+     steve@eicq.org--2006/eicq--main--0.9--patch-2
+     steve@eicq.org--2006/eicq--main--0.9--patch-3
+     steve@eicq.org--2006/eicq--main--0.9--patch-4
+     steve@eicq.org--2006/eicq--main--0.9--patch-5
+     steve@eicq.org--2006/eicq--main--0.9--patch-6
+     steve@eicq.org--2006/eicq--main--0.9--patch-7
+     steve@eicq.org--2006/eicq--main--0.9--patch-8
+     steve@eicq.org--2006/eicq--main--0.9--patch-9
+     steve@eicq.org--2006/eicq--main--0.9--patch-10
+     steve@eicq.org--2006/eicq--main--0.9--patch-11
+     steve@eicq.org--2006/eicq--main--0.9--patch-12
+     steve@eicq.org--2006/eicq--main--0.9--patch-13
+     steve@eicq.org--2006/eicq--main--0.9--patch-14
+     steve@eicq.org--2006/eicq--main--0.9--patch-15
+     steve@eicq.org--2007/eicq--main--0.9.1--base-0
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-1
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-2
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-3
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-4
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-5
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-6
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-7
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-8
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-9
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-10
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-11
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-12
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-13
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-14
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-15
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-16
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-17
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-18
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-19
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-20
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-21
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-22
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-23
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-24
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-25
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-26
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-27
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-28
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-29
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-30
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-31
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-32
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-33
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-34
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-35
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-36
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-37
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-38
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-39
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-40
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-41
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-42
+     steve@eicq.org--2007/eicq--main--0.9.1--patch-43
+     steve@eicq.org--2007/eicq--main--0.9.1--version-0
+
+
diff --git a/ChangeLog.d/ChangeLog-0.9.Eicq b/ChangeLog.d/ChangeLog-0.9.Eicq
new file mode 100644 (file)
index 0000000..d10c38c
--- /dev/null
@@ -0,0 +1,498 @@
+# do not edit -- automatically generated by arch changelog
+# non-id: automatic-ChangeLog--steve@eicq.org--2006/eicq--main--0.9
+#
+
+2007-01-17 13:59:13 GMT        Steve Youngs <steve@eicq.org>   patch-15
+
+    Summary:
+      Merged from lg (patch 1) -- Mule fix.
+    Revision:
+      eicq--main--0.9--patch-15
+
+    Patches applied:
+    
+     * lg@xwem.org--2007/eicq--lg--0.9--patch-1
+       Mule fix
+
+    modified files:
+     eicq.el
+
+    new patches:
+     lg@xwem.org--2007/eicq--lg--0.9--patch-1
+
+
+2007-01-15 17:20:16 GMT        Steve Youngs <steve@eicq.org>   patch-14
+
+    Summary:
+      Makefile tweaks.
+    Revision:
+      eicq--main--0.9--patch-14
+
+    This changeset brings Eicq's build inline with the new LFS compliant
+    SXEmacs install hierarchy/search paths.
+    
+    * Makefile (PREFIX): Default to new SXEmacs LFS compliant directory.
+      (LISP_DIR): Move to _after_ PREFIX.
+      (INFO_DIR): Ditto.
+    
+
+    modified files:
+     Makefile
+
+
+2006-10-09 00:56:50 GMT        Steve Youngs <steve@eicq.org>   patch-13
+
+    Summary:
+      Build improvements
+    Revision:
+      eicq--main--0.9--patch-13
+
+    
+    * eicq.el: Byte-compiler warning fix... autoload
+      `eicq-wharf-dec-messages' at compile time.
+    
+    * Makefile (XEMACS): Default to sxemacs
+      (PREFIX): Default to either
+        /usr/local/lib/sxemacs/site-packages
+      or
+        /usr/local/lib/xemacs/site-packages
+      depending on the value of $XEMACS.
+    
+
+    modified files:
+     Makefile eicq.el
+
+
+2006-10-09 00:08:23 GMT        Steve Youngs <steve@eicq.org>   patch-12
+
+    Summary:
+      Saner, easier handling of fill-column in log buffer
+    Revision:
+      eicq--main--0.9--patch-12
+
+    The changeset takes care of an issue I'd been having with the fill-column
+    in the log buffer.  If you ran Eicq in a separate frame the log buffer's
+    fill-column was always way too high.  Originally the fill-column was
+    supposed to have been calculated based on the width of the frame.  Now
+    what we do is leave fill-column alone unless the user has set
+    `eicq-log-fill-column'. 
+    
+    * eicq-log.el (eicq-log-mode): Don't try to be clever with the
+      fill-column, just leave it at the default setting unless the user
+      explicitly sets a different value.
+      (eicq-log-fill-column): Update doc string.
+    
+
+    modified files:
+     eicq-log.el
+
+
+2006-09-14 06:16:47 GMT        Steve Youngs <steve@eicq.org>   patch-11
+
+    Summary:
+      Wharf show status, automatically decrement msg count.
+    Revision:
+      eicq--main--0.9--patch-11
+
+    This changeset enhances the EicqWharf.  It will now automatically
+    decrement the message count when sending a message.  And it also shows
+    your current status.
+    
+    Another small change is that if you run Eicq in a separate frame by
+    setting `eicq-start-in-new-frame' to `t', the frame has the name property
+    set.  This helps you do sexy things with it in WMs like Sawfish.
+    
+    * eicq.el (eicq-show-window): Give the Eicq frame a name property
+      "EicqLog".  This actually sets the Xwindow "class" for the frame, which
+      in turn, helps WMs identify it.  Think: Sawfish matched-windows.
+      (eicq-send-message-alias-around): Decrement the message count in
+      EicqWharf if it is being used.
+      (eicq-send-url-alias-around): Ditto.
+    
+    * eicq-wharf.el (eicq-wharf-new-frame): Insert the user's actual status
+      instead of the word "Status".
+    
+    * eicq-wharf.el (eicq-wharf-update-status): New.  Updates the status line
+      in the EicqWharf.
+    
+    * eicq-status.el (eicq-change-status): Maybe update the status line in
+      the EicqWharf.
+    
+    
+    
+
+    modified files:
+     eicq-status.el eicq-wharf.el eicq.el
+
+
+2006-09-01 22:22:10 GMT        Steve Youngs <steve@eicq.org>   patch-10
+
+    Summary:
+      Handle aliases with strange characters in them
+    Revision:
+      eicq--main--0.9--patch-10
+
+    * eicq.el (eicq-alias-around): Fix regexp to handle alias names with
+      non-word-class characters in them.
+    
+
+    modified files:
+     eicq.el
+
+
+2006-08-19 16:27:42 GMT        Steve Youngs <steve@eicq.org>   patch-9
+
+    Summary:
+      Fix problem with sounds not working in SXEmacs
+    Revision:
+      eicq--main--0.9--patch-9
+
+    This actually points to a bigger problem in SXEmacs itself because
+    `play-media-stream' is an autoloaded function, but it isn't being
+    autoloaded. 
+    
+    * eicq.el: Load sound.el at compile-time.
+    
+
+    modified files:
+     eicq.el
+
+
+2006-07-08 06:09:55 GMT        Steve Youngs <steve@eicq.org>   patch-8
+
+    Summary:
+      Fix incoming and outgoing authorisation requests
+    Revision:
+      eicq--main--0.9--patch-8
+
+    This changeset pretty much finishes the authorisation code in Eicq.
+    Incoming auth requests can be accepted or rejected.  If you accept the
+    request, the user that sent it will be added to your contact list and
+    they are sent an `ADDEDYOU' message.  If you reject the request, they are
+    sent a `auth-reject' message and reason... see:
+    `eicq-auth-reject-reason'.
+    
+    Outgoing auth requests can also be sent to other users.  Use
+    `eicq-auth-request' to do this, and see `eicq-auth-request-reason' for
+    the message that gets sent with the request.
+    
+    I'd like to say something about ICQ authorisations.  They are pretty much
+    a complete waste of time.  They are only useful with crippled ICQ clients
+    that don't let you send messages to users who aren't on your contact
+    list and don't let you add users to your contact list without
+    authorisation.  Eicq does _NOT_ fall into this category of ICQ client.
+    
+    * eicq-v8.el (eicq-v8-snac-srv-authreply): New.  Handle SRV_AUTHREPLY.
+    
+    * eicq.el (eicq-auth-reject-reason): New.  Message to send to a user when
+      rejecting their authorisation request.
+      (eicq-auth-request-reason): New.  Message to send to a user when
+      requesting authorisation from them.
+      (eicq-do-auth-accept): New.  Handle incoming accepted auth messages. 
+      (eicq-do-auth-reject): New.  Handle incoming rejected auth messages. 
+      (eicq-do-message-helper): Display authorisation rejected reason. 
+      (eicq-login): Add `auth-reject' and `auth-accept' message types. 
+      (eicq-authorize): Fix.  Accept or reject authorisation requests.  If
+      accepted, the user is added to the contact list.
+      (eicq-auth-request): New.  Request authorisation from another user. 
+    
+
+    modified files:
+     eicq-v8.el eicq.el
+
+
+2006-06-23 04:47:52 GMT        Steve Youngs <steve@eicq.org>   patch-7
+
+    Summary:
+      New macros to execute code only in either XEmacs or SXEmacs
+    Revision:
+      eicq--main--0.9--patch-7
+
+    The motivation for this was seeing an obsolete warning about
+    `play-sound-file' when building Eicq in SXEmacs.  Two new macros,
+    `eicq-do-in-xemacs' and `eicq-do-in-sxemacs' can be used to wrap stuff
+    that can only be executed in either XEmacs or SXEmacs.
+    
+    * eicq.el (eicq-do-in-xemacs): New.  To execute code only in XEmacs.
+      (eicq-do-in-sxemacs): New.  As above, except for SXEmacs.
+      (eicq-maybe-play-sound): Use them here so SXEmacs can call the media
+      defun's directly, thus avoiding byte-compiler warnings.
+      (play-media-stream): Autoload this.
+    
+
+    modified files:
+     eicq.el
+
+
+2006-06-23 03:25:53 GMT        Steve Youngs <steve@eicq.org>   patch-6
+
+    Summary:
+      Fix sending messages when current msg contains "[text]" in it
+    Revision:
+      eicq--main--0.9--patch-6
+
+    If somebody sent you a message and it contained "[text]" in it, when you
+    hit `m' to reply, you'd get a "no alias/uin" error.  This fixes that.
+    
+    * eicq.el (eicq-alias-around): Fix regexp so that you don't get errors
+      when a message contains "[sometext]" in it.
+    
+
+    modified files:
+     eicq.el
+
+
+2006-03-18 10:54:31 GMT        Steve Youngs <steve@eicq.org>   patch-5
+
+    Summary:
+      regexp-opt build fix
+    Revision:
+      eicq--main--0.9--patch-5
+
+    This fixes a build problem of not finding regexp-opt.  I have no idea why
+    I wasn't seeing it in my WD, but there you go.
+    
+    * eicq-buddy.el: Don't autoload regexp-opt here.
+    
+    * eicq-report.el: Or here.
+    
+    * eicq.el: Do it here instead.
+    
+
+    modified files:
+     eicq-buddy.el eicq-report.el eicq.el
+
+
+2006-02-15 06:20:13 GMT        Steve Youngs <steve@eicq.org>   patch-4
+
+    Summary:
+      Tweak alias tab-completion a little
+    Revision:
+      eicq--main--0.9--patch-4
+
+    This changeset changes the completion on aliases a little.  It used to
+    complete only on connected and/or active aliases.  Now it completes on
+    _all_ aliases.  I find that this makes more sense as I frequently send
+    messages to people who aren't online.
+    
+    * eicq.el (eicq-completing-alias): Complete on _all_ aliases, not just
+      the active and connected ones.
+    
+
+    modified files:
+     eicq.el
+
+
+2006-01-15 15:55:02 GMT        Steve Youngs <steve@sxemacs.org>        patch-3
+
+    Summary:
+      Remove `eicq-extra-buffers-to-kill'
+    Revision:
+      eicq--main--0.9--patch-3
+
+    * eicq-log.el (eicq-log-update-history): No need to add anything to
+      `eicq-extra-buffers-to-kill'. 
+      (eicq-extra-buffers-to-kill): Removed.
+    
+    * eicq.el (eicq-exit): `eicq-extra-buffers-to-kill' isn't used anymore.
+      (eicq-logout): Ditto.
+    
+
+    modified files:
+     eicq-log.el eicq.el
+
+
+2006-01-15 02:01:06 GMT        Steve Youngs <steve@eicq.org>   patch-2
+
+    Summary:
+      Save history after each message
+    Revision:
+      eicq--main--0.9--patch-2
+
+    This changeset means that the history files will be saved after each
+    message is appended to them, instead of just when you log out.  The
+    "Wrote: /foo/bar/file" messages have been suppressed.
+    
+    It means that when I kill my SXEmacs without logging out of Eicq my
+    history directory doesn't have those "#file#" backups and I don't get the
+    "Consider recover-file" messages next time I log in.
+    
+    * eicq-log.el (eicq-log-update-history): Save the history files after
+      each message but use `write-region' so we can suppress those annoying
+      "Wrote: /foo/bar/file" messages.
+    
+
+    modified files:
+     eicq-log.el
+
+
+2005-12-26 04:59:25 GMT        Steve Youngs <steve@eicq.org>   patch-1
+
+    Summary:
+      Merged versionfix-1 from 2005 repo, Prepare for 0.9 cycle
+    Revision:
+      eicq--main--0.9--patch-1
+
+    * NEWS: Update, prepare for 0.9 release cycle
+    
+    * Makefile (VER): Bump to 0.9
+    
+    
+    Patches applied:
+    
+     * steve@eicq.org--2005/eicq--main--0.8--versionfix-1
+       Oops, forgot to update the NEWS file.
+    
+    
+
+    new files:
+     ChangeLog.d/.arch-ids/ChangeLog-0.8.id
+     ChangeLog.d/ChangeLog-0.8
+
+    modified files:
+     Makefile NEWS
+
+    new patches:
+     steve@eicq.org--2005/eicq--main--0.8--versionfix-1
+
+
+2005-12-26 03:48:33 GMT        Steve Youngs <steve@eicq.org>   base-0
+
+    Summary:
+      tag of steve@eicq.org--2005/eicq--main--0.8--version-0
+    Revision:
+      eicq--main--0.9--base-0
+
+    (automatically generated log message)
+
+    new patches:
+     dev@xwem.org--2004-w/eicq--ckent--0.7--patch-1
+     dev@xwem.org--2004-w/eicq--ckent--0.7--patch-2
+     dev@xwem.org--2004-w/eicq--ckent--0.7--patch-3
+     karma@sxemacs.org--2005/eicq--karma--0.7--patch-1
+     karma@sxemacs.org--2005/eicq--karma--0.7--patch-2
+     karma@sxemacs.org--2005/eicq--karma--0.7--patch-4
+     lg@xwem.org--2005/eicq--lg--0.7--patch-1
+     lg@xwem.org--2005/eicq--lg--0.7--patch-2
+     lg@xwem.org--2005/eicq--lg--0.7--patch-5
+     lg@xwem.org--2005/eicq--lg--0.7--patch-8
+     lg@xwem.org--2005/eicq--lg--0.7--patch-9
+     lg@xwem.org--2005/eicq--lg--0.7--patch-12
+     lg@xwem.org--2005/eicq--lg--0.7--patch-13
+     lg@xwem.org--2005/eicq--lg--0.7--patch-14
+     lg@xwem.org--2005/eicq--lg--0.7--patch-16
+     lg@xwem.org--2005/eicq--lg--0.7--patch-18
+     lg@xwem.org--2005/eicq--lg--0.7--patch-19
+     lg@xwem.org--2005/eicq--lg--0.7--patch-20
+     lg@xwem.org--2005/eicq--lg--0.7--patch-21
+     lg@xwem.org--2005/eicq--lg--0.7--patch-23
+     lg@xwem.org--2005/eicq--lg--0.7--patch-28
+     lg@xwem.org--2005/eicq--lg--0.8--patch-1
+     lg@xwem.org--2005/eicq--lg--0.8--patch-2
+     lg@xwem.org--2005/eicq--lg--0.8--patch-3
+     lg@xwem.org--2005/eicq--lg--0.8--patch-4
+     steve@eicq.org--2004/eicq--main--0.6--base-0
+     steve@eicq.org--2004/eicq--main--0.6--patch-1
+     steve@eicq.org--2004/eicq--main--0.6--patch-2
+     steve@eicq.org--2004/eicq--main--0.6--patch-3
+     steve@eicq.org--2004/eicq--main--0.6--patch-4
+     steve@eicq.org--2004/eicq--main--0.6--patch-5
+     steve@eicq.org--2004/eicq--main--0.6--patch-6
+     steve@eicq.org--2004/eicq--main--0.6--patch-7
+     steve@eicq.org--2004/eicq--main--0.6--patch-8
+     steve@eicq.org--2004/eicq--main--0.6--patch-9
+     steve@eicq.org--2004/eicq--main--0.6--patch-10
+     steve@eicq.org--2004/eicq--main--0.6--patch-11
+     steve@eicq.org--2004/eicq--main--0.6--patch-12
+     steve@eicq.org--2004/eicq--main--0.6--patch-13
+     steve@eicq.org--2004/eicq--main--0.6--patch-14
+     steve@eicq.org--2004/eicq--main--0.6--patch-15
+     steve@eicq.org--2005/eicq--main--0.7--base-0
+     steve@eicq.org--2005/eicq--main--0.7--patch-1
+     steve@eicq.org--2005/eicq--main--0.7--patch-2
+     steve@eicq.org--2005/eicq--main--0.7--patch-3
+     steve@eicq.org--2005/eicq--main--0.7--patch-4
+     steve@eicq.org--2005/eicq--main--0.7--patch-5
+     steve@eicq.org--2005/eicq--main--0.7--patch-6
+     steve@eicq.org--2005/eicq--main--0.7--patch-7
+     steve@eicq.org--2005/eicq--main--0.7--patch-8
+     steve@eicq.org--2005/eicq--main--0.7--patch-9
+     steve@eicq.org--2005/eicq--main--0.7--patch-10
+     steve@eicq.org--2005/eicq--main--0.7--patch-11
+     steve@eicq.org--2005/eicq--main--0.7--patch-12
+     steve@eicq.org--2005/eicq--main--0.7--patch-13
+     steve@eicq.org--2005/eicq--main--0.7--patch-14
+     steve@eicq.org--2005/eicq--main--0.7--patch-15
+     steve@eicq.org--2005/eicq--main--0.7--patch-16
+     steve@eicq.org--2005/eicq--main--0.7--patch-17
+     steve@eicq.org--2005/eicq--main--0.7--patch-18
+     steve@eicq.org--2005/eicq--main--0.7--patch-19
+     steve@eicq.org--2005/eicq--main--0.7--patch-20
+     steve@eicq.org--2005/eicq--main--0.7--patch-21
+     steve@eicq.org--2005/eicq--main--0.7--patch-22
+     steve@eicq.org--2005/eicq--main--0.7--patch-23
+     steve@eicq.org--2005/eicq--main--0.7--patch-24
+     steve@eicq.org--2005/eicq--main--0.7--patch-25
+     steve@eicq.org--2005/eicq--main--0.7--patch-26
+     steve@eicq.org--2005/eicq--main--0.7--patch-27
+     steve@eicq.org--2005/eicq--main--0.7--patch-28
+     steve@eicq.org--2005/eicq--main--0.7--patch-29
+     steve@eicq.org--2005/eicq--main--0.7--patch-30
+     steve@eicq.org--2005/eicq--main--0.7--patch-31
+     steve@eicq.org--2005/eicq--main--0.7--patch-32
+     steve@eicq.org--2005/eicq--main--0.7--patch-33
+     steve@eicq.org--2005/eicq--main--0.7--patch-34
+     steve@eicq.org--2005/eicq--main--0.7--patch-35
+     steve@eicq.org--2005/eicq--main--0.7--patch-36
+     steve@eicq.org--2005/eicq--main--0.7--patch-37
+     steve@eicq.org--2005/eicq--main--0.7--patch-38
+     steve@eicq.org--2005/eicq--main--0.7--patch-39
+     steve@eicq.org--2005/eicq--main--0.7--patch-40
+     steve@eicq.org--2005/eicq--main--0.7--patch-41
+     steve@eicq.org--2005/eicq--main--0.7--patch-42
+     steve@eicq.org--2005/eicq--main--0.7--patch-43
+     steve@eicq.org--2005/eicq--main--0.7--patch-44
+     steve@eicq.org--2005/eicq--main--0.7--patch-45
+     steve@eicq.org--2005/eicq--main--0.7--patch-46
+     steve@eicq.org--2005/eicq--main--0.7--patch-47
+     steve@eicq.org--2005/eicq--main--0.7--patch-48
+     steve@eicq.org--2005/eicq--main--0.7--patch-49
+     steve@eicq.org--2005/eicq--main--0.7--patch-50
+     steve@eicq.org--2005/eicq--main--0.7--patch-51
+     steve@eicq.org--2005/eicq--main--0.7--patch-52
+     steve@eicq.org--2005/eicq--main--0.7--patch-53
+     steve@eicq.org--2005/eicq--main--0.7--patch-54
+     steve@eicq.org--2005/eicq--main--0.7--patch-55
+     steve@eicq.org--2005/eicq--main--0.7--patch-56
+     steve@eicq.org--2005/eicq--main--0.7--patch-57
+     steve@eicq.org--2005/eicq--main--0.7--patch-58
+     steve@eicq.org--2005/eicq--main--0.7--patch-59
+     steve@eicq.org--2005/eicq--main--0.7--patch-60
+     steve@eicq.org--2005/eicq--main--0.7--version-0
+     steve@eicq.org--2005/eicq--main--0.8--base-0
+     steve@eicq.org--2005/eicq--main--0.8--patch-1
+     steve@eicq.org--2005/eicq--main--0.8--patch-2
+     steve@eicq.org--2005/eicq--main--0.8--patch-3
+     steve@eicq.org--2005/eicq--main--0.8--patch-4
+     steve@eicq.org--2005/eicq--main--0.8--patch-5
+     steve@eicq.org--2005/eicq--main--0.8--patch-6
+     steve@eicq.org--2005/eicq--main--0.8--patch-7
+     steve@eicq.org--2005/eicq--main--0.8--patch-8
+     steve@eicq.org--2005/eicq--main--0.8--patch-9
+     steve@eicq.org--2005/eicq--main--0.8--patch-10
+     steve@eicq.org--2005/eicq--main--0.8--patch-11
+     steve@eicq.org--2005/eicq--main--0.8--patch-12
+     steve@eicq.org--2005/eicq--main--0.8--patch-13
+     steve@eicq.org--2005/eicq--main--0.8--patch-14
+     steve@eicq.org--2005/eicq--main--0.8--patch-15
+     steve@eicq.org--2005/eicq--main--0.8--patch-16
+     steve@eicq.org--2005/eicq--main--0.8--patch-17
+     steve@eicq.org--2005/eicq--main--0.8--patch-18
+     steve@eicq.org--2005/eicq--main--0.8--patch-19
+     steve@eicq.org--2005/eicq--main--0.8--patch-20
+     steve@eicq.org--2005/eicq--main--0.8--patch-21
+     steve@eicq.org--2005/eicq--main--0.8--patch-22
+     steve@eicq.org--2005/eicq--main--0.8--patch-23
+     steve@eicq.org--2005/eicq--main--0.8--version-0
+
+
diff --git a/INSTALL b/INSTALL
new file mode 100644 (file)
index 0000000..d2e7de4
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,109 @@
+
+========================================================================
+EMchat is now written entirely in emacs-lisp, so theoretically it should
+run on anything that can run (S)XEmacs and can connect to the ICQ servers.
+
+You will need at least XEmacs 21.4 or any version of SXEmacs.
+========================================================================
+
+This installation is definitely a 'no-brainer'
+
+1) Check the Makefile, and edit anything as required.
+
+   On Windows, you must have set your HOME variable (e.g. on Windows 98
+   in your autoexec.bat, add 'set HOME=C:\' before installation. You
+   should have set HOME for Cygwin anyway). Reboot if necessary before
+   installing EMchat!
+
+   For Cygwin, search for '# Cygwin #' in the Makefile and to see what
+   you need to change to build on Cygwin.
+
+   For Solaris, search for '# Solaris #' in the Makefile to see what
+   you need to change to build on Solaris.
+
+2) 'make'
+
+3) become 'root' and then 'make install'. On Windows just type
+   'make install'
+
+Hold it, you're not finished yet...
+
+Add the following to your `user-init-file' (XEmacs -- ~/.xemacs/init.el
+                                            SXEmacs -- ~/.sxemacs/init.el)
+---------- cut ----------
+
+(require 'emchat)
+(setq emchat-user-alias "me")
+
+
+---------- cut ----------
+
+As the user that will be using EMchat, fire up (S)XEmacs and...
+
+M-x emchat-setup RET
+
+That will set up the needed stuff in your home directory.
+
+Adding your own UIN:
+-------------------
+~/.emchat/world is the file that stores not only the UIN's of your
+friends but also your own UIN.
+
+Just edit ~/.emchat/world and change the UIN beside 'me' to reflect your
+own UIN.
+
+Of course you can change the alias ('me') of your own UIN to be whatever
+you want.  But you'll have to change the (setq emchat-user-alias "...") 
+line in your `user-init-file' to match.
+
+
+Ok, now you're done.
+
+'M-x emchat-login'.  There you go! 
+
+Don't hesitate to message me a success report or mail me your
+screenshots!
+
+
+Example world file:
+------------------
+Literally you can put anything you like in this resource file, such as
+this introduction.  EMchat will only consider a line to be a valid buddy
+if...
+
+    -- `:icq' starts at column zero (there's no leading whitespace or
+       characters).
+
+    -- There is one space between `:icq' and a UIN.
+
+    -- There is one space between a UIN and a buddy name.
+
+    -- The buddy name does NOT contain any colon `:' characters.
+       Buddy names can contain whitespace anywhere except as the
+       first character.
+
+    -- There is one space between the buddy name and any group names.
+       Group names begin with a colon `:'.
+
+So, for example...
+
+:icq 34307457 emchat
+:icq 12345678 me
+:icq 88888888 the queen :royalty
+
+This way, it defines three buddies: \"emchat\", \"me\", and \"the
+queen\". It reads alias name until the end of the line, or until the
+first group name.  In that example, the buddy \"the queen\" is in
+the group `:royalty'.
+
+Adding your own UIN:
+
+Just change \"12345678 me\" above to your UIN/alias.  And don't
+forget to change the (setq emchat-user-alias \"me\") line in your
+`user-init-file' to match.
+
+BTW, that 1st buddy up there, 34307457 emchat, is a valid UIN, it's
+mine. :-)
+
+Remember to M-x emchat-world-update after changing this rc file.
+
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..57b87e8
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,220 @@
+## Makefile for EMchat   -*-Makefile-*-
+##
+## Copyright (C) 2001 - 2008 Steve Youngs
+##
+## This file is part of EMchat.
+
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following conditions
+## are met:
+##
+## 1. Redistributions of source code must retain the above copyright
+##    notice, this list of conditions and the following disclaimer.
+##
+## 2. Redistributions in binary form must reproduce the above copyright
+##    notice, this list of conditions and the following disclaimer in the
+##    documentation and/or other materials provided with the distribution.
+##
+## 3. Neither the name of the author nor the names of any contributors
+##    may be used to endorse or promote products derived from this
+##    software without specific prior written permission.
+##
+## THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+## IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+## WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+## DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+## CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+## SUBSTITUTE GOODS OR SERVICES# LOSS OF USE, DATA, OR PROFITS# OR
+## BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+## WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+## OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+## IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+PACKAGE = emchat
+VER = 0.9.5
+
+SHELL = /bin/sh
+# Cygwin # Comment out line above and uncomment the following line
+# SHELL = /usr/bin/sh
+
+# Cygwin # Comment out the line above and uncomment the
+# following line (/cygdrive/c is Cygwin notation for C:\ !!!)
+# PREFIX = /cygdrive/c/Program\ Files/XEmacs/site-packages
+
+# If you want to make a tarball that you can just unpack on all your
+# PC's you can 'make pkg'.  The 'pkg' target uses these directories to
+# build the tarball.
+STAGING = ../build-pkg
+INFO_STAGING = $(STAGING)/info
+LISP_STAGING = $(STAGING)/lisp/$(PACKAGE)
+
+# Programs and their flags.
+ifeq ($(XEMACS),)
+  XEMACS = sxemacs
+endif
+
+XEMACS_FLAGS = -batch -no-autoloads
+MAKEINFO = makeinfo
+INSTALL = install
+# Solaris #  Comment out above line and uncomment the line below
+# INSTALL = install -u 0 -g 0
+
+PKG_INSTALL = install
+TAR = /bin/tar
+TAR_FLAGS = czf
+
+# Everything hangs off this.  
+ifeq ($(PREFIX),)
+  ifeq ('$(XEMACS)','sxemacs')
+    PREFIX = /usr/local/share/sxemacs/site-packages
+  else
+    ifeq ('$(XEMACS)','xemacs')
+      PREFIX = /usr/local/lib/xemacs/site-packages
+    endif
+  endif
+endif
+
+# Where the lisp files go.
+LISP_DIR = $(PREFIX)/lisp/$(PACKAGE)
+
+# logos/icons etc
+DATA_DIR = $(PREFIX)/etc/$(PACKAGE)
+
+# Where the info files go.
+INFO_DIR = $(PREFIX)/info
+
+############################################################################
+##                No User Configurable Items Below Here                   ##
+############################################################################
+
+## Order is IMPORTANT here.  Add new files to the _end_ unless you
+## know what you are doing.
+SOURCES = \
+       emchat-utils.el    \
+       emchat.el          \
+       emchat-buddy.el    \
+       emchat-convert.el  \
+       emchat-curl.el     \
+       emchat-doctor.el   \
+       emchat-emphasis.el \
+       emchat-history.el  \
+       emchat-log.el      \
+       emchat-menu.el     \
+       emchat-meta.el     \
+       emchat-report.el   \
+       emchat-setup.el    \
+       emchat-status.el   \
+       emchat-toolbar.el  \
+       emchat-track.el    \
+       emchat-v8.el       \
+       emchat-wharf.el    \
+       emchat-world.el
+#       emchat-xwem.el
+
+GENERATED_SRC = \
+       auto-autoloads.el \
+       custom-load.el    \
+       custom-defines.el \
+
+EXTRA_SRC = INSTALL NEWS README TODO emchat-version.el
+
+OBJECTS = $(SOURCES:.el=.elc)
+GENERATED_OBJ = $(GENERATED_SRC:.el=.elc)
+TEXI_FILES = $(PACKAGE).texi
+INFO_FILES = $(TEXI_FILES:.texi=.info)
+
+DATA_FILES = $(wildcard images/*.x[pb]m) \
+       $(wildcard images/*.png)
+
+.SUFFIXES:
+.SUFFIXES: .info .texi .elc .el
+
+all:: prepsrc version compile texinfo
+
+compile:
+       $(XEMACS) $(XEMACS_FLAGS) -l "build.el"
+
+prepsrc.el:
+       @echo "(defvar srcfiles" > $@
+       @echo "  (quote ($(GENERATED_SRC)" >> $@
+       @echo "          $(SOURCES))))" >> $@
+
+prepsrc: prepsrc.el
+
+.texi.info:
+       $(MAKEINFO) $<
+
+texinfo: emchat-version.texi $(INFO_FILES)
+
+emchat-version.el:
+       echo ";;; Automatically generated file -- DO NOT EDIT OR DELETE" > $@
+       echo ";;;###autoload" >> $@
+       echo "(defconst emchat-version" >> $@
+       if [ -d "./{arch}" -a -x `which tla 2>/dev/null` ]; then \
+               printf '  "%s"' `tla logs -f|tail -n1` >> $@; \
+       else \
+               echo -n '  "$(VER)"' >> $@; \
+       fi
+       echo ")" >> $@
+       echo "(provide 'emchat-version)" >> $@
+
+version: emchat-version.el
+
+emchat-version.texi:
+       if [ -d "./{arch}" -a -x `which tla 2>/dev/null` ]; then \
+               printf "@set VERSION %s" `tla logs -f|tail -n1|sed s/@/@@/` > $@; \
+       else \
+               echo "@set VERSION $(VER)" > $@; \
+       fi
+
+install: all
+       $(INSTALL) -d $(INFO_DIR) $(LISP_DIR) $(DATA_DIR)
+       $(INSTALL) -m 644 $(INFO_FILES) $(INFO_DIR)
+       $(INSTALL) -m 644 $(DATA_FILES) $(DATA_DIR)
+       $(INSTALL) -m 644 $(SOURCES) $(GENERATED_SRC) $(EXTRA_SRC) \
+               $(OBJECTS) $(GENERATED_OBJ) $(LISP_DIR)
+
+# Solaris # Comment out the above and uncomment the following.
+# install: all
+#      for file in $(INFO_DIR) $(LISP_DIR); \
+#        do $(INSTALL) -d $$file; \
+#      done
+#      for file in $(INFO_FILES); \
+#        do $(INSTALL) -f $(INFO_DIR) -m 644 $$file; \
+#      done
+#      for file in $(SOURCES) $(GENERATED_SRC) $(EXTRA_SRC) $(OBJECTS) $(GENERATED_OBJ); \
+#        do $(INSTALL) -f $(LISP_DIR) -m 644 $$file; \
+#      done
+
+
+pkg: all
+       $(PKG_INSTALL) -d $(STAGING) $(INFO_STAGING) $(LISP_STAGING)
+       $(PKG_INSTALL) -m 644 $(INFO_FILES) $(INFO_STAGING)
+       $(PKG_INSTALL) -m 644 $(SOURCES) $(GENERATED_SRC) $(EXTRA_SRC) \
+               $(OBJECTS) $(GENERATED_OBJ) $(LISP_STAGING)
+       (cd $(STAGING); \
+               $(TAR) $(TAR_FLAGS) $(PACKAGE)-$(VER)-pkg.tar.gz ./*)
+
+upgrade: distclean uninstall install
+
+uninstall:: 
+       rm -rf $(LISP_DIR)
+       rm -f $(INFO_DIR)/$(INFO_FILES)
+
+clean::
+       rm -f $(OBJECTS) $(GENERATED_OBJ) $(GENERATED_SRC) \
+               $(INFO_FILES)
+
+
+distclean: clean
+       rm -f core* *~ TAGS emchat-version.el emchat-version.texi \
+               prepsrc.el
+
+# Developer targets
+tags: TAGS
+
+TAGS: $(SOURCES)
+       etags $(SOURCES)
+
+.PHONY: emchat-version.el version emchat-version.texi
diff --git a/NEWS b/NEWS
new file mode 100644 (file)
index 0000000..d4f56c0
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,267 @@
+-*- Outline -*-
+
+* 0.9.2 to 0.9.3 (First EMchat release)
+
+* 0.9.1
+
+This was the last Eicq release.  From this point on it is EMchat.
+Oh, and sorry for not updating this file in the last couple of
+versions. 
+
+* 0.8 to 0.9
+
+* 0.7 to 0.8
+
+- Removed all the old stagnating v5 protocol code. (Me)
+- GUI enhancements (Me)
+       Removed some unnecessary scrollbars
+       Optionally use the gutter tabs instead of the status buffer
+       Display X-Face and Colour Face images in buddy buffer
+- Fix bug with Eicq trying to play undefined sounds. (Me)
+- Better handling of switching between log/buddy buffers (Me).
+- Add an "oops" function. (Me)
+       This is for those times when you send a msg to the wrong
+       person, `eicq-oops', sends the msg to the right person and an
+       apology/explanation to the wrong person.
+- Eliza meets Eicq. (Me)
+       As far as we are aware, Eicq is the only ICQ client in the
+       world that allows your contacts to psycho-analyze themselves.
+- Activity indicatory for XWEM. (Me)
+       Displays a small glyph in the xwem-minibuffer.  The glyph
+       changes when you have new incoming messages.
+- Fix bug that was causing `current-buffer' to be screwed after an
+  auto-relogin. (Me)
+- Support Russian language out of the box. (Evgeny Zajcev)
+- Key binding fix. (Evgeny Zajcev)
+- BBDB fix. (Evgeny Zajcev, Me)
+
+* 0.6 to 0.7
+
+- Protocol code fixes/additions (Evgeny Zajcev, Me)
+       Way too many changes to list here.  Suffice to say that in
+       this release, Eicq went from non-working bitrot to usable and
+       functioning ICQ client! :-)  See the README file for a summary
+       of the currently working features.
+- Log buffer enhancements (aka Gnus-style emphasis) (Me)
+       Underline, bold, italic text.  Hyperlinked URL's, email
+       addresses and Unix manual page names.
+- Auto-response messages improvements (Me)
+       Auto-responses are only sent once per contact per period of
+       not being in the "online" status.  Can also set some contacts
+       to never receive these auto-responses.
+- Allow other ICQ user to request "online notifications" (Me)
+       This works by the other user sending you a message with the
+       magic string ",,notify-me" in the message, and when you next
+       change status to "online", anyone who has sent you the magic
+       string gets sent a message saying you're back online.
+- Global key prefix (default is M-`) customisable (Me)
+       Also most of the previously globally bound keys have been
+       removed from the global map.  Now all that is in the global
+       map is what is really needed, things like eicq-login and
+       eicq-show-window. 
+- Contact names appear in buddy buffer in the same order as world (ME)
+- Contact histories (Alexey Mikhailov)
+       Adds mICQ-style history for each contact.  Turn it on with:
+               (setq eicq-history-enabled-flag t)
+- Eicq-track (Alexey Mikhailov)
+       ERC/Riece style modeline indicator.
+- Handle "invisible" status correctly (Me)
+       This is something that Eicq has never done right, up until
+       now.  It is possible to be invisible _and_ online or away or
+       na etc.
+- Make Eicq usable on a TTY/console (Me)
+       Who says you need a GUI to chat on ICQ? :-)
+
+* 0.5.9 to 0.6
+
+- Switch from n.n.n to n.n version numbers.
+       Actually, these n.n version numbers are only seen on the
+       tarball filenames etc.  The version string you see from 
+       M-x eicq-version looks like:
+
+       Eicq: steve@eicq.org--2005/eicq--main--0.6--patch-15
+
+- Development was moved away from SF.net and is now done all
+       "in-house" at eicq.org.
+- Switched to GNU/Arch version control instead of CVS.
+- Many additions/fixes to protocol code (Evgeny Zajcev, Me)
+- Make it easy for people to donate to the project (Me)
+       M-x eicq-donate
+
+
+* 0.5.0 to 0.5.9
+
+- Switched to BSD license.
+
+* 0.2.17 to 0.5.0
+
+- Major cleanup and restructuring (Me)
+       Lots and lots of stuff has changed, see the ChangeLog for all
+       the gory details.  Oh, it would be a REALLY GOOD IDEA if you
+       remove any previous version of Eicq BEFORE you install this
+       one.  Yes, it's changed THAT much.
+
+       We haven't achieved ICQv8 protocol compliance yet, but
+       hopefully, we'll be at least partially there with this
+       release. 
+
+* 0.2.16 to 0.2.17
+
+- Auto-reconnect (Me)
+       Don't attempt to reconnect if a password isn't set or if
+       delete-offline-messages is set to 'ask.
+- Buddy buffer reset to pre-logged-in-state on logout. (Me)
+- eicq-connect/disconnect cleanup (Erik Arneson, Me)
+- New function 'eicq-search-by-uin' (Me)
+       Search for a user by their ICQ number.
+- New function 'eicq-add-user' (Me)
+       Dynamically add a new contact to you buddy list.
+- Eicq is now "web-aware" capable. (Me)
+- EicqWharf cleanup (Erik Arneson)
+       Don't try to do anything unless the Wharf frame has been
+       created. 
+
+
+* 0.2.15 to 0.2.16
+
+- Bug report code cleanup/enhancement. (Me)
+- Use 'locate-data-directory' to find data files. (Me)
+- eicq-wharf.el New file (Erik Arneson)
+       Create a tiny frame suitable for docking.  Keeps track of
+       number of new messages.
+- New hooks to use with eicq-wharf.el (Me)
+- 2nd set of auto-response messages (Me)
+       To be used when you have idled away as opposed to explicitly
+       marking yourself away (not yet working).
+- Cleaner layout for query output. (Me)
+- Remove background colour settings. (Me)
+- Auto-reconnect if kicked off ICQ server. (Me)
+- Don't log outgoing auto-response messages. (Me)
+- Optionally auto-save the log file on exiting Eicq. (Me)
+
+* 0.2.14 to 0.2.15
+
+- Cygwin builds (Thorsten Bonow)
+       Add cygwin related comments to Makefile, INSTALL,
+       eicq-user-install.sh 
+- New file 'eicq-convert.el' (Erik Arneson)
+       Convert Licq and Micq contact lists to Eicq 'world' format.
+- Makefile improvements (Erik Arneson).
+- icq2tcp.c (Erik Arneson)
+       Ported from the C++ icq2tcp.cc to ANSI C
+- Better handling of remote bridges (Erik Arneson).
+- Optionally start Eicq in its own frame (Erik Arneson).
+- Implement auto-response messages (Me).
+- Update URLs to reflect SourceForge's new domain 'sf.net'(Me).
+- Solaris builds (Jack Twilley)
+       Add needed changes to Makefile to build on Solaris.
+
+* 0.2.13 to 0.2.14
+
+- Rewrote the bug report code.  
+       It now reports any user variable that has be changed 
+       from the default.
+- eicq-version now accepts arg.
+       So C-u M-x eicq-version RET will insert the version string
+       in the current buffer at point.
+- Added type boolean to all the 'on/off' defcustoms.
+- Removed some obsolete v2 stuff.
+- Renamed udp2tcp.cc to icq2tcp.cc
+- Added new target "pkg" to Makefile
+       It builds Eicq and creates a tarball that can be used to
+       install Eicq simply by unpacking the tarball into the 
+       appropriate directory.
+       
+
+* 0.2.12 to 0.2.13
+
+- The number of tools on toolbar reduced.
+- Statuses moved from buddy buffer to their own read-only buffer.
+- Smilies 
+- URL/email highlighting in normal messages.
+- Can turn sounds off/on.
+
+* 0.2.11 to 0.2.12
+
+- Change status via widgets in the buddy buffer.
+- In log buffer:
+       'n' move to next unread message
+       'p' move to previous unread message
+       'N' move to next message (whether read or unread)
+       'P' move to previous message (whether read or unread)
+       Outgoing messages are automatically marked as read.
+- Auto away/na timeouts now work correctly.
+- Auto online after a auto away/na.
+- Use the same toolbar in both the log and buddy buffers.
+- M-x eicq-login automatically brings up the buddy and log buffers.
+- The toolbar button "Disconnect":
+       Does a 'eicq-logout'
+       Kills the Eicq buffers.
+
+* 0.2.10 to 0.2.11
+
+- 'eicq-report-bug' now working.
+
+* 0.2.9 to 0.2.10
+
+- No longer distributed as an XEmacs package (due to compatibility issues)
+- Re-arrange variables so that everything compiles cleanly with no errors.
+- Uses XEmacs to create the info documentation.
+
+* 0.2.8 to 0.2.9
+
+- New function 'eicq-report-bug'
+- 'eicq-email-author' uses Gnus if available.
+
+* 0.2.5 to 0.2.8
+
+- Mainly just doc fixes.
+
+* 0.2.4 to 0.2.5
+
+- entered into the mainstream XEmacs packages
+
+* 0.2.3 to 0.2.4
+
+- clickety click toolbars
+- new locations for files (a system wide approach)
+- more sound
+
+* 0.2.2 to 0.2.3
+
+- sound added
+
+* 0.2.1 to 0.2.2
+
+- highlight alias and url (from Erik)
+- world-mode
+- eicq-change-user, eicq-hide-window
+
+* 0.2.0 to 0.2.1
+
+- remove relogin, more stable
+
+* 0.1.3 to 0.2.0
+
+- ICQ version 5 protocol
+- meta user info query and update
+- register new user, change password
+- receive contact list transfer
+- forward message
+- more stable (less kicked out)
+
+* 0.1.2 to 0.1.3
+
+- restructure of eicq-world
+- use resource file instead of lisp structure
+- new files in package: NEWS and world (resource file)
+- alias selection as temporary group
+- fixed random popping up uin
+- safer udp2tcp: use length prefix instead of delimiting magic string
+- eicq-do-status-update-hook and eicq-do-message-hook for customization
+- split and send long messages
+- search users, update basic info and extended info
+- relogin quiently after being kicked out
+- auto-na
+
+
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..5ef5982
--- /dev/null
+++ b/README
@@ -0,0 +1,220 @@
+-*- outline -*-
+
+* Introduction
+
+http://www.emchat.org/INSTALL
+
+This file is best viewed under (S)XEmacs. Press C-c C-o now to
+see the outline of topics. You can use (S)XEmacs menu to
+navigate and hide/show different topics. (C-c means Control
+and c; M-x means Meta and x.)
+
+I publish this package in the hope of making more people
+appreciate (S)XEmacs and Lisp.
+
+You can contact me for anything at <steve@emchat.org>
+
+* Feature list
+
+- EMchat is written entirely in elisp
+- EMchat uses the latest version of the ICQ protocol. (OSCAR)
+- Send/receive messages
+- Send/receive URL type messagse
+- Send/Receive authorisation request messages
+- Approve/Decline incoming auth requests
+- Query ICQ users' meta info
+- Search for ICQ users
+- Dynamically add new users to your contact list (recent protocol
+  changes broke this)
+- Play sounds for different events.
+- Auto online after a auto away/na.
+- Auto response away/na/dnd/occ messages.
+- Different auto response messages if EMchat has idled away/na
+- Auto reconnect if you are kicked off ICQ.
+- Gnus style smileys
+- Gnus style text emphasis (underline, bold, italic, etc)
+- "Clickable" hyperlinks for URL's, email addresses, and Unix manual page titles
+- climm (mICQ) style per contact history logs
+- ERC/Riece style modeline activity indicator
+- Works in both a GUI environment and on a console/TTY (even both at the same time)
+- A dockable frame that tracks the number of unread messages.
+- Interactive customisation through (S)XEmacs Custom widgets.
+- Key binding, "scripting" in elisp.
+- Allow other users/contacts to psycho-analyse themselves
+- Display X-Face/Colour Face header images in buddy buffer.
+- An "oops" function
+- Customisable semi-automation
+
+
+EMchat cannot yet transfer files, chat, or anything that requires a
+peer-to-peer direct TCP connection.  This is not a limitation of
+EMchat, but rather of XEmacs.  As yet, XEmacs can not "listen" for an
+incoming TCP connection.
+
+P2P _IS_ coming!  SXEmacs now has server sockets, we just have to use
+em in EMchat.
+
+* Installation
+See the file 'INSTALL' in this directory.
+
+There are a few mailing lists. See <http://www.emchat.org/#maillist>
+
+Have fun!
+
+* Submitting Patches
+
+If you've got a patch for a bug fix or some wiz-bang new feature mail
+them to <emchat-devel@emchat.org>.  The EMchat developers will review your
+contribution and either accept it and add it to the EMchat code, or
+reject it.  Whether accepted or rejected, you'll hear back from us.
+
+Please be aware though that because of spam levels the EMchat mailing
+list is a members-only posting.  If you are not subscribed you'll have
+to wait for the moderator to process your post.  Please be patient,
+he's a rilly busy guy. :-)
+
+* Faq and tips
+
+** password
+
+How to save password?
+
+M-x customize-variable RET emchat-user-password
+Or simply, (setq emchat-user-password "mypassword") in your
+`user-init-file'. 
+
+** "M" vs "m" (send-message)
+
+Commands in capital letters prompt you for aliases/uin while
+those in small letters search for aliases/uin around the
+cursor in emchat buffers, and perform actions on them. For
+example, "m" inside an incoming message acts like a reply.
+
+** alias vs uin
+
+"JackaLX" is my alias while "34307457" is my uin. In all prompts
+of entering an icq person, you can enter either an alias or
+an uin, although only alias completing read is provided. 
+(Press TAB when entering an alias!)
+
+** message/alias history
+
+Use M-p/M-n or UP/DOWN to navigate history in prompts of
+entering alias or messages.
+Use M-r/M-s to search history.
+
+** log file size
+
+Watch out for monster emchat-log buffer size! Use M-x
+emchat-log-new-file occasionally.
+
+As of version 0.2.16 Eicq will automatically save the log file when
+you disconnect from ICQ.  You can change this behaviour with
+'M-x emchat-customize' in the 'emchat-log' group.
+
+** hooks
+
+If you want to customize anything fancy:
+
+emchat-buddy-mode-hook
+emchat-log-mode-hook
+emchat-new-message-hook
+emchat-read-message-hook
+emchat-status-update-hook
+emchat-system-message-hook
+
+** Using EMchatWharf
+
+EMchatWharf is a tiny frame that shows the number of unread messages you
+have.  It is suitable for docking into the GNOME panel (YMMV).  I use
+it with Sawfish WM (in a "sawlet" dockapp thingy).  And I've also used
+EMchatWharf in FVWM by simply setting the geometry and making it
+sticky from my FVWM rc file.
+
+To get the EMchatWharf frame put into your (S)XEmacs init file:
+
+(require 'emchat-wharf)
+(setq emchat-wharf-frame-use-p t)
+(add-hook 'emchat-new-message-hook #'emchat-wharf-inc-messages)
+(add-hook 'emchat-system-message-hook #'emchat-wharf-inc-system)
+(add-hook 'emchat-read-message-hook #'emchat-wharf-dec-messages)
+
+*** Add Riece integration to EMchatWharf
+
+Riece is a VERY good emacs IRC client (I highly recommend it).  If
+you'd like to know when there is activity in your Riece frame, you can
+have EMchatWharf tell you.  All you have to do is add this to the
+above EMchatWharf settings...
+
+(setq emchat-wharf-notice-riece-flag t)
+(add-hook 'riece-biff-activity-hook #'emchat-wharf-riece-active)
+(add-hook 'riece-biff-clear-hook #'emchat-wharf-riece-inactive)
+
+And then turn on riece-biff in your Riece settings
+
+** EMchat in its own frame
+
+You can optionally start EMchat in its own frame with:
+
+(setq emchat-start-in-new-frame t)
+
+** Using EMchat-Track
+
+EMchat-Track is a modeline indicator that tells you when you have new
+messages.  To turn it on, just put in your (S)XEmacs init file:
+
+(setq emchat-track-enable t)
+
+** Using EMchat-History
+
+EMchat-History are per contact history files.  Basically individual logs
+for each contact.  Turn it on with:
+
+(setq emchat-history-enabled-flag t)
+
+** Displaying X-Face or colour Face Images in buddy buffer
+
+You can display X-Face images (or colour face images) in the buddy
+buffer, but it does require a little setting up, both in EMchat and in
+BBDB.
+
+*** EMchat Setup
+
+This is the easy part, all you need to do is:
+
+  (setq emchat-buddy-show-xface t)
+
+*** BBDB Setup
+
+First of all, you need a new field called "icqnick" for each EMchat
+contact that is in your BBDB.  This field's value is the alias name
+from EMchat (the name displayed in the buddy buffer).
+
+  M-x bbdb-insert-new-field RET icqnick RET
+
+  answer `yes' to the prompt about `icqnick' isn't a known field,
+  define it?
+
+  Then just give it the desired value (contact name)
+
+You'll also have to set up BBDB to collect X-Face and colour face
+headers from your mail.  For some docs on how to do that, see:
+
+  <http://www.emacswiki.org/cgi-bin/wiki/BbdbFaces>
+
+** newline
+
+How to enter new lines in minibuffer? 
+
+       Type 'Hello C-q 12 World'
+
+To get:
+
+       Hello
+       world
+
+** (S)XEmacs Init File tips
+
+(resize-minibuffer-mode 1)
+
+
diff --git a/TODO b/TODO
new file mode 100644 (file)
index 0000000..d87c8ed
--- /dev/null
+++ b/TODO
@@ -0,0 +1,59 @@
+-*- outline -*-
+
+* Last Updated: June 14, 2005
+
+Disregard the date there, this file is hideously out of date, it will
+be fixed up in the next release.
+
+Here's a list of things I may or may not get around to putting
+into EMchat.
+
+This list is not in order of importance or any kind of order at all.
+And just because something is on the list doesn't mean that it will
+become part of EMchat.
+
+Feel free to do any of these things and send a patch to
+<emchat-devel@emchat.org>
+
+* Todo list
+
+** Direct TCP, file transfer/chat.
+
+       Can't do this until (S)XEmacs has server sockets.
+
+** Pop-up/permanent window for entering long message.
+
+** Store offline messages and send them when online.
+
+** Security problem of `emchat-user-password' in init file.
+
+** Openssl support.
+
+** Do something useful with the 'group' code.
+
+       Send message to multiple contacts etc etc.
+
+** Ignore that annoying spammer!
+       
+       There are definitely times when you'd rather not hear what
+       someone has to say. Mwuahahah!
+
+** Triggers
+
+        Imagine running an elisp defun whenever an EMchat message matching
+       a particular regular expression comes in.  This functionality
+       will need to be documented carefully due to the security 
+       implications, of course.
+
+** Externally triggered messages
+
+       biff meets EMchat.  "Hey, you just got some email.  You better 
+       read it."  Or maybe "The power is out and your UPS just kicked 
+       on.".  The sky is the limit.
+
+** PostgreSQL support
+
+       Take advantage of XEmacs' PostgreSQL support for storing and
+       retrieving all kinds of useless data about your contacts.
+
+
diff --git a/build.el b/build.el
new file mode 100644 (file)
index 0000000..6c6cece
--- /dev/null
+++ b/build.el
@@ -0,0 +1,78 @@
+;;; build.el --- Builds EMchat.
+;;
+;; Copyright (C) 2006 Sebastian Freundt
+;; Copyright (C) 2007 Steve Youngs
+;;
+;; Author: Sebastian Freundt <hroptatyr@sxemacs.org>
+;; Maintainer: EMchat Development Team
+;; Keywords: internal
+;;
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+;;
+;;; Synched up with: Not in FSF.
+
+;;; Commentary:
+;;
+;;  This file is only used during EMchat builds, it does what the name
+;;  implies... builds the lisp, plus it generates auto-autoloads.el,
+;;  custom-load.el and custom-define.el files.
+
+;;; Code:
+(setq stack-trace-on-error t)
+
+(defvar wd default-directory)
+(push wd load-path)
+
+(defvar needed '(cus-dep autoload bytecomp byte-optimize font))
+(mapcar #'require needed)
+
+(defalias #'executable-find #'ignore)
+
+(let ((pname "emchat")
+      (adir wd))
+  (update-autoload-files adir pname)
+  (Custom-make-dependencies adir)
+  (update-custom-define-files adir pname))
+
+(load "prepsrc")
+
+(mapcar
+ #'(lambda (sym)
+     (let ((file (symbol-name sym)))
+       (when (string= file "custom-defines.el")
+        (autoload 'emchat-emphasis-custom-with-format
+          "emchat-emphasis" nil nil 'macro))
+       (byte-compile-file (expand-file-name file wd))))
+ srcfiles)
+
+;; indicate success
+(kill-emacs 0)
+
+;;; build.el ends here
diff --git a/emchat-buddy.el b/emchat-buddy.el
new file mode 100644 (file)
index 0000000..4ac4bf0
--- /dev/null
@@ -0,0 +1,363 @@
+;;; emchat-buddy.el --- "Buddy" code for EMchat
+
+;; Copyright (C) 2007 Steve Youngs
+
+;; Author:        Steve Youngs <steve@emchat.org>
+;; Maintainer:    Steve Youngs <steve@emchat.org>
+;; Created:       2002-10-01
+;; Homepage:      http://www.emchat.org/
+;; Keywords:      comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(eval-and-compile
+  (require 'emchat-menu)
+  (require 'emchat-status)
+  (require 'emchat-world)
+  (require 'emchat-history))
+
+(eval-when-compile
+  (require 'advice)
+  (require 'bbdb))
+
+(defgroup emchat-buddy nil
+  "Contact list preferences."
+  :group 'emchat)
+
+;;;###autoload
+(defcustom emchat-buddy-window-width 20
+  "*Width of window for `emchat-buddy-buffer'."
+  :group 'emchat-interface)
+
+(defcustom emchat-buddy-view 
+  'emchat-connected-aliases
+  "*View of buddy buffer.
+It determines what aliases to be display in buddy buffer.  For example,
+\(emchat-connected-aliases) means display all connected aliases.
+
+See `emchat-buddy-view-all', `emchat-buddy-view-connected', and
+`emchat-buddy-view-active'."
+  :group 'emchat-buddy
+  :type '(choice (item emchat-all-aliases)
+                 (item emchat-connected-aliases)
+                 (item emchat-active-aliases))
+  :initialize 'custom-initialize-default)
+
+(defcustom emchat-buddy-show-xface nil
+  "*When non-nil, display XFace images in the buddy buffer.
+
+The images come from BBDB.  For an image to display in the buddy
+buffer there has to be an existing BBDB entry for the contact that
+has both a `face' field, for the image, and a `icqnick' field, to
+match from the contact name in the buddy buffer."
+  :type 'boolean
+  :group 'emchat-buddy
+  :require 'bbdb)
+
+(defcustom emchat-buddy-prefer-cface-to-xface (featurep 'png)
+  "*When non-nil, display colour faces instead of X-Face if available."
+  :type 'boolean
+  :group 'emchat-buddy)
+
+(defface emchat-face-selected
+  '((((background dark))
+     (:foreground "darkblue" :background "yellow"))
+    (((background light))
+     (:foreground "darkblue" :background "yellow")))
+  "Face for OFFLINE status."
+  :group 'emchat-buddy)
+
+;;; Internal variables
+
+;;;###autoload
+(defvar emchat-buddy-buffer nil
+  "Buffer for contact list.")
+
+(defun emchat-buddy-mode ()
+  "Major mode for contact list in emchat.
+Commands: \\{emchat-buddy-mode-map}
+
+Turning on `emchat-buddy-mode' runs the hook `emchat-buddy-mode-hook'."
+  (interactive)
+  (kill-all-local-variables)
+  (use-local-map emchat-buddy-mode-map)
+  (setq mode-name "emchat-buddy")
+  (setq major-mode 'emchat-buddy-mode)
+  ;; put easy-menu-add after set mode-name
+  (easy-menu-add emchat-main-easymenu)
+  (easy-menu-add emchat-buddy-menu)
+  (easy-menu-add emchat-log-menu)
+  (set-specifier has-modeline-p nil
+                (cons (current-buffer) nil))
+  (set-specifier horizontal-scrollbar-visible-p nil
+                (cons (current-buffer) nil))
+  ;(setq modeline-format "%b")
+
+  (run-hooks 'emchat-buddy-mode-hook))
+
+(defun emchat-buddy-view-set (&optional symbol value)
+  "Set `emchat-buddy-view'."
+  (set-default symbol value)
+  (emchat-buddy-show-buffer 'new 'no-select))
+
+(defun emchat-face-to-png (face)
+  "Base64 decode a Face header into a PNG.
+Returns a string."
+  (with-temp-buffer
+    (insert face)
+    (base64-decode-region (point-min) (point-max))
+    (buffer-string)))
+
+(defun emchat-buddy-show-xface (alias)
+  "Display an XFace image in the buddy buffer."
+  (unless (featurep '(and xface bbdb-autoloads))
+    (error 'unimplemented "X-Face and/or BBDB"))
+  (save-excursion
+    (when (buffer-live-p emchat-buddy-buffer)
+      (set-buffer emchat-buddy-buffer)
+      (goto-char (point-min))
+      (when (search-forward-regexp (concat "^" (regexp-quote alias) "$") nil t)
+       (let ((ext (extent-at (point)))
+             (all-records (bbdb-records))
+             face cface nick record)
+         (while all-records
+           (setq record (car all-records)
+                 nick (bbdb-record-getprop record 'icqnick)
+                 face (bbdb-record-getprop record 'face)
+                 cface (bbdb-record-getprop record 'cface))
+           (when (and (equal nick alias)
+                      (or face cface))
+             ;; put some whitespace between the image and the name
+             (set-extent-begin-glyph
+              (make-extent (point-at-bol) (point-at-eol))
+              (make-glyph " "))
+             ;; Insert the X-Face
+             (when (and face
+                        (or (not emchat-buddy-prefer-cface-to-xface)
+                            (not cface)))
+               (set-extent-begin-glyph 
+                ext
+                (make-glyph (list (vector 'xface
+                                          :data (concat "X-Face: " face)
+                                          :foreground "black"
+                                          :background "white")))))
+             ;; Insert the cface
+             (when (and (featurep 'png)
+                        cface
+                        emchat-buddy-prefer-cface-to-xface)
+               (set-extent-begin-glyph
+                ext
+                (make-glyph (list (vector 'png
+                                          :data (emchat-face-to-png cface)))))))
+           (setq all-records (cdr all-records))))))))
+
+;;;###autoload
+(defun emchat-buddy-show-buffer (&optional new no-select)
+  "Switch to `emchat-buddy-buffer'.
+Create buffer if buffer does not exists already or
+NEW is non-nil.
+Don't select buddy window if NO-SELECT is non-nil.
+See `emchat-buddy-view' and `emchat-buddy-status-color-hint-flag'."
+  (interactive)
+  (when (or (not (buffer-live-p emchat-buddy-buffer))
+            new)
+    (setq emchat-buddy-buffer (get-buffer-create "*emchat buddy*"))
+    (set-buffer emchat-buddy-buffer)
+    (erase-buffer)
+    (loop for alias in (symbol-value emchat-buddy-view)
+      as status = (emchat-world-getf alias 'status)
+      as face = (emchat-status-face status)
+      do (insert-face (concat alias "\n") face)
+      do (when emchat-buddy-show-xface (emchat-buddy-show-xface alias))
+      do (emchat-buddy-update-face alias))
+    (emchat-buddy-mode))
+  (unless no-select
+    (switch-to-buffer emchat-buddy-buffer)))
+
+(defun emchat-buddy-view-all ()
+  "Display all aliases in `emchat-world'.
+See `emchat-buddy-view'."
+  (interactive)
+  (emchat-buddy-view-set 'emchat-buddy-view 'emchat-all-aliases))
+
+(defun emchat-buddy-view-connected ()
+  "Display all connected aliases.
+See `emchat-buddy-view' and `emchat-connected-aliases'."
+  (interactive)
+  (emchat-buddy-view-set 'emchat-buddy-view 'emchat-connected-aliases))
+
+(defun emchat-buddy-view-active ()
+  "Display all active aliases.
+See `emchat-buddy-view' and `emchat-active-aliases'."
+  (interactive)
+  (emchat-buddy-view-set 'emchat-buddy-view 'emchat-active-aliases))
+
+(eval-when-compile (defvar emchat-history-directory))
+
+(defun emchat-buddy-show-xface-in-balloon (alias)
+  "Display an XFace image in the balloon-help buffer."
+  (unless (featurep '(and xface bbdb-autoloads))
+    (error 'unimplemented "X-Face and/or BBDB"))
+  (save-excursion
+    (let ((ext (or (extent-at (point))
+                  (make-extent (point-min) (point-min))))
+         (all-records (bbdb-records))
+         face cface nick record)
+      (while all-records
+       (setq record (car all-records)
+             nick (bbdb-record-getprop record 'icqnick)
+             face (bbdb-record-getprop record 'face)
+             cface (bbdb-record-getprop record 'cface))
+       (when (and (equal nick alias)
+                  (or face cface))
+         ;; put some whitespace between the image and the name
+         (set-extent-begin-glyph
+          (make-extent (point-min) (point-min))
+          (make-glyph " "))
+         ;; Insert the X-Face
+         (when (and face
+                    (or (not emchat-buddy-prefer-cface-to-xface)
+                        (not cface)))
+           (set-extent-begin-glyph 
+            ext
+            (make-glyph (list (vector 'xface
+                                      :data (concat "X-Face: " face)
+                                      :foreground "black"
+                                      :background "white")))))
+         ;; Insert the cface
+         (when (and (featurep 'png)
+                    cface
+                    emchat-buddy-prefer-cface-to-xface)
+           (set-extent-begin-glyph
+            ext
+            (make-glyph (list (vector 'png
+                                      :data (emchat-face-to-png cface)))))))
+       (setq all-records (cdr all-records))))))
+
+(defadvice balloon-help-display-help (after emchat-balloon-xface (&rest args) activate)
+  "Display an X-Face or cface image in the balloon."
+  (when emchat-buddy-show-xface
+    (let ((alias (progn
+                  (set-buffer balloon-help-buffer)
+                  (goto-char (point-min))
+                  (when (re-search-forward "\\(^.*\\) (" (eolp) t)
+                    (substring (match-string 1) 1)))))
+      (when alias
+       (emchat-buddy-show-xface-in-balloon alias)))))
+
+(defun emchat-buddy-update-face (alias &optional delete)
+  "Update face of ALIAS.
+Non-nil DELETE means delete alias from buffer."
+  (save-excursion
+    (when (buffer-live-p emchat-buddy-buffer)
+      (set-buffer emchat-buddy-buffer)
+      (goto-char (point-min))
+
+      (if (search-forward-regexp
+           ;; use "^" alias "$" so searching "foo" will not get "foobar"
+           (concat "^"
+                   ;; to allow funny characters in alias
+                   (regexp-quote alias)
+                   "$")
+           nil t)
+          ;; old alias
+          (if delete
+              (delete-region
+               (point-at-bol)
+               ;; take care of last line
+               (min (1+ (point-at-eol)) (point-max))))
+        ;; new alias
+        (unless delete
+          (insert alias "\n")
+          (forward-line -1)))
+
+      (unless delete
+       (let* ((ext (extent-at (point)))
+              (bhelp (format 
+                      "%s (%s)\n Status: %s\n Groups: %s\nHistory: %s\n\n\n"
+                      alias
+                      (emchat-alias-uin alias)
+                      (or (emchat-world-getf alias 'status)
+                          "offline")
+                      (or (emchat-world-getf alias 'group)
+                          "none")
+                      (or (emchat-world-getf alias 'history)
+                          "none")))
+              (face (emchat-status-face (emchat-world-getf alias 'status))))
+         (when (extentp ext)
+           (set-extent-property ext 'face face)
+           (set-extent-property ext 'balloon-help bhelp))
+
+         (when (emchat-world-getf alias 'selected)
+           ;; highlight first char
+           (put-text-property
+            (+ 0 (point-at-bol)) (+ 1 (point-at-bol))
+            'face 'emchat-face-selected)))))))
+
+(defun emchat-buddy-select-all-in-view (state &optional predicate)
+  "Select all aliases in current view.
+See `emchat-group-select-aliases' for STATE.
+PREDICATE accepts an alias as an argument and limits the application.
+Current view is `emchat-buddy-view'."
+  (loop for x in (symbol-value emchat-buddy-view)
+    if (or (null predicate)
+           (funcall predicate x))
+    do (emchat-group-select-aliases state x)))
+
+(defun emchat-buddy-select-all-in-view-by-status (status)
+  "Toggle selections of all aliases with STATUS in current view."
+  (interactive
+   (list (emchat-completing-read "status: " emchat-valid-statuses)))
+  (emchat-buddy-select-all-in-view
+   'toggle
+   (lambda (x)
+     (equal (emchat-world-getf x 'status) status))))
+
+(defun emchat-buddy-select-all-in-view-by-regexp (regexp)
+  "Toggle selections of all aliases matching REGEXP in current view."
+  ;; checked my screenshots? know why i use a symbol prefix now?
+  (interactive "sregexp: ")
+  (emchat-buddy-select-all-in-view
+   'toggle
+   (lambda (x)
+     (string-match regexp x))))
+
+(defun emchat-buddy-selected-in-view ()
+  "Return a list of all selected aliases in current view.
+Selected means an alias has non-nil 'selected property.
+Current view is `emchat-buddy-view'."
+  (loop for x in (symbol-value emchat-buddy-view)
+    if (emchat-world-getf x 'selected)
+    collect x))
+
+(provide 'emchat-buddy)
+
+;;; emchat-buddy.el ends here
+
diff --git a/emchat-convert.el b/emchat-convert.el
new file mode 100644 (file)
index 0000000..c3b9286
--- /dev/null
@@ -0,0 +1,112 @@
+;;; emchat-convert.el --- Utilities to convert other ICQ configurations to EMCHAT
+
+;; Copyright (C) 2001 - 2007 Steve Youngs, Erik Arneson
+
+;; OriginalAuthor: Erik Arneson <erik@aarg.net>
+;; Maintainer: Erik Arneson <erik@aarg.net>
+;; Created: Aug 06, 2001
+;; Homepage: http://www.emchat.org/
+;; Keywords: comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(eval-and-compile
+  (require 'emchat-world))
+
+;;;###autoload
+(defun emchat-import-from-licq ()
+  "Import your contact list from LICQ.  It doesn't import ignored UIDs."
+  (interactive)
+  (let (uin udat user-alist ignored)
+    (setq user-alist
+          (loop for file in (directory-files
+                             (expand-file-name "~/.licq/users/") t nil nil t)
+            when (file-readable-p file)
+            do (progn
+                 (string-match "/\\([0-9]+\\)\\.uin$" file)
+                 ;; Why can't I use 'match-string' here?  Gah!
+                 (setq uin (subseq file (match-beginning 1) (match-end 1)))
+                 (set-buffer (find-file-noselect file))
+                 ;; Need to also look for 'Groups.System = 24' to find
+                 ;; out if the user is ignored.
+                 (if (re-search-forward "^Groups.System = 24$" nil t)
+                     (setq ignored t)
+                   (setq ignored nil)
+                   (goto-char (point-min))
+                   ;; If an Alias is listed, use that.  Otherwise, set
+                   ;; the alias to the UIN.
+                   (if (re-search-forward "^Alias = \\(.*\\)$" nil t)
+                       (setq udat (cons uin (match-string 1)))
+                     (setq udat (cons uin uin))))
+                 (kill-buffer (current-buffer)))
+            when (not ignored)
+            collect udat))
+    (set-buffer (find-file-noselect (expand-file-name emchat-world-rc-filename)))
+    (goto-char (point-max))
+    (insert "\n\n==== These entries were imported from your LICQ configuration.\n")
+    (loop for udat in user-alist
+      do (insert (format ":icq %s %s :licq\n" (car udat) (cdr udat))))
+    (save-buffer (current-buffer))
+    (kill-buffer (current-buffer))))
+
+;;;###autoload
+(defun emchat-import-from-micq ()
+  "Import ICQ contact data from a .micqrc file."
+  (interactive)
+  (let (user-alist
+        unode me)
+    (set-buffer (find-file-noselect 
+                (or (expand-file-name "micqrc"
+                                      (file-name-as-directory
+                                       (expand-file-name ".micq"
+                                                         (user-home-directory))))
+                    (expand-file-name ".micqrc" (user-home-directory)))))
+    (goto-char (point-min))
+    (if (re-search-forward "^UIN \\([0-9]+\\)$" nil t)
+        (setq me (match-string 1)))
+    (if (re-search-forward "^Contacts$\\|^\\[Contacts\\]$" nil t)
+        (setq user-alist
+              (loop while (re-search-forward 
+                          "^[ \t]*\\*?\\([0-9]+\\)[ \t]+\\(.*\\)$" nil t)
+                do (setq unode (cons (match-string 1) (match-string 2)))
+                collect unode)))
+    (kill-buffer (current-buffer))
+    (set-buffer (find-file-noselect (expand-file-name emchat-world-rc-filename)))
+    (goto-char (point-max))
+    (insert "\n\n==== These entries were imported from your MICQ configuration.\n")
+    (if me
+        (insert (format ":icq %s me\n\n" me)))
+    (loop for unode in user-alist
+      do (insert (format ":icq %s %s :micq\n" (car unode) (cdr unode))))
+    (save-buffer (current-buffer))
+    (kill-buffer (current-buffer))))
+
+;; End of file.
+
diff --git a/emchat-curl.el b/emchat-curl.el
new file mode 100644 (file)
index 0000000..50bfd8a
--- /dev/null
@@ -0,0 +1,193 @@
+;; emchat-curl.el --- Download files from log buffer   -*- Emacs-Lisp -*-
+
+;; Copyright (C) 2007 Steve Youngs
+
+;; Author:     Steve Youngs <steve@emchat.org>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Created:    <2007-08-31>
+;; Homepage:   http://www.emchat.org/
+;; Keywords:   curl download ICQ emchat file
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;; 
+;;    Download stuff from URls in your log buffer via ffi-curl.el.
+;;    That means you need SXEmacs to use this.
+
+;;; Todo:
+;;
+;;     
+
+;;; Code:
+(eval-when-compile
+  (require 'emchat-utils)
+  (autoload #'curl:download& "ffi-curl")
+  (autoload #'curl:easy-getinfo "ffi-curl")
+  (defvar curl:errors-alist))
+
+(define-error 'emchat-curl
+  (if (featurep 'sxemacs)
+      "Your SXEmacs lacks FFI support"
+    "FFI not available in your emacs, consider upgrading to SXEmacs"))
+
+(defgroup emchat-curl nil
+  "EMchat's FFI/Curl"
+  :prefix "emchat-curl-"
+  :group 'emchat)
+
+(defcustom emchat-curl-download-directory
+  (file-name-as-directory (paths-construct-path
+                          '("download") emchat-directory))
+  "*Default download directory."
+  :type 'directory
+  :group 'emchat-curl)
+
+(defcustom emchat-curl-hook-function #'emchat-curl-post-hook
+  "This function is called after a successful file download.
+
+It must accept one argument, JOB, which contains the worker-job just
+finished."
+  :type 'function
+  :group 'emchat-curl)
+
+;;; Internal variables
+
+(defvar emchat-curl-file nil)
+(defvar emchat-curl-dir nil)
+
+(defun emchat-curl-post-hook (job)
+  "Default function called after downloading files."
+  (let* ((ctx (get job 'ctx))
+        (resp (curl:easy-getinfo ctx :response-code))
+        (url (curl:easy-getinfo ctx :effective-url))
+        (speed (curl:easy-getinfo ctx :speed-download))
+        (size (curl:easy-getinfo ctx :size-download))
+        (file (expand-file-name emchat-curl-file emchat-curl-dir))
+        (resp-str (cdr (assq resp curl:errors-alist))))
+    (if resp-str
+       (emchat-log-info "Job failed: %s\nReason: %s" job resp-str)
+      (emchat-log-info
+       "Job: %s
+Detail: #<job :url <%s>
+              :local-file \"%s\"
+              :size %d bytes%s
+              :speed %s>
+"
+       job url file size
+       (cond
+       ((>= size (* 1024 1024 1024))
+        (format " (%0.2fGB)" (/ size (* 1024 1024 1024.0))))
+       ((>= size (* 1024 1024))
+        (format " (%0.2fMB)" (/ size (* 1024 1024.0))))
+       ((>= size 1024)
+        (format " (%0.2fKB)" (/ size 1024.0))))
+       (cond
+       ((>= speed (* 1024 1024 1024))
+        (format "%0.2f GB/s" (/ speed (* 1024 1024 1024.0))))
+       ((>= speed (* 1024 1024))
+        (format "%0.2f MB/s" (/ speed (* 1024 1024.0))))
+       ((>= speed 1024)
+        (format "%0.2f KB/s" (/ speed 1024.0)))
+       (t
+        (format "%0.2f B/s" speed)))))))
+
+(emchat-do-in-sxemacs
+ (defregexp emchat-curl-filename-regexp (concat emchat-emphasis-url-regexp 
+                                            "/\\([^/].*$\\)")
+   "Regexp matching the file part of a URL."))
+(emchat-do-in-xemacs
+ (defconst emchat-curl-filename-regexp (concat emchat-emphasis-url-regexp 
+                                            "/\\([^/].*$\\)")
+   "Regexp matching the file part of a URL."))
+
+(defun emchat-curl-url (url file directory)
+  "Download URL to FILE in DIRECTORY."
+  (unless (fboundp #'ffi-defun)
+    (error 'emchat-curl))
+  (add-one-shot-hook 'curl:download&-post-hook emchat-curl-hook-function)
+  (curl:download& url (expand-file-name file directory)))
+
+(defun emchat-curl-url-at-point ()
+  "Downloads url at point."
+  (interactive)
+  (when (extentp (extent-at (point)))
+    (let* ((dir (if current-prefix-arg
+                   (expand-file-name
+                    (read-directory-name "Download directory: "))
+                 emchat-curl-download-directory))
+          (url (extent-string (extent-at (point))))
+          (fregexp emchat-curl-filename-regexp)
+          file)
+      (unless (file-directory-p dir)
+       (make-directory-path dir))
+      (setq file 
+           (and (string-match fregexp url)
+                (not (string=
+                      "/"
+                      (substring
+                       (substring url (match-beginning 2) (match-end 2)) -1)))
+                (substring url (match-beginning 2) (match-end 2))))
+      (if file
+         (progn
+           (emchat-curl-url url file dir)
+           (setq emchat-curl-file file
+                 emchat-curl-dir dir))
+       (message "I don't see a file in: %s" url)))))
+
+(defun emchat-curl-url-at-mouse (event)
+  "Downloads url at event."
+  (interactive "e")
+  (when (extentp (extent-at-event event))
+    (let* ((dir (if current-prefix-arg
+                   (expand-file-name
+                    (read-directory-name "Download directory: "))
+                 emchat-curl-download-directory))
+          (url (extent-string (extent-at-event event)))
+          (fregexp emchat-curl-filename-regexp)
+          file)
+      (unless (file-directory-p dir)
+       (make-directory-path dir))
+      (setq file 
+           (and (string-match fregexp url)
+                (not (string=
+                      "/"
+                      (substring
+                       (substring url (match-beginning 2) (match-end 2)) -1)))
+                (substring url (match-beginning 2) (match-end 2))))
+      (if file
+         (progn
+           (emchat-curl-url url file dir)
+           (setq emchat-curl-file file
+                 emchat-curl-dir dir))
+       (message-or-box "I don't see a file in: %s" url)))))
+
+(provide 'emchat-curl)
+;;; emchat-curl.el ends here
diff --git a/emchat-doctor.el b/emchat-doctor.el
new file mode 100644 (file)
index 0000000..1c0ec2e
--- /dev/null
@@ -0,0 +1,128 @@
+;; emchat-doctor.el --- Let ICQ users psycho-analize themselves
+
+;; Copyright (C) 2005 - 2007 Steve Youngs
+
+;; Author:        Steve Youngs <steve@emchat.org>
+;; Maintainer:    Steve Youngs <steve@emchat.org>
+;; Created:       <2005-09-14>
+;; Homepage:      http://www.emchat.org/
+;; Keywords:      ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;; 
+;; Inspired by riece-doctor.el, where much of this was stolen from. :-)   
+
+;;; Todo:
+;;
+;;     
+
+;;; Code:
+(autoload 'doctor-mode "doctor")
+(autoload 'doctor-read-print "doctor")
+
+(defgroup emchat-doctor nil
+  "Let ICQ users psycho-analyze themselves."
+  :prefix "emchat-"
+  :group 'emchat)
+
+(defcustom emchat-doctor-enabled-flag nil
+  "When non-nil, the doctor is in."
+  :type 'boolean
+  :group 'emchat-doctor)
+
+(defcustom emchat-doctor-begin-string ",,doctor"
+  "When this is received as a msg, start the doctor."
+  :type 'string
+  :group 'emchat-doctor)
+
+(defcustom emchat-doctor-end-string ",,doctor quit"
+  "When this is received as a msg, end the doctor."
+  :type 'string
+  :group 'emchat-doctor)
+
+(defcustom emchat-doctor-hello-string
+  "Hello, I am your therapist.
+To end our session today, just say \",,doctor quit\".
+
+Now, what seems to be the problem, today?"
+  "Initial greeting from the EMchat Doctor."
+  :type 'string
+  :group 'emchat-doctor)
+
+(defcustom emchat-doctor-goodbye-string
+  "Thank you for coming to see me today.
+
+To summarise:  basically, you're nuts.
+
+My invoice will arrive in the mail shortly, 
+unless you are suffering from a split personality 
+disorder, in that case 2 invoices will arrive.
+
+Goodbye, and please don't operate any heavy
+machinery for a while."
+  "String sent when the therapy session ends."
+  :type 'string
+  :group 'emchat-doctor)
+
+;;; Internal variables
+(defvar emchat-doctor-patients nil
+  "List of people who are talking to the doctor.")
+
+(defun emchat-doctor-buffer-name (alias)
+  (concat " *emchat-doctor--" alias "*"))
+
+(defun emchat-doctor-reply (message alias)
+  (emchat-v8-send-simple-message
+   emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias)) message)
+  (emchat-log-outgoing alias ">>> <Doctor>: %s" message))
+
+(defun emchat-doctor (message alias)
+  (if (equal message emchat-doctor-end-string)
+      (progn
+       (setq emchat-doctor-patients (remove alias emchat-doctor-patients))
+       (when (buffer-live-p (emchat-doctor-buffer-name alias))
+         (kill-buffer (emchat-doctor-buffer-name alias)))
+       (emchat-doctor-reply emchat-doctor-goodbye-string alias))
+    (if (equal message emchat-doctor-begin-string)
+       (emchat-doctor-reply "You are already talking to me." alias)
+      (set-buffer (get-buffer-create (emchat-doctor-buffer-name alias)))
+      (doctor-mode)
+      (insert message "\n")
+      (let ((point (point))
+           reply)
+       (doctor-read-print)
+       (setq reply (buffer-substring (1+ point) (- (point) 2)))
+       (emchat-doctor-reply reply alias)))))
+
+(provide 'emchat-doctor)
+;;; emchat-doctor.el ends here
+
diff --git a/emchat-emphasis.el b/emchat-emphasis.el
new file mode 100644 (file)
index 0000000..8529784
--- /dev/null
@@ -0,0 +1,370 @@
+;; emchat-emphasis.el --- Gnus-style text emphasis in EMchat
+
+;; Copyright (C) 2005 - 2007 Steve Youngs
+
+;; Author:        Steve Youngs <steve@emchat.org>
+;; Maintainer:    Steve Youngs <steve@emchat.org>
+;; Created:       <2005-04-29>
+;; Homepage:      http://www.emchat.org/
+;; Keywords:      ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;; 
+;;   "prettify" the log buffer, ala Gnus.  Most of this is unashamedly
+;;   stolen from Gnus.
+
+;;; Todo:
+;;
+;;     
+
+;;; Code:
+(eval-when-compile
+  (autoload 'manual-entry "man" nil t))
+
+(defmacro emchat-emphasis-custom-with-format (&rest body)
+  `(let ((format "\
+\\(\\s-\\|^\\|\\=\\|[-\"]\\|\\s(\\)\\(%s\\(\\w+\\(\\s-+\\w+\\)*[.,]?\\)%s\\)\
+\\(\\([-,.;:!?\"]\\|\\s)\\)+\\s-\\|[?!.]\\s-\\|\\s)\\|\\s-\\)"))
+     ,@body))
+
+(defun emchat-emphasis-custom-value-to-external (value)
+  (emchat-emphasis-custom-with-format
+   (if (consp (car value))
+       (list (format format (car (car value)) (cdr (car value)))
+            2
+            (if (nth 1 value) 2 3)
+            (nth 2 value))
+     value)))
+
+(defun emchat-emphasis-custom-value-to-internal (value)
+  (emchat-emphasis-custom-with-format
+   (let ((regexp (concat "\\`"
+                        (format (regexp-quote format)
+                                "\\([^()]+\\)" "\\([^()]+\\)")
+                        "\\'"))
+        pattern)
+     (if (string-match regexp (setq pattern (car value)))
+        (list (cons (match-string 1 pattern) (match-string 2 pattern))
+              (= (nth 2 value) 2)
+              (nth 3 value))
+       value))))
+
+(defgroup emchat-emphasis nil
+  "Emphasise text in the log buffer."
+  :prefix "emchat-emphasis-"
+  :group 'emchat-log)
+
+(defcustom emchat-emphasis-enabled-flag nil
+  "*When non-nil, emphasise text in the log buffer."
+  :type 'boolean
+  :group 'emchat-emphasis)
+
+(defcustom emchat-emphasis-alist
+  (let ((types
+        '(("\\*" "\\*" bold)
+          ("_" "_" underline)
+          ("/" "/" italic)
+          ("_/" "/_" underline-italic)
+          ("_\\*" "\\*_" underline-bold)
+          ("\\*/" "/\\*" bold-italic)
+          ("_\\*/" "/\\*_" underline-bold-italic))))
+    (nconc
+     (emchat-emphasis-custom-with-format
+      (mapcar (lambda (spec)
+               (list (format format (car spec) (cadr spec))
+                     (or (nth 3 spec) 2)
+                     (or (nth 4 spec) 3)
+                     (intern (format "emchat-emphasis-%s" (nth 2 spec)))))
+             types))
+     '(("\\(\\s-\\|^\\)\\(_\\(\\(\\w\\|_[^_]\\)+\\)_\\)\\(\\s-\\|[?!.,;]\\)"
+       2 3 emchat-emphasis-underline))))
+  "*Alist that says how to fontify certain phrases.
+Each item looks like this:
+
+  (\"_\\\\(\\\\w+\\\\)_\" 0 1 'underline)
+
+The first element is a regular expression to be matched.  The second
+is a number that says what regular expression grouping used to find
+the entire emphasised word.  The third is a number that says what
+regexp grouping should be displayed and highlighted.  The fourth
+is the face used for highlighting."
+  :type
+  '(repeat
+    (menu-choice
+     :format "%[Customizing Style%]\n%v"
+     :indent 2
+     (group :tag "Default"
+           :value ("" 0 0 default)
+           :value-create
+           (lambda (widget)
+             (let ((value (widget-get
+                           (cadr (widget-get (widget-get widget :parent)
+                                             :args))
+                           :value)))
+               (if (not (eq (nth 2 value) 'default))
+                   (widget-put
+                    widget
+                    :value
+                    (emchat-emphasis-custom-value-to-external value))))
+             (widget-group-value-create widget))
+           regexp
+           (integer :format "Match group: %v")
+           (integer :format "Emphasise group: %v")
+           face)
+     (group :tag "Simple"
+           :value (("_" . "_") nil default)
+           (cons :format "%v"
+                 (regexp :format "Start regexp: %v")
+                 (regexp :format "End regexp: %v"))
+           (boolean :format "Show start and end patterns: %[%v%]\n"
+                    :on " On " :off " Off ")
+           face)))
+  :get #'(lambda (symbol)
+          (mapcar #'emchat-emphasis-custom-value-to-internal
+                  (default-value symbol)))
+  :set #'(lambda (symbol value)
+          (set-default symbol (mapcar #'emchat-emphasis-custom-value-to-external
+                                      value)))
+  :group 'emchat-emphasis)
+
+(defcustom emchat-emphasise-whitespace-regexp "^[ \t]+\\|[ \t]*\n"
+  "A regexp to describe whitespace which should not be emphasised.
+Typical values are \"^[ \\t]+\\\\|[ \\t]*\\n\" and \"[ \\t]+\\\\|[ \\t]*\\n\".
+The former avoids underlining of leading and trailing whitespace,
+and the latter avoids underlining any whitespace at all."
+  :group 'emchat-emphasis
+  :type 'regexp)
+
+(defcustom emchat-emphasis-url-regexp
+  (concat "\\(https?://\\|s?ftp://\\|gopher://\\|telnet://"
+         "\\|wais://\\|file:/\\|s?news:\\)"
+         "[^]\t\n \"'()<>[^`{}]*[^]\t\n \"'()<>[^`{}.,;]+")
+  "A regular expression matching URLs."
+  :type 'regexp
+  :group 'emchat-emphasis)
+
+(defcustom emchat-emphasis-email-regexp
+  "[-a-zA-Z0-9._]+@\\([-a-zA-z0-9_]+\\.\\)+[a-zA-Z0-9]+"
+  "A regular expression matching email addresses."
+  :type 'regexp
+  :group 'emchat-emphasis)
+
+(defcustom emchat-emphasis-man-regexp "\\b\\w+([1-9n])"
+  "A regular expression matching unix manual pages.
+
+For example, `xemacs\(1\)'."
+  :type 'regexp
+  :group 'emchat-emphasis)
+
+(make-face 'emchat-emphasis-bold)
+(set-face-parent 'emchat-emphasis-bold 'bold)
+
+(defcustom emchat-emphasis-bold 'emchat-emphasis-bold
+  "Face used for displaying strong emphasised text (*word*)."
+  :type 'face
+  :group 'emchat-emphasis)
+
+(make-face 'emchat-emphasis-italic)
+(set-face-parent 'emchat-emphasis-italic 'italic)
+
+(defcustom emchat-emphasis-italic 'emchat-emphasis-italic
+  "Face used for displaying italic emphasised text (/word/)."
+  :type 'face
+  :group 'emchat-emphasis)
+
+(make-face 'emchat-emphasis-underline)
+(set-face-parent 'emchat-emphasis-underline 'underline)
+
+(defcustom emchat-emphasis-underline 'emchat-emphasis-underline
+  "Face used for displaying underlined emphasised text (_word_)."
+  :type 'face
+  :group 'emchat-emphasis)
+
+(make-face 'emchat-emphasis-underline-bold)
+(set-face-parent 'emchat-emphasis-underline-bold 'bold)
+(set-face-property 'emchat-emphasis-underline-bold 'underline t)
+
+(defcustom emchat-emphasis-underline-bold 'emchat-emphasis-underline-bold
+  "Face used for displaying underlined bold emphasised text (_*word*_)."
+  :type 'face
+  :group 'emchat-emphasis)
+
+(make-face 'emchat-emphasis-underline-italic)
+(set-face-parent 'emchat-emphasis-underline-italic 'italic)
+(set-face-property 'emchat-emphasis-underline-italic 'underline t)
+
+(defcustom emchat-emphasis-underline-italic 'emchat-emphasis-underline-italic
+  "Face used for displaying underlined italic emphasised text (_/word/_)."
+  :type 'face
+  :group 'emchat-emphasis)
+
+(make-face 'emchat-emphasis-bold-italic)
+(set-face-parent 'emchat-emphasis-bold-italic 'bold-italic)
+
+(defcustom emchat-emphasis-bold-italic 'emchat-emphasis-bold-italic
+  "Face used for displaying bold italic emphasised text (/*word*/)."
+  :type 'face
+  :group 'emchat-emphasis)
+
+(make-face 'emchat-emphasis-underline-bold-italic)
+(set-face-parent 'emchat-emphasis-underline-bold-italic 'bold-italic)
+(set-face-property 'emchat-emphasis-underline-bold-italic 'underline t)
+
+(defcustom emchat-emphasis-underline-bold-italic
+  'emchat-emphasis-underline-bold-italic
+  "Face used for displaying underlined bold italic emphasised text.
+Example: (_/*word*/_)."
+  :type 'face
+  :group 'emchat-emphasis)
+
+(make-face 'emchat-emphasis-strikethru)
+(set-face-property 'emchat-emphasis-strikethru 'strikethru t)
+
+(defcustom emchat-emphasis-strikethru 'emchat-emphasis-strikethru
+  "Face used for displaying strike-through text (-word-)."
+  :type 'face
+  :group 'emchat-emphasis)
+
+(defface emchat-emphasis-highlight-words
+  '((t (:background "black" :foreground "yellow")))
+  "Face used for displaying highlighted words."
+  :group 'emchat-emphasis)
+
+;;; Internal variables
+
+(defun emchat-emphasis-treat-message (b e)
+  "Emphasise text in region B E according to `emchat-emphasis-alist'."
+  (let ((alist emchat-emphasis-alist)
+       regexp elem beg invisible visible face)
+    (save-excursion
+      (save-restriction
+       (narrow-to-region b e)
+       (goto-char (point-min))
+       (setq beg (point))
+       (while (setq elem (pop alist))
+         (goto-char beg)
+         (setq regexp (car elem)
+               invisible (nth 1 elem)
+               visible (nth 2 elem)
+               face (nth 3 elem))
+         (while (re-search-forward regexp nil t)
+           (when (and (match-beginning visible) (match-beginning invisible))
+             (put-text-property
+              (match-beginning invisible) (match-end invisible) 'invisible t)
+             (remove-text-properties
+              (match-beginning visible) (match-end visible) '(invisible t))
+             (put-text-property
+              (match-beginning visible) (match-end visible) 'face face)
+             (goto-char (match-end invisible)))))))))
+
+(defun emchat-emphasis-visit-hyperlink-at-point ()
+  "Follow the hyperlink at point in the EMchat log buffer.
+
+This can either be a URL, in which case `browse-url' is called with
+the string of the extent as an arg.  Or it can be an email address, in
+which case `compose-mail' is called.  Or it can be a Unix manual page,
+where `manual-entry' is called."
+  (interactive)
+  (when (extentp (extent-at (point)))
+    (let ((str (extent-string (extent-at (point)))))
+      (cond ((string-match emchat-emphasis-url-regexp str)
+            (browse-url str))
+           ((string-match emchat-emphasis-email-regexp str)
+            (compose-mail str))
+           ((string-match emchat-emphasis-man-regexp str)
+            (if (fboundp 'manual-entry)
+                (manual-entry str)
+              (error 'unimplemented "Unix manual pages")))
+           (t
+            (error 'invalid-operation))))))
+
+(defun emchat-emphasis-visit-hyperlink-at-mouse (event)
+  "Follow the hyperlink at EVENT in the EMchat log buffer.
+
+This can either be a URL, in which case `browse-url' is called with
+the string of the extent as an arg.  Or it can be an email address, in
+which case `compose-mail' is called.  Or it can be a Unix manual page,
+where `manual-entry' is called."
+  (interactive "e")
+  (when (extentp (extent-at-event event))
+    (let ((str (extent-string (extent-at-event event))))
+      (cond ((string-match emchat-emphasis-url-regexp str)
+            (browse-url str))
+           ((string-match emchat-emphasis-email-regexp str)
+            (compose-mail str))
+           ((string-match emchat-emphasis-man-regexp str)
+            (if (fboundp 'manual-entry)
+                (manual-entry str)
+              (error 'unimplemented "Unix manual pages")))
+           (t
+            (error 'invalid-operation))))))
+
+(defun emchat-emphasis-hyperlink-message (b e)
+  "Add hyperlinks to the message in region B E.
+
+In other words, URLs, email addresses, and unix manual page names will
+be \"clickable\"."
+  (save-excursion
+    (save-restriction
+      (narrow-to-region b e)
+      (goto-char (point-min))
+      (while (re-search-forward emchat-emphasis-url-regexp nil t)
+       (let ((extent (make-extent (match-beginning 0) (match-end 0)))
+             (echo "Mouse button2 -- Follow this link."))
+         (set-extent-property extent 'face 'widget-button-face)
+         (set-extent-property extent 'mouse-face 'highlight)
+         (set-extent-property extent 'keymap emchat-hyperlink-map)
+         (set-extent-property extent 'help-echo echo)
+         (set-extent-property extent 'balloon-help echo)
+         (set-extent-property extent 'duplicable t)))
+      (while (re-search-forward emchat-emphasis-email-regexp nil t)
+       (let ((extent (make-extent (match-beginning 0) (match-end 0)))
+             (echo "Mouse button2 -- Compose mail."))
+         (set-extent-property extent 'face 'emchat-emphasis-highlight-words)
+         (set-extent-property extent 'mouse-face 'highlight)
+         (set-extent-property extent 'keymap emchat-hyperlink-map)
+         (set-extent-property extent 'help-echo echo)
+         (set-extent-property extent 'balloon-help echo)
+         (set-extent-property extent 'duplicable t)))
+      (while (re-search-forward emchat-emphasis-man-regexp nil t)
+       (let ((extent (make-extent (match-beginning 0) (match-end 0)))
+             (echo "Mouse button2 -- Read this manual."))
+         (set-extent-property extent 'face 'man-xref)
+         (set-extent-property extent 'mouse-face 'highlight)
+         (set-extent-property extent 'keymap emchat-hyperlink-map)
+         (set-extent-property extent 'help-echo echo)
+         (set-extent-property extent 'balloon-help echo)
+         (set-extent-property extent 'duplicable t))))))
+       
+(provide 'emchat-emphasis)
+;;; emchat-emphasis.el ends here
+
diff --git a/emchat-history.el b/emchat-history.el
new file mode 100644 (file)
index 0000000..c9c32d1
--- /dev/null
@@ -0,0 +1,176 @@
+;;; emchat-history.el --- Mode for viewing history in EMchat and its interface.
+
+;; Copyright (C) 2005 - 2007 Steve Youngs, Alexey Mikhailov
+
+;; Author:        Alexey Mikhailov <karma@sxemacs.org>
+;; Maintainer:    Alexey Mikhailov <karma@sxemacs.org>
+;; Created:       2005-04-19
+;; Homepage:      http://www.emchat.org/
+;; Keywords:      comm ICQ history
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;;
+;; Provides mode for viewing person history and interface for EMchat.
+;; To start using it, add this to your ~/.sxemacs/init.el...
+;;
+;;    (setq emchat-history-enabled-flag t)
+
+(eval-and-compile
+  (require 'outline)
+  (require 'emchat)
+  (require 'emchat-log)
+  (require 'font-lock))
+
+(defvar emchat-history-old-window-config nil)
+
+(defun emchat-history (&optional alias)
+  "Show history log for ALIAS person."
+  (interactive)
+  (let* ((alias (or alias
+                   (emchat-completing-read "Show history for: "
+                                         emchat-all-aliases nil t)))
+        (histf (emchat-world-getf alias 'history)))
+    (when histf
+      (find-file histf)
+      (emchat-history-mode))))
+
+(defun emchat-history-around ()
+  "Show history around."
+  (interactive)
+  (emchat-history (emchat-alias-around)))
+
+
+(defun emchat-history-here-other-window (&optional count)
+  "Show history around in other window."
+  (interactive)
+  (setq emchat-history-old-window-config (current-window-configuration))
+  (unless count (setq count 1))
+  (let ((alias (emchat-alias-here)))
+    (other-window count)
+    (emchat-history alias)))
+      
+(defvar emchat-history-outline-regexp "\\(^\\s-?[0-9]*[ ][A-Za-z]*[ ][A-Z]..\:..\\)"
+  "Regexp for history header.
+See `outline-regexp'.")
+
+(defvar emchat-history-event-regexp 
+  (concat "\\(^\\s-?[0-9]*[ ][A-Za-z]*[ ][A-Z]..\:..\\)"
+         ".\\(\\[[A-Za-z0-9].*\\]\\).\\([\*><]*\\).\\(.*\\)")
+  "Regexp for history event.
+
+First paren set matches date header, second -- person nickname, third
+-- event type, fourth -- all other stuff.")
+
+(defun emchat-history-mode ()
+  "Major mode for viewing history in emchat.
+Commands: \\{emchat-history-mode-map}
+
+Turning on `emchat-history-mode' runs the hook `emchat-history-mode-hook'."
+  (interactive)
+  (kill-all-local-variables)
+  (use-local-map emchat-history-mode-map)
+  (setq mode-name "emchat-history")
+  (setq major-mode 'emchat-history-mode)
+  (easy-menu-add emchat-history-menu)
+  (font-lock-mode t)
+  (toggle-read-only t)
+  (outline-minor-mode t)
+  (set (make-local-variable 'outline-regexp)
+       emchat-history-outline-regexp)
+  (goto-char (point-max))
+  (forward-line -1)
+  (run-hooks 'emchat-history-mode-hook))
+
+(defun emchat-history-bury-buffer (&optional kill)
+  "Bury buffer in `emchat-history' mode.
+
+With optional prefix arg, KILL, kill the buffer instead of burying
+it."
+  (interactive "P")
+  ;; safeguard against calling this when the current buffer isn't in
+  ;; emchat-history-mode
+  (when (eq major-mode 'emchat-history-mode)
+    (if current-prefix-arg
+       (kill-buffer nil)
+      (bury-buffer nil)))
+  ;; Possibly restore the old window config
+  (when emchat-history-old-window-config
+    (set-window-configuration emchat-history-old-window-config)
+    (setq emchat-history-old-window-config nil)))
+
+(defun emchat-history-save (&optional alias)
+  "Save all the open history files."
+  (interactive)
+  (if alias
+      (with-current-buffer (find-buffer-visiting
+                           (emchat-world-getf alias 'history))
+       (save-buffer))
+    (mapcar
+     #'(lambda (a)
+        (let ((buf (find-buffer-visiting
+                    (emchat-world-getf a 'history))))
+          (and buf
+               (with-current-buffer buf
+                 (save-buffer)))))
+     emchat-all-aliases)))
+
+(defalias 'emchat-history-next 'outline-forward-same-level)
+(defalias 'emchat-history-prev 'outline-backward-same-level)
+
+(defface emchat-history-timestamp-face
+  '((((background light))
+     (:foreground "red4" :bold t)))
+  "Face used to highlight timestamps in `emchat-history' mode."
+  :group 'emchat-log)
+
+(defface emchat-history-event-type-face
+  '((((background light))
+     (:foreground "magenta3" :bold t)))
+  "Face used to highlight event types in `emchat-history' mode."
+  :group 'emchat-log)
+
+(defface emchat-history-nick-face
+  '((((background light))
+     (:foreground "green4" :bold t)))
+  "Face used to highlight nicks in `emchat-history' mode."
+  :group 'emchat-log)
+
+(defconst emchat-history-font-lock-keywords
+  (list
+   (cons emchat-history-event-regexp '(1 'emchat-history-timestamp-face))
+   (cons emchat-history-event-regexp '(2 'emchat-history-nick-face))
+   (cons emchat-history-event-regexp '(3 'emchat-history-event-type-face)))
+  "Highlighting rules for `emchat-history' buffers.")
+
+(provide 'emchat-history)
+
+;;; emchat-history.el ends here
diff --git a/emchat-log.el b/emchat-log.el
new file mode 100644 (file)
index 0000000..dc1174e
--- /dev/null
@@ -0,0 +1,641 @@
+;;; emchat-log.el --- Logging code for EMchat.
+
+;; Copyright (C) 2002 - 2007 Steve Youngs
+
+;; Author:        Steve Youngs <steve@emchat.org>
+;; Maintainer:    Steve Youngs <steve@emchat.org>
+;; Created:       2002-10-01
+;; Homepage:      http://www.emchat.org/
+;; Keywords:      comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;;
+;; Logs incoming and outgoing events in EMchat.
+
+(eval-and-compile
+  (defvar emchat-directory nil)
+  (require 'emchat-emphasis)
+  (require 'emchat-curl)
+  (require 'emchat-menu)
+  (require 'emchat-track)
+  (require 'outline))
+
+(eval-when-compile
+  (defvar emchat-history-enabled-flag nil)
+  (defvar emchat-history-directory)
+  (autoload #'smiley-region "smiley" nil t))
+
+(defgroup emchat-log nil
+  "Message logging preferences."
+  :group 'emchat)
+
+(defcustom emchat-log-fill-column 0
+  "Fill column for `emchat-log-buffer'.
+
+If this is set to 0 \(zero\), the default, the fill-column in the log
+buffer is left alone.  In other words, default value for fill-column." 
+  :type 'integer
+  :group 'emchat-log)
+
+(defcustom emchat-log-filename (expand-file-name "log" emchat-directory)
+  "*Pathname and filename for storing emchat log.
+Automatically created if the directory is non-existent."
+  :type 'file
+  :group 'emchat-log)
+
+(defcustom emchat-log-buffer-position-flag 'tail
+  "*Non-nil means automatically updating buffer position.
+Nil means no automatic update, 'tail means keeping the bottom of the buffer 
+visible, other non-nil means keeping the top of the buffer visible."
+  :group 'emchat-log
+  :type '(choice (item t) (item tail) (item nil)))  
+
+(defcustom emchat-log-info-flag 'tail
+  "*Non-nil means log misc info.
+These include any info from ICQ server other than buddy messages, status
+change notice, and query results.
+Nil means no log, 'tail means putting new log at the end of the log
+buffer, other non-nil means putting new log at the beginning."
+  :group 'emchat-log
+  :type '(choice (item t) (item tail) (item nil)))
+
+(defcustom emchat-log-buddy-status-flag 'tail
+  "*Non-nil means log buddy status change notice.
+Nil means no log, 'tail means putting new log at the end of the log
+buffer, other non-nil means putting new log at the beginning."
+  :group 'emchat-log
+  :type '(choice (item t) (item tail) (item nil)))
+
+(defcustom emchat-log-buddy-message-flag 'tail
+  "*Non-nil means log buddy messages from ICQ server.
+Nil means no log, 'tail means putting new log at the end of the log
+buffer, other non-nil means putting new log at the beginning."
+  :group 'emchat-log
+  :type '(choice (item t) (item tail) (item nil)))
+
+(defcustom emchat-log-outgoing-flag 'tail
+  "*Non-nil means log outgoing messages to ICQ server.
+Nil means no log, 'tail means putting new log at the end of the log
+buffer, other non-nil means putting new log at the beginning."
+  :group 'emchat-log
+  :type '(choice (item t) (item tail) (item nil)))
+
+(defcustom emchat-log-error-flag 'tail
+  "*Non-nil means log critical error messages.
+Nil means no log, 'tail means putting new log at the end of the log
+buffer, other non-nil means putting new log at the beginning."
+  :group 'emchat-log
+  :type '(choice (item t) (item tail) (item nil)))
+
+(defcustom emchat-log-debug-flag nil
+  "*Non-nil means log verbose debugging messages.
+Nil means no log, 'tail means putting new log at the end of the log
+buffer, other non-nil means putting new log at the beginning."
+  :group 'emchat-log
+  :type '(choice (item t) (item tail) (item nil)))
+
+(defcustom emchat-log-system-flag 'tail
+  "*Non-nil means log system messages.
+These include network status, login status, and others.
+Nil means no log, 'tail means putting new log at the end of the log
+buffer, other non-nil means putting new log at the beginning."
+  :group 'emchat-log
+  :type '(choice (item t) (item tail) (item nil)))
+
+(defcustom emchat-log-info-mark nil
+  "*Non-nil means mark unread.
+These include any info from ICQ server other than buddy messages, 
+status change notice, and query results.
+Nil means mark read."
+  :group 'emchat-log
+  :type 'boolean)
+
+(defcustom emchat-log-buddy-status-mark nil
+  "*Non-nil means mark buddy status change notice unread.
+Nil means mark read."
+  :type 'boolean
+  :group 'emchat-log)
+
+(defcustom emchat-log-buddy-message-mark t
+  "*Non-nil means mark buddy messages unread.
+Nil means mark read."
+  :type 'boolean
+  :group 'emchat-log)
+
+(defcustom emchat-log-outgoing-mark nil
+  "*Non-nil means mark outgoing messages unread.
+Nil means mark read."
+  :group 'emchat-log
+  :type 'boolean)
+
+(defcustom emchat-log-error-mark t
+  "*Non-nil means mark critical error messages unread.
+Nil means mark read."
+  :group 'emchat-log
+  :type 'boolean)
+
+(defcustom emchat-log-debug-mark t
+  "*Non-nil means mark verbose debugging messages unread.
+Nil means mark read."
+  :group 'emchat-log
+  :type 'boolean)
+
+(defcustom emchat-log-system-mark nil
+  "*Non-nil means mark system messages unread.
+Nil means mark read."
+  :group 'emchat-log
+  :type 'boolean)
+
+(defcustom emchat-save-log-on-exit-p t
+  "*Non-nil means the log file will be automatically saved when exiting."
+  :group 'emchat-log
+  :type 'boolean
+  :tag "Save log on exit")
+
+(defcustom emchat-smiley nil
+  "*Non-nil means smileys are enabled."
+  :group 'emchat-interface
+  :type '(choice (item t) (item nil)))
+
+;;; Internal variables
+
+(defvar emchat-log-buffer nil
+  "Buffer for log.")
+
+(defvar emchat-log-outline-regexp "^...:.. "
+  "Regexp for log header.
+See `outline-regexp'.")
+
+(defvar emchat-log-mode-syntax-table
+  (let ((table (copy-syntax-table text-mode-syntax-table)))
+    (modify-syntax-entry ?~  "w " table)
+    (modify-syntax-entry ?`  "w " table)
+    (modify-syntax-entry ?!  "w " table)
+    (modify-syntax-entry ?@  "w " table)
+    (modify-syntax-entry ?#  "w " table)
+    (modify-syntax-entry ?$  "w " table)
+    (modify-syntax-entry ?%  "w " table)
+    (modify-syntax-entry ?^  "w " table)
+    (modify-syntax-entry ?&  "w " table)
+    (modify-syntax-entry ?(  "w " table)
+    (modify-syntax-entry ?)  "w " table)
+    (modify-syntax-entry ?-  "w " table)
+    (modify-syntax-entry ?+  "w " table)
+    (modify-syntax-entry ?=  "w " table)
+    (modify-syntax-entry ?{  "w " table)
+    (modify-syntax-entry ?[  "w " table)
+    (modify-syntax-entry ?}  "w " table)
+    (modify-syntax-entry ?]  "w " table)
+    (modify-syntax-entry ?\\ "w " table)
+    (modify-syntax-entry ?|  "w " table)
+    (modify-syntax-entry ?:  "w " table)
+    (modify-syntax-entry ?\; "w " table)
+    (modify-syntax-entry ?\" "w " table)
+    (modify-syntax-entry ?'  "w " table)
+    (modify-syntax-entry ?<  "w " table)
+    (modify-syntax-entry ?,  "w " table)
+    (modify-syntax-entry ?>  "w " table)
+    (modify-syntax-entry ?.  "w " table)
+    (modify-syntax-entry ?\? "w " table)
+    table)
+  "Syntax table used while in `emchat-log-mode'.")
+
+(defun emchat-log-update-modeline ()
+  (let ((invisible emchat-user-meta-invisible))
+    (if invisible
+       (setq modeline-buffer-identification
+             (list (cons modeline-buffer-id-left-extent
+                         (cons 10 (list "[" 'emchat-user-alias "]: ")))
+                   (cons modeline-buffer-id-right-extent 
+                         (cons 1 (list "<" 
+                                       'emchat-user-status
+                                       'emchat-user-meta-invisibility-indicator
+                                       ">")))))
+      (setq modeline-buffer-identification
+           (list (cons modeline-buffer-id-left-extent
+                       (cons 10 (list "[" 'emchat-user-alias "]: ")))
+                 (cons modeline-buffer-id-right-extent 
+                       (cons 1 (list "<" 
+                                     'emchat-user-status
+                                     ">"))))))))
+
+(defun emchat-log-mode ()
+  "Major mode for logging messages in emchat.
+Commands: \\{emchat-log-mode-map}
+
+Turning on `emchat-log-mode' runs the hook `emchat-log-mode-hook'."
+  (interactive)
+  (kill-all-local-variables)
+  (use-local-map emchat-log-mode-map)
+  (setq mode-name "emchat-log")
+  (setq major-mode 'emchat-log-mode)
+  ;; put easy-menu-add after set mode-name
+  (easy-menu-add emchat-main-easymenu)
+  (easy-menu-add emchat-buddy-menu)
+  (easy-menu-add emchat-log-menu)
+  (unless (zerop emchat-log-fill-column)
+    (setq fill-column emchat-log-fill-column))
+  ;; No menubar from outline mode.
+  (let ((features (remove 'menubar features)))
+    (outline-minor-mode))
+  (set (make-local-variable 'outline-regexp)
+       emchat-log-outline-regexp)
+  (emchat-log-update-modeline)
+  ;; Use our syntax-table
+  (set-syntax-table emchat-log-mode-syntax-table)
+  (run-hooks 'emchat-log-mode-hook))
+
+(defvar emchat-log-logo (expand-file-name "logo.png" emchat-glyph-dir)
+  "The logo used at the top of a new log buffer.")
+
+(defvar emchat-log-header (expand-file-name "log-header.xbm"
+                                           emchat-glyph-dir)
+  "The intro at the top of a new log buffer.")
+
+;;;###autoload
+(defun emchat-log-show-buffer (&optional new no-select)
+  "Switch to `emchat-log-buffer'.
+Create buffer with log file if buffer does not exists already.
+Non-nil NEW means rotate and create a new log file.
+Non-nil NO-SELECT means don't select log window.
+See `emchat-log-filename'."
+  (interactive)
+  (when new
+    ;; save and close current log first if any
+    (setq emchat-log-buffer
+          (find-buffer-visiting emchat-log-filename))
+
+    (if emchat-log-buffer
+        (with-current-buffer emchat-log-buffer
+          (save-buffer)
+          (kill-buffer nil)))
+
+    ;; rename old log in disk
+    (if (file-exists-p emchat-log-filename)
+        (rename-file
+         emchat-log-filename
+         (concat emchat-log-filename
+                 ;; in case you do something stupid with it
+                 (format-time-string "-%Y-%b%d-%H%M-%S")))))
+
+  (unless (buffer-live-p emchat-log-buffer)
+    (setq emchat-log-buffer (find-file-noselect emchat-log-filename))
+    (with-current-buffer emchat-log-buffer
+      (emchat-log-mode)
+      (when (zerop (buffer-size))
+       (if (and  (device-on-window-system-p)
+                 (featurep '(and png xbm)))
+           (progn
+             (insert "\n")
+             (let ((ext (make-extent (point) (point))))
+               (set-extent-begin-glyph
+                ext
+                (make-glyph (list (vector 'png ':file emchat-log-logo))))
+               (set-extent-end-glyph
+                ext
+                (make-glyph (list (vector 'xbm ':file emchat-log-header))))
+               (insert "\n\n")))
+          (insert "===========================================\n"
+                 "Welcome to EMchat - The (S)XEmacs IM Client\n\n"
+                 "If you like this software, please consider\n"
+                 "         \'M-x emchat-donation RET\'\n"
+                 "===========================================\n\n")))))
+  (unless no-select
+    (switch-to-buffer emchat-log-buffer)))
+
+(defun emchat-log-new-file ()
+  "Rotate and create a new log file."
+  (interactive)
+  (emchat-log-show-buffer 'new))
+
+(defconst emchat-log-entry-re "^[SMTWRFA][0-9][0-9]:[0-9][0-9]"
+  "Regular expression matching the beginning of a log entry.")
+
+(defun emchat-log-update-history (id message weekday)
+  "Updates the history for ID, with MESSAGE.
+
+WEEKDAY is an array of 7 characters indicating a day of the week for
+the timestamp."
+  (when (and (member id emchat-visible-contacts)
+            (not (member id emchat-invisible-contacts))
+            (not (search "***|" message)))
+    (let ((hfile (emchat-world-getf id 'history)))
+      (save-excursion
+       (with-current-buffer (find-file-noselect hfile 'nowarn)
+         (when buffer-read-only
+           (toggle-read-only))
+         (goto-char (point-max))
+         (insert
+          (format-time-string "%e %b ")
+          (aref weekday (string-to-number (format-time-string "%w")))
+          (format-time-string "%R ")
+          (format "[%s] %s" id message))
+         (let ((beg (point-at-bol)))
+           (fill-region beg (point-max))))))))
+
+(defun emchat-log-update-tracker (id message)
+  "Update the EMchat track modeline indicator.
+
+ID is the entity that sent MESSAGE."
+  (unless (get 'emchat-track 'initialized)
+    (emchat-track-init))
+  (and (not (get-buffer-window emchat-log-buffer))
+       (ecase emchat-track-events-type 
+        (all (emchat-track-add-nick id))
+        (incoming
+         (and (not (search ">>>" message)) ; XXX
+              (not (search "***|" message)) ; XXX
+              (emchat-track-add-nick id)))
+        (msg
+         (and (not (equal id "!debug")) ; XXX
+              (not (equal id "!error")) ; XXX
+              (not (equal id "!system")) ; XXX
+              (not (search ">>>" message)) ; XXX
+              (not (search "***|" message)) ; XXX
+              (emchat-track-add-nick id))))))
+
+(defun emchat-log-update-balloon (id)
+  "Update the balloon-help extent property for ID."
+  (save-excursion
+    (search-backward id)
+    (let* ((exp (extent-at (point)))
+          (bhelp 
+           (format 
+            "%s (%s)\n Status: %s\n Groups: %s\nHistory: %s\n\n\n"
+            id
+            (emchat-alias-uin id)
+            (or (emchat-world-getf id 'status)
+                "offline")
+            (or (emchat-world-getf id 'group)
+                "none")
+            (or (emchat-world-getf id 'history)
+                "none")))
+          (face (emchat-status-face (emchat-world-getf id 'status))))
+      (when (extentp exp)
+       (set-extent-property exp 'face face)
+       (set-extent-property exp 'balloon-help bhelp)))))
+
+(defun emchat-log (id message option mark-unread)
+  "Log message under ID.
+Put MESSAGE at the end of log buffer if OPTION is non-nil.
+Mark MESSAGE unread if MARK-UNREAD is non-nil"
+  (if (and option (buffer-live-p emchat-log-buffer))
+      (with-current-buffer emchat-log-buffer
+        (save-excursion
+          (let ((start-point (if (eq option 'tail)
+                                 (point-max) (point-min)))
+                (weekday ["S" "M" "T" "W" "R" "F" "A"])
+                ;; to fill messages correctly
+                (paragraph-start ""))
+            (goto-char start-point)
+            (insert
+             (aref weekday (string-to-number (format-time-string "%w")))
+             (format-time-string "%R ")
+             ;; use concat instead of format for extent
+             (concat "[" id "] " message "\n"))
+            (fill-region start-point (point))
+            (when emchat-history-enabled-flag
+             (emchat-log-update-history id message weekday))
+            (when emchat-track-enable
+             (emchat-log-update-tracker id message))
+            (when (member id emchat-all-aliases)
+             (emchat-log-update-balloon id))
+           (when emchat-smiley
+             (smiley-region start-point (point)))
+           (when emchat-emphasis-enabled-flag
+             (emchat-emphasis-treat-message start-point (point)))
+           (emchat-emphasis-hyperlink-message start-point (point))
+            (goto-char start-point)
+           (if mark-unread
+               (emchat-log-mark-unread)
+             (emchat-log-mark-read))))
+       (if emchat-log-buffer-position-flag
+           (if (eq emchat-log-buffer-position-flag 'tail)
+               (progn
+                 (goto-char (point-max))
+                 (re-search-backward emchat-log-entry-re))
+             (progn 
+               (goto-char (point-min))
+               (re-search-forward emchat-log-entry-re)))))))
+
+(defun emchat-log-info (&rest messages)
+  "See `emchat-log-info-flag'.
+MESSAGES is an argument list for `format' to be inserted."
+  (emchat-log "!info" (apply 'format messages) emchat-log-info-flag emchat-log-info-mark))
+
+(defun emchat-log-buddy-status (alias &rest messages)
+  "See `emchat-log-buddy-status-flag'.
+ALIAS is an id to be logged under.
+MESSAGES is an argument list for `format' to be inserted."
+  (emchat-log alias 
+           (apply 'format messages) 
+           emchat-log-buddy-status-flag emchat-log-buddy-status-mark))
+
+(defun emchat-log-buddy-message (alias fmt &rest fmt-messages)
+  "See `emchat-log-buddy-message-flag'.
+ALIAS is an id to be logged under.
+FMT is message format, passed directly to `format'.
+FMT-MESSAGES are arguments for `format'."
+  (emchat-log alias 
+           (apply 'format fmt fmt-messages) 
+           emchat-log-buddy-message-flag emchat-log-buddy-message-mark))
+
+(defun emchat-log-buddy-url (alias message url)
+  "See `emchat-log-buddy-message-flag'.
+ALIAS is an id MESSAGE to be logged under.
+URL will be highlighted."
+  ;; idea from Erik Arneson <erik@starseed.com>
+  (set-extent-properties
+   (make-extent 0 (length url) url)
+   `(highlight t duplicable t
+              keymap ,emchat-hyperlink-map
+              balloon-help "Mouse button2 -- Follow this link."
+              face ,widget-button-face))
+  (emchat-log alias (concat message "\nURL: " url)
+            emchat-log-buddy-message-flag emchat-log-buddy-message-mark))
+
+(defun emchat-log-outgoing (alias &rest messages)
+  "See `emchat-log-outgoing-flag'.
+ALIAS is an id to be logged under.
+MESSAGES is an argument list for `format' to be inserted."
+  (emchat-log alias 
+           (apply 'format messages) emchat-log-outgoing-flag emchat-log-outgoing-mark))
+
+(defun emchat-log-error (&rest messages)
+  "See `emchat-log-error-flag'.
+MESSAGES is an argument list for `format' to be inserted."
+  (emchat-log "!error" 
+           (apply 'format messages) emchat-log-error-flag emchat-log-error-mark))
+
+(defun emchat-log-debug (&rest messages)
+  "See `emchat-log-debug-flag'.
+MESSAGES is an argument list for `format' to be inserted."
+  (emchat-log "!debug" 
+           (apply 'format messages) emchat-log-debug-flag emchat-log-debug-mark))
+
+(defun emchat-log-system (&rest messages)
+    "See `emchat-log-system-flag'.
+MESSAGES is an argument list for `format' to be inserted."
+  (emchat-log "!system" 
+           (apply 'format messages) emchat-log-system-flag emchat-log-system-mark)
+  (run-hooks 'emchat-system-message-hook))
+
+(defface emchat-face-log-unread
+  '((((background dark))
+     (:foreground "red"))
+    (((background light))
+     (:foreground "red4" :bold t)))
+  "Face for unread log messages."
+  :group 'emchat-log)
+
+(defface emchat-face-log-read
+  '((((background dark))
+     (:foreground "turquoise"))
+    (((background light))
+     (:foreground "steelblue")))
+  "Face for read log messages."
+  :group 'emchat-log)
+
+(defvar emchat-log-mark-alist
+  '((unread . emchat-face-log-unread)
+    (read . emchat-face-log-read))
+  "Alist of log message marks and their colors.")
+
+(defun emchat-log-mark (&optional mark)
+  "Mark log message around point using MARK.
+Possible MARK: 'read, 'unread, 'toggle.
+Nil MARK means 'read.
+See `emchat-face-log-unread' and `emchat-face-log-read'."
+  (save-excursion
+    ;; so that we can mark current line even at bol
+    (end-of-line)
+    (let ((len (length emchat-log-outline-regexp))
+          (p (search-backward-regexp emchat-log-outline-regexp nil t))
+          (face (cdr (assoc mark emchat-log-mark-alist))))
+      (if p (add-text-properties
+             p (+ len p -2)
+             (list 'face face 'start-open t))))))
+
+(defun emchat-log-mark-region (start end &optional mark)
+  "Mark all log messages in the region.
+MARK is any mark in `emchat-log-mark'."
+  (interactive "r")
+  (save-excursion
+    (goto-char start)
+    ;; Due to bad design of outline.el, we use condition-case to guard
+    ;; against error when advancing at the end of buffer.
+    (condition-case nil
+        (while (<= (point) end)
+          (emchat-log-mark mark)
+          (emchat-log-next 1))
+      (error nil))))
+
+(defun emchat-log-mark-unread (&optional mark-region)
+  "Mark log message around point as unread.
+Non-nil MARK-REGION or prefix argument means marks all log in the region."
+  (interactive "P")
+  (if mark-region
+      (emchat-log-mark-region (region-beginning) (region-end) 'unread)
+    (emchat-log-mark 'unread)))
+
+(defun emchat-log-mark-read (&optional mark-region)
+  "Mark log message around point as read.
+Non-nil MARK-REGION or prefix argument means marks all log in the region."
+  (interactive "P")
+  (if mark-region
+      (emchat-log-mark-region (region-beginning) (region-end) 'read)
+    (emchat-log-mark 'read))
+  (if (interactive-p)
+      (run-hooks 'emchat-read-message-hook)))
+
+(defun emchat-log-around ()
+  "Return the log message around.
+If called interactively, display and push log into `kill-ring'."
+  (interactive)
+  (let* ((log-start (save-excursion
+                     (outline-back-to-heading)
+                     (search-forward "] " nil t)
+                     (point)))
+        (log-end (or (save-excursion
+                       (condition-case nil
+                           (outline-get-next-sibling)
+                         (error nil)))
+                     (point-max)))
+        (log (buffer-substring log-start log-end)))
+    (when (interactive-p)
+      (message log)
+      (kill-new log))
+    log))
+
+(defalias 'emchat-log-contract 'hide-subtree)
+(defalias 'emchat-log-expand 'show-subtree)
+(defalias 'emchat-log-previous 'outline-backward-same-level)
+(defalias 'emchat-log-next 'outline-forward-same-level)
+
+(defun emchat-log-next-unread ()
+  "Moves point to the next unread message.  
+Does nothing if there are no unread messages after point."
+  (interactive)
+  (let ((here (point)))
+    (goto-char 
+     (catch 'where
+       (progn 
+        (while (not (eq here (point-max))) ; mildly bogus target
+          (let ((next (next-single-property-change here 'face)))
+            (unless next
+              (throw 'where (point)))
+            (if (eq (get-text-property next 'face)
+                    (cdr (assoc 'unread emchat-log-mark-alist)))
+                (throw 'where next)
+              (setq here next)))))))))
+
+(defun emchat-log-previous-unread ()
+  "Moves point to the previous unread message.  
+Does nothing if there are no unread messages after point."
+  (interactive)
+  (let ((here (point)))
+    (goto-char 
+     (catch 'where
+       (progn 
+        (while (not (eq here (point-max))) ; mildly bogus target
+          (let ((prev (previous-single-property-change here 'face)))
+            (unless prev
+              (throw 'where (point)))
+            (if (eq (get-text-property prev 'face)
+                    (cdr (assoc 'unread emchat-log-mark-alist)))
+                (throw 'where prev)
+              (setq here prev)))))))))
+
+(provide 'emchat-log)
+
+;;; emchat-log.el ends here
+
diff --git a/emchat-menu.el b/emchat-menu.el
new file mode 100644 (file)
index 0000000..8a601d2
--- /dev/null
@@ -0,0 +1,246 @@
+;;; emchat-menu.el --- Menus and keymaps for EMchat.
+
+;; Copyright (C) 2002 - 2007 Steve Youngs
+
+;; Author:        Steve Youngs <steve@emchat.org>
+;; Maintainer:    Steve Youngs <steve@emchat.org>
+;; Created:       2002-10-01
+;; Homepage:      http://www.emchat.org/
+;; Keywords:      comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Code
+(eval-when-compile
+  (require 'emchat-utils))
+
+;; Global bindings.
+
+;; Define new prefix for EMchat
+(define-prefix-command 'emchat-prefix)
+
+;; Set EMchat global bindings
+(define-key emchat-prefix "Xi" #'emchat-login)
+(define-key emchat-prefix "w" #'emchat-show-window)
+(define-key emchat-prefix "f" #'world-find)
+
+;; Bindings common to both log and buddy buffer.
+(defvar emchat-main-map
+  (let ((map (make-keymap 'emchat-main-map)))
+    (suppress-keymap map)
+    (define-key map [X] nil)            ; BUG?
+    (define-key map [X i] #'emchat-login)
+    (define-key map [X o] #'emchat-logout)
+    (define-key map [X q] #'emchat-exit)
+    (define-key map [X s] #'emchat-change-status)
+    (define-key map [b] #'emchat-toggle-invisibility)
+    (define-key map [S] #'emchat-group-select-aliases)
+    (define-key map [s] #'emchat-group-select-aliases)
+    (define-key map [w] #'emchat-show-window)
+    (define-key map [H] #'emchat-history-save)
+    (define-key map [h] #'emchat-hide-window)
+    (define-key map [M] #'emchat-send-message)
+    (define-key map [m] #'emchat-send-message)
+    (define-key map [U] #'emchat-send-url)
+    (define-key map [u] #'emchat-send-url)
+    (define-key map [A] #'emchat-authorize)
+    (define-key map [a] #'emchat-authorize)
+    (define-key map [i] #'emchat-query-info)
+    (define-key map [I] #'emchat-query-info)
+    (define-key map [F] #'emchat-search)
+    (define-key map [f] #'world-find)
+    (define-key map [V] nil)
+    (define-key map [V c] #'emchat-buddy-view-connected)
+    (define-key map [V v] #'emchat-buddy-view-active)
+    (define-key map [V a] #'emchat-buddy-view-all)
+    map)
+  "Keyboard map common for `emchat-log-mode-map' and `emchat-buddy-mode-map'.")
+
+(defvar emchat-main-menu
+  '("EMchat"
+    ["Show Window" emchat-show-window t]
+    ["Hide Window" emchat-hide-window t]
+    ["Register New UIN" emchat-register-new-user t]
+    ["Change Password" emchat-change-password t]
+    ["Login" emchat-login t]
+    ["Logout" emchat-logout t]
+    ["Exit" emchat-exit t]
+    "---"
+    ["Select" emchat-group-select-aliases t]
+    ["Send Message" emchat-send-message t]
+    ["Send URL" emchat-send-url t]
+    ["Authorize" emchat-authorize t]
+    ["Change Status" emchat-change-status t]
+    ["Change Idle Timeout" emchat-change-idle-timeout t]
+    ["Search" emchat-search t]
+    ["Update Meta Info" emchat-update-meta-info t]
+    "---"
+    ["alias -> uin" emchat-alias-uin t]
+    ["uin -> alias" emchat-uin-alias t]
+    ["Redo Packet" emchat-redo-hex t]
+    ["Resend Contact List" emchat-send-contact-list t]
+    ["Buddy Buffer" emchat-buddy-show-buffer t]
+    ["Log Buffer" emchat-log-show-buffer t]
+    "---"
+    ["Email Author" emchat-email-author t]
+    ["Submit Bug Report" (emchat-report-bug emchat-blurb) t]
+    ["Make a Donation" emchat-donation t]
+    ["Customize" emchat-customize t])
+  "Menu for both `emchat-log-mode' and `emchat-buddy-mode'.")
+
+(easy-menu-define
+ emchat-main-easymenu nil "EMchat" emchat-main-menu)
+
+(defvar emchat-log-menu
+  '("EMchat-log"
+    ["Select Around" emchat-select-alias-around t]
+    ["Send Message Around" emchat-send-message-alias-around t]
+    ["Send URL Around" emchat-send-url-alias-around t]
+    ["Forward Message" emchat-forward-message-around t]
+    ["Oops!" emchat-oops t]
+    ["Authorize Around" emchat-authorize-alias-around t]
+    ["Query Around" emchat-query-info-alias-around t]
+    ["History Around" emchat-history-around t]
+    "---"
+    ["New Log File" emchat-log-new-file t]
+    ["Contract Log" emchat-log-contract t]
+    ["Expand Log" emchat-log-expand t]
+    ["Previous Log" emchat-log-previous t]
+    ["Next Log" emchat-log-next t]
+    "---"
+    ["Mark Read" emchat-log-mark-read t]
+    ["Mark Unread" emchat-log-mark-unread t])
+  "Menu for `emchat-log-mode'.")
+
+(easy-menu-define
+ emchat-buddy-easymenu nil "Buddy" emchat-log-menu)
+
+(defvar emchat-log-mode-map
+  (let ((map (make-sparse-keymap 'emchat-log-mode-map)))
+    (set-keymap-parents map (list emchat-main-map))
+    (define-key map [delete] #'emchat-log-contract)
+    (define-key map [insert] #'emchat-log-expand)
+    (define-key map [(control up)] #'emchat-log-previous)
+    (define-key map [(control down)] #'emchat-log-next)
+    (define-key map [v] #'emchat-log-mark-unread)
+    (define-key map [c] #'emchat-log-mark-read)
+    (define-key map [W] #'emchat-alias-around)
+    (define-key map [s] #'emchat-select-alias-around)
+    (define-key map [m] #'emchat-send-message-alias-around)
+    (define-key map [u] #'emchat-send-url-alias-around)
+    (define-key map [a] #'emchat-authorize-alias-around)
+    (define-key map [i] #'emchat-query-info-alias-around)
+    (define-key map [f] #'emchat-forward-message-around)
+    (define-key map [n] #'emchat-log-next-unread)
+    (define-key map [N] #'emchat-log-next)
+    (define-key map [o] #'emchat-switch-to-buddy-buffer)
+    (define-key map [O] #'emchat-oops)
+    (define-key map [p] #'emchat-log-previous-unread)
+    (define-key map [P] #'emchat-log-previous)
+    (define-key map [t] #'emchat-history-around)
+    (define-key map [T] #'emchat-history)
+    map)
+  "Keymap for `emchat-log-mode'.")
+
+(defvar emchat-history-menu
+  '("EMchat-History"
+    ["Prev Event" emchat-history-prev t]
+    ["Next Event" emchat-history-next t]
+    ["Save Histories" emchat-history-save t]
+    ["Quit"       emchat-history-bury-buffer t])
+  "Menu for `emchat-history-mod'.")
+
+(defvar emchat-history-mode-map
+  (let ((map (make-sparse-keymap 'emchat-history-mode-map)))
+    (define-key map [n] #'emchat-history-next)
+    (define-key map [p] #'emchat-history-prev)
+    (define-key map [s] #'emchat-history-save)
+    (define-key map [q] #'emchat-history-bury-buffer)
+    map)
+  "Keymap for `emchat-history-mode'.")
+
+(easy-menu-define
+ emchat-history-easymenu nil "History" emchat-history-menu)
+
+(defvar emchat-buddy-menu
+  '("EMchat-Buddy"
+    ["Select Here" emchat-select-alias-here t]
+    ["Select By Status" emchat-buddy-select-all-in-view-by-status t]
+    ["Select By Regexp" emchat-buddy-select-all-in-view-by-regexp t]
+    ["Send Message Here" emchat-send-message-alias-here t]
+    ["Send URL Here" emchat-send-url-alias-here t]
+    ["Authorize Here" emchat-authorize-alias-here t]
+    ["Query Info Here" emchat-query-info-alias-here t]
+    ["History Here" emchat-history-here-other-window t]
+    "---"
+    ["View Connected" emchat-buddy-view-connected t]
+    ["View Active" emchat-buddy-view-active t]
+    ["View All" emchat-buddy-view-all t])
+  "Menu for `emchat-buddy-mode'.")
+
+(easy-menu-define
+ emchat-log-easymenu nil "Log" emchat-buddy-menu)
+
+(defvar emchat-alias-map
+  (let ((map (make-sparse-keymap 'emchat-alias-map)))
+    (define-key map [button2] #'emchat-send-message-via-mouse)
+    map)
+  "Keymap for alias extent.")
+
+(defvar emchat-hyperlink-map
+  (let ((map (make-sparse-keymap 'emchat-hyperlink-map)))
+    (define-key map [button2] #'emchat-emphasis-visit-hyperlink-at-mouse)
+    (define-key map [return] #'emchat-emphasis-visit-hyperlink-at-point)
+    (emchat-do-in-sxemacs
+      (define-key map [(control button2)] #'emchat-curl-url-at-mouse)
+      (define-key map [(control return)] #'emchat-curl-url-at-point)
+      (define-key map [d] #'emchat-curl-url-at-point))
+    map)
+  "Keymap for the hyperlink extents.")
+
+(defvar emchat-buddy-mode-map
+  (let ((map (make-sparse-keymap 'emchat-buddy-mode-map)))
+    (set-keymap-parents map (list emchat-main-map))
+    (define-key map [W] #'emchat-alias-here)
+    (define-key map [s] #'emchat-select-alias-here)
+    (define-key map [m] #'emchat-send-message-alias-here)
+    (define-key map [u] #'emchat-send-url-alias-here)
+    (define-key map [a] #'emchat-authorize-alias-here)
+    (define-key map [i] #'emchat-query-info-alias-here)
+    (define-key map [n] #'next-line)
+    (define-key map [o] #'emchat-switch-to-log-buffer)
+    (define-key map [p] #'previous-line)
+    (define-key map [t] #'emchat-history-here-other-window)
+    map)
+  "Keymap for `emchat-buddy-mode'.")
+
+(provide 'emchat-menu)
+;;; emchat-menu.el ends here
+
diff --git a/emchat-meta.el b/emchat-meta.el
new file mode 100644 (file)
index 0000000..9e51b63
--- /dev/null
@@ -0,0 +1,473 @@
+;;; emchat-meta.el --- User meta info code for EMchat
+
+;; Copyright (C) 2002 - 2007 Steve Youngs
+
+;; Author:        Steve Youngs <steve@emchat.org>
+;; Maintainer:    Steve Youngs <steve@emchat.org>
+;; Created:       2002-10-02
+;; Homepage:      http://www.emchat.org/
+;; Keywords:      comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(defgroup emchat-meta nil
+  "User info stored in ICQ server.
+Run `emchat-update-meta-info' after changing any of these variables."
+  :prefix "emchat-user-meta-"
+  :group 'emchat)
+
+(defcustom emchat-user-meta-nickname "e-i-c-q"
+  "*Your nickname stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable.
+ICQ server refuses any string containing substring \"icq\"."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-firstname "SXEmacs"
+  "*Your first name stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable.
+ICQ server refuses any string containing substring \"icq\"."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-lastname "Linux"
+  "*Your last name stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable.
+ICQ server refuses any string containing substring \"icq\"."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-primary-email "emacs@home.com"
+  "*Your primary email address stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable.
+ICQ server refuses any string containing substring \"icq\"."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-secondary-email "emchat@home.com"
+  "*Your secondary email address stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-old-email "emchat@home.com"
+  "*Your old email address stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-city nil
+  "*Your city stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-state nil
+  "*Your state stored on the ICQ server.
+We're talking 'address' here, not online state.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-phone nil
+  "*Your phone number stored on the ICQ server.
+Do you really want to divulge this information?
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-fax nil
+  "*Your fax number stored on the ICQ server.
+Do you really want to divulge this information?
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-street nil
+  "*Your street name and number stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-cell-phone nil
+  "*Your cell phone number stored on the ICQ server.
+Do you really want to divulge this information?
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-zipcode nil
+  "*Your zip code/postal code stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-country nil
+  "*Your country stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-web-aware t
+  "*Set this to non-nil if you want your presence know on the web."
+  :type 'boolean
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-invisible nil
+  "*Set to non-nil to be \"invisible\" to other ICQ users.
+
+Having your status set to \"invisible\" is a little different from
+other statuses in that you can be \"invisible\" at the same time as
+being \"online\", \"away\", \"occ\", \"dnd\", or \"na\"."
+  :type 'boolean
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-invisibility-indicator "/inv"
+  "String to indicate your visibility.
+
+It is displayed as part of your status, eg:
+
+    [JackaLX]: <online/inv>"
+  :type 'string
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-hide-ip nil
+  "*Set to non-nil if you want to hide your IP.
+Run `emchat-update-meta-info' after modifying this variable."
+  :type 'boolean
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-authorization t
+  "*Authorization needed to add you to others' contact lists..
+Run `emchat-update-meta-info' after modifying this variable."
+  :type 'boolean
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-about
+  "Give a man a new Emacs command,
+  and he can hack for a night;
+Teach a man to make new Emacs commands,
+  and he can hack for a life time."
+  "*User 'about' info stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-homepage 
+  "http://www.emchat.org/"
+  "*User homepage stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-age 65535
+  "*Your age stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable.
+65535 = not entered."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-sex 'not-entered
+  "*Your sex stored on the ICQ server.
+No, it's not an invitation.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta
+  :type '(choice (item male) (item female)
+                 (item not-entered)))
+
+(defcustom emchat-user-meta-birth-year nil
+  "*Your birth year (YY) stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-birth-month nil
+  "*Your birth month (MM) stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-birth-day nil
+  "*Your birth day (DD) stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-language-1 0
+  "*User 1st language stored on the ICQ server.
+Possible values are:
+
+ 0 Unspecified 7 Chinese   17 French     27 Japanese   36 Portuguese 46 Tagalog
+55 Afrikaans   8 Croatian  18 Gaelic     28 Khmer      37 Romanian   47 Tatar
+58 Albanian    9 Czech     19 German     29 Korean     38 Russian    48 Thai
+ 1 Arabic     10 Danish    20 Greek      30 Lao        39 Serbian    49 Turkish
+59 Armenian   11 Dutch     21 Hebrew     31 Latvian    40 Slovak     50 Ukrainian
+ 2 Bhojpuri   12 English   22 Hindi      32 Lithuanian 41 Slovenian  51 Urdu
+ 3 Bulgarian  13 Esperanto 23 Hungarian  33 Malay      42 Somali     52 Vietnamese
+ 4 Burmese    14 Estonian  24 Icelandic  34 Norwegian  43 Spanish    53 Yiddish
+ 5 Cantonese  15 Farsi     25 Indonesian 57 Persian    44 Swahili    54 Yoruba
+ 6 Catalan    16 Finnish   26 Italian    35 Polish     45 Swedish
+
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-language-2 0
+  "*User 2nd language stored on the ICQ server.
+Possible values are:
+
+ 0 Unspecified 7 Chinese   17 French     27 Japanese   36 Portuguese 46 Tagalog
+55 Afrikaans   8 Croatian  18 Gaelic     28 Khmer      37 Romanian   47 Tatar
+58 Albanian    9 Czech     19 German     29 Korean     38 Russian    48 Thai
+ 1 Arabic     10 Danish    20 Greek      30 Lao        39 Serbian    49 Turkish
+59 Armenian   11 Dutch     21 Hebrew     31 Latvian    40 Slovak     50 Ukrainian
+ 2 Bhojpuri   12 English   22 Hindi      32 Lithuanian 41 Slovenian  51 Urdu
+ 3 Bulgarian  13 Esperanto 23 Hungarian  33 Malay      42 Somali     52 Vietnamese
+ 4 Burmese    14 Estonian  24 Icelandic  34 Norwegian  43 Spanish    53 Yiddish
+ 5 Cantonese  15 Farsi     25 Indonesian 57 Persian    44 Swahili    54 Yoruba
+ 6 Catalan    16 Finnish   26 Italian    35 Polish     45 Swedish
+
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-language-3 0
+  "*User 3rd language stored on the ICQ server.
+Possible values are:
+
+ 0 Unspecified 7 Chinese   17 French     27 Japanese   36 Portuguese 46 Tagalog
+55 Afrikaans   8 Croatian  18 Gaelic     28 Khmer      37 Romanian   47 Tatar
+58 Albanian    9 Czech     19 German     29 Korean     38 Russian    48 Thai
+ 1 Arabic     10 Danish    20 Greek      30 Lao        39 Serbian    49 Turkish
+59 Armenian   11 Dutch     21 Hebrew     31 Latvian    40 Slovak     50 Ukrainian
+ 2 Bhojpuri   12 English   22 Hindi      32 Lithuanian 41 Slovenian  51 Urdu
+ 3 Bulgarian  13 Esperanto 23 Hungarian  33 Malay      42 Somali     52 Vietnamese
+ 4 Burmese    14 Estonian  24 Icelandic  34 Norwegian  43 Spanish    53 Yiddish
+ 5 Cantonese  15 Farsi     25 Indonesian 57 Persian    44 Swahili    54 Yoruba
+ 6 Catalan    16 Finnish   26 Italian    35 Polish     45 Swedish
+
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-city nil
+  "*User work city stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-state nil
+  "*User work state stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-phone nil
+  "*User work phone number stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-fax nil
+  "*User work fax number stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-address nil
+  "*User work address stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-company nil
+  "*User company stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-department nil
+  "*User work department stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-position nil
+  "*User work position stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+(defcustom emchat-user-meta-work-homepage "http://www.emchat.org/"
+  "*User work homepage stored on the ICQ server.
+Run `emchat-update-meta-info' after modifying this variable."
+  :group 'emchat-meta)
+
+;;; Internal variables
+
+(defvar emchat-monthnames
+  ["0" "Jan" "Feb" "Mar" "Apr" "May" "Jun"
+   "Jul" "Aug" "Sep" "Oct" "Nov" "Dec"])
+
+;;; FIXME:  This needs to be updated for v8
+; (defun emchat-pack-meta-user-update-general ()
+;   "Pack meta user packet 064a:03e8.
+; `M-x customize-group RET emchat-info' before this."
+;   (emchat-pack
+;    "\x4a\x06"
+;    "\xe8\x03"
+;    (emchat-int-bin (length emchat-user-meta-nickname))
+;    emchat-user-meta-nickname
+;    (emchat-int-bin (length emchat-user-meta-firstname))
+;    emchat-user-meta-firstname
+;    (emchat-int-bin (length emchat-user-meta-lastname))
+;    emchat-user-meta-lastname
+;    (emchat-int-bin (length emchat-user-meta-primary-email))
+;    emchat-user-meta-primary-email
+;    (emchat-int-bin (length emchat-user-meta-secondary-email))
+;    emchat-user-meta-secondary-email
+;    (emchat-int-bin (length emchat-user-meta-old-email))
+;    emchat-user-meta-old-email
+;    (emchat-int-bin (length emchat-user-meta-city))
+;    emchat-user-meta-city
+;    (emchat-int-bin (length emchat-user-meta-state))
+;    emchat-user-meta-state
+;    (emchat-int-bin (length emchat-user-meta-phone))
+;    emchat-user-meta-phone
+;    (emchat-int-bin (length emchat-user-meta-fax))
+;    emchat-user-meta-fax
+;    (emchat-int-bin (length emchat-user-meta-street))
+;    emchat-user-meta-street
+;    (emchat-int-bin (length emchat-user-meta-cell-phone))
+;    emchat-user-meta-cell-phone
+;    ;; zip code? only accept valid values
+;    "\x00\x00\x00\x00"
+;    (emchat-int-bin (car (rassoc emchat-user-meta-country emchat-country-code)))))
+
+;;; FIXME:  This needs to be updated for v8
+; (defun emchat-pack-meta-user-security ()
+;   "Pack meta user packet 064a:0424."
+;   (emchat-pack
+;    "\x4a\x06"
+;    "\x24\x04"
+;    (if emchat-user-meta-authorization
+;        "\x00"
+;      "\x01")
+;    (if emchat-user-meta-web-aware
+;        "\x01" 
+;      "\x00")
+;    (if emchat-user-meta-hide-ip 
+;        "\x00" 
+;      "\x01")))
+
+;;; FIXME:  This needs to be updated for v8
+; (defun emchat-pack-meta-user-update-work ()
+;   "Pack meta user packet 064a:03f2.
+; `M-x customize-group RET emchat-info' before this."
+;   (emchat-pack
+;    "\x4a\x06"
+;    "\xf2\x03"
+;    (emchat-int-bin (length emchat-user-meta-work-city))
+;    emchat-user-meta-work-city
+;    (emchat-int-bin (length emchat-user-meta-work-state))
+;    emchat-user-meta-work-state
+;    (emchat-int-bin (length emchat-user-meta-work-phone))
+;    emchat-user-meta-work-phone
+;    (emchat-int-bin (length emchat-user-meta-work-fax))
+;    emchat-user-meta-work-fax
+;    (emchat-int-bin (length emchat-user-meta-work-address))
+;    emchat-user-meta-work-address
+;    ;; unknown
+;    "\x00\x00\x00\x00\x00\x00"
+;    (emchat-int-bin (length emchat-user-meta-work-company))
+;    emchat-user-meta-work-company
+;    (emchat-int-bin (length emchat-user-meta-work-department))
+;    emchat-user-meta-work-department
+;    (emchat-int-bin (length emchat-user-meta-work-position))
+;    emchat-user-meta-work-position
+;    ;; unknown
+;    "\x00\x00"
+;    (emchat-int-bin (length emchat-user-meta-work-homepage))
+;    emchat-user-meta-work-homepage))
+
+;;; FIXME:  This needs to be updated for v8
+; (defun emchat-pack-meta-user-update-more ()
+;   "Pack meta user packet 064a:03fc.
+; `M-x customize-group RET emchat-info' before this."
+;   (emchat-pack
+;    "\x4a\x06"
+;    "\xfc\x03"
+;    (emchat-int-bin emchat-user-meta-age)
+;    (case emchat-user-meta-sex
+;      (male "\x02")
+;      (female "\x01")
+;      (otherwise "\x00"))
+;    (emchat-int-bin (length emchat-user-meta-homepage))
+;    emchat-user-meta-homepage
+;    (emchat-int-byte emchat-user-meta-birth-year)
+;    (emchat-int-byte emchat-user-meta-birth-month)
+;    (emchat-int-byte emchat-user-meta-birth-day)
+;    (emchat-int-byte emchat-user-meta-language-1)
+;    (emchat-int-byte emchat-user-meta-language-2)
+;    (emchat-int-byte emchat-user-meta-language-3)))
+
+;;; FIXME:  This needs to be updated for v8
+; (defun emchat-pack-meta-user-update-about ()
+;   "Pack meta user packet 064a:0406.
+; `M-x customize-group RET emchat-info' before this."
+;   (emchat-pack
+;    "\x4a\x06"
+;    "\x06\x04"
+;    (emchat-int-bin (length emchat-user-meta-about))
+;    emchat-user-meta-about))
+
+;;; FIXME:  This needs to be updated for v8
+; (defvar emchat-do-meta-alist
+;   '(("\x64\x00" . emchat-do-meta-user-update-general-confirm)
+;     ("\x6e\x00" . emchat-do-meta-user-update-work-confirm)
+;     ("\x78\x00" . emchat-do-meta-user-update-more-confirm)
+;     ("\x82\x00" . emchat-do-meta-user-update-about-confirm)
+;     ("\xaa\x00" . emchat-do-meta-user-password)
+;     ("\xc8\x00" . emchat-do-meta-user-general)
+;     ("\xd2\x00" . emchat-do-meta-user-work)
+;     ("\xdc\x00" . emchat-do-meta-user-more)
+;     ("\xe6\x00" . emchat-do-meta-user-about)
+;     ("\xf0\x00" . emchat-do-meta-user-interest)
+;     ("\xfa\x00" . emchat-do-meta-user-background)
+;     ("\x0e\x01" . emchat-do-meta-user-picture)
+;     ("\x9a\x01" . emchat-do-meta-user-found))
+;   "Handlers for server packet meta user subcommands.")
+
+;;; FIXME:  This needs to be updated for v8
+; (defun emchat-do-meta-user (packet)
+;   "Handle server command 03de in PACKET."
+;   (let* ((subcommand (substring packet 21 23))
+;          (result (substring packet 23 24))
+;          (data (substring packet 24))
+;          (handler (cdr (assoc subcommand emchat-do-meta-alist))))
+;     (if (not (equal result "\x0a"))
+;         (emchat-log-info "meta user command failed")
+;       (if (fboundp handler)
+;           (funcall handler data)
+;         (emchat-do-meta-user-unknown packet)))))
+
+;;; FIXME:  This needs to be updated for v8
+; (defun emchat-do-meta-user-unknown (packet)
+;   "Handle server command 03de unknown subcommands in PACKET."
+;   (emchat-log-debug
+;    "meta user subcommand %s unhandled = %s"
+;    (emchat-bin-hex (substring packet 21 23))
+;    (emchat-bin-pretty-hex (substring packet 24))))
+
+;;; FIXME:  This needs to be updated for v8
+; (defun emchat-update-meta-info ()
+;   "Update user meta info on the ICQ server.
+; Run this after changing any meta user info variables."
+;   (interactive)
+;   ;(emchat-send (emchat-pack-update-authorization))
+;   (emchat-send (emchat-pack-meta-user-security))
+;   (emchat-send (emchat-pack-meta-user-update-general))
+;   (emchat-send (emchat-pack-meta-user-update-work))
+;   (emchat-send (emchat-pack-meta-user-update-more))
+;   (emchat-send (emchat-pack-meta-user-update-about)))
+
+(provide 'emchat-meta)
+
+;;; emchat-status.el ends here
+
diff --git a/emchat-report.el b/emchat-report.el
new file mode 100644 (file)
index 0000000..9052063
--- /dev/null
@@ -0,0 +1,335 @@
+;;; emchat-report.el --- Generate a bug report   -*-Emacs-Lisp-*-
+
+;; Copyright (C) 2001 - 2007 Steve Youngs
+
+;; Author:        Steve Youngs <steve@emchat.org>
+;; Maintainer:    Steve Youngs <steve@emchat.org>
+;; Keywords:      bug-report
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;; To submit a bug report use: M-x emchat-report-bug
+;; To send general comments/questions use: M-x emchat-email-author
+
+;;; Code:
+
+(autoload 'emchat-version "emchat" 
+  "Version of emchat you are currently using." t nil)
+(require 'sendmail)
+(require 'shadow)
+(require 'gnus-msg)
+(require 'gnus-util)
+(require 'message)
+
+;; To keep the byte-compiler from spewing out warnings.
+(eval-when-compile
+  (defvar after-sep-pos)
+  (defvar final-resting-place)
+  (defvar emchat-version)
+  (require 'font-lock)
+  (require 'yow)
+  (require 'pp))
+
+
+;;; Variables
+
+(defcustom emchat-report-bug-send-init nil
+  "*If non-nil, include the user's init.el file in the bug report."
+  :group 'emchat-option
+  :type 'boolean)
+
+;;; Internal variables
+
+(defconst emchat-report-salutations
+  ["Dear bug team:"
+   "Ciao bug team:"
+   "Salut bug team:"
+   "Guten Tag bug team:"
+   "To whom it may concern:"
+   "Fellow EMchat'ers:"
+   "Yo bug team:"
+   "G'day bug team:"
+   "Greetings Earthlings:"]
+  "A list of salutations used for `emchat-report-bug'.")
+
+(defvar emchat-bug-address
+  "EMchat Bugs <emchat-bugs@emchat.org>"
+  "The address used for submitting bug reports.")
+
+(defvar emchat-report-blurb nil)
+
+;;; Functions
+
+(defun emchat-report-pre-hook ()
+  "Pre hook run by report-submit-bug-report."
+  (message-goto-subject)
+  (insert "EMchat bug: ")
+  (if emchat-report-blurb
+      (progn
+       (mail-text)
+       (insert "\n" emchat-report-blurb "\n"))))
+
+(defun emchat-report-post-hook ()
+  "Post hook run by report-submit-bug-report."
+  (save-excursion
+    (message-goto-subject)
+    (font-lock-fontify-buffer)
+    (let ((subj (read-string "Subject header: ")))
+      (if (string-equal subj "")
+         (subst-char-in-region
+          (point)
+          (progn
+            (insert
+             (if (or (fboundp 'yow) (load "yow" t t)) (yow) ""))
+            (point))
+          ?\n ?\ )
+       (insert subj)))))
+
+;; Stolen from Gnus.
+(defun emchat-report-debug ()
+  "Go through the EMchat source files and report what variables have been changed.
+The source file has to be in the load path."
+  (let ((files '("emchat-buddy.el" "emchat-comm.el" "emchat-curl.el" "emchat-doctor.el"
+                "emchat-emphasis.el" "emchat-log.el" "emchat-meta.el" "emchat-report.el"
+                "emchat-status.el" "emchat-toolbar.el" "emchat-track.el" "emchat-wharf.el"
+                "emchat-world.el" "emchat-xwem.el" "emchat.el"))
+       (point (point))
+       file expr olist sym)
+    (message "Please wait while we snoop your variables...")
+    (sit-for 0)
+    ;; Go through all the files looking for non-default values for variables.
+    (save-excursion
+      (set-buffer (get-buffer-create " *emchat bug info*"))
+      (while files
+       (erase-buffer)
+       (when (and (setq file (locate-library (pop files)))
+                  (file-exists-p file))
+         (insert-file-contents file)
+         (goto-char (point-min))
+         (if (not (re-search-forward "^;;* *Internal variables" nil t))
+             (message "Malformed sources in file %s" file)
+           (narrow-to-region (point-min) (point))
+           (goto-char (point-min))
+           (while (setq expr (ignore-errors (read (current-buffer))))
+             (ignore-errors
+               (and (or (eq (car expr) 'defvar)
+                        (eq (car expr) 'defcustom))
+                    (stringp (nth 3 expr))
+                    (or (not (boundp (nth 1 expr)))
+                        (not (equal (eval (nth 2 expr))
+                                    (symbol-value (nth 1 expr)))))
+                    (push (nth 1 expr) olist)))))))
+      (kill-buffer (current-buffer)))
+    (when (setq olist (nreverse olist))
+      (insert "\n"))
+    (while olist
+      (when (boundp (car olist))
+       (condition-case ()
+           (pp `(setq ,(car olist)
+                      ,(if (or (consp (setq sym (symbol-value (car olist))))
+                               (and (symbolp sym)
+                                    (not (or (eq sym nil)
+                                             (eq sym t)))))
+                           (list 'quote (symbol-value (car olist)))
+                         (symbol-value (car olist))))
+               (current-buffer))
+         (error
+          (format "(setq %s 'whatever)\n" (car olist)))))
+       ;(insert ";; (makeunbound '" (symbol-name (car olist)) ")\n"))
+      (setq olist (cdr olist)))
+    ;; Remove any control chars - they seem to cause trouble for some
+    ;; mailers.  (Byte-compiled output from the stuff above.)
+    (goto-char point)
+    (while (re-search-forward "[\000-\010\013-\037\200-\237]" nil t)
+      (replace-match (format "\\%03o" (string-to-char (match-string 0)))
+                    t t))))
+
+(defun emchat-prepare-report ()
+  "Grabs the variables, features to include in bug report.
+Then put it all into a mail buffer, nicely formatted."
+  (message-goto-to)
+  (insert emchat-bug-address)
+  (message-goto-body)
+  (forward-line 1)
+  (setq after-sep-pos (point))
+  (setq final-resting-place (point-marker))
+  (insert 
+   "\n\n"
+   "===============================================================\n"
+   "System info to help the EMchat boys and girls try to fix your bug:\n"
+   "==============================================================="
+   "\n\n")
+  (emchat-version 1)
+  ;; Insert all the EMchat vars that have been changed from default.
+  ;; The actual work for this is done in `emchat-bug-debug', but it
+  ;; needs to be called toward the end of this function.
+  (insert "\n\nEMchat variables of note:\n----------------------\n")
+  ;; Insert the output of 'describe-installation'.
+  (insert "\n\n"
+         (symbol-value 'Installation-string))
+  ;; Load-path shadows can cause some grief.
+  (flet ((append-message
+          (&rest args) ())
+        (clear-message
+          (&optional label frame stdout-p no-restore)
+          ()))
+    (insert "\n\nLoad-Path Lisp Shadows:\n"
+           "----------------------\n")
+    (let ((before-shadows (point)))
+      (insert
+       (format "%s"
+               (find-emacs-lisp-shadows load-path)))
+      (save-restriction
+       (narrow-to-region before-shadows (point))
+       (fill-paragraph t)
+       (insert "\n"))))
+  ;; Insert a list of installed packages.
+  (insert "\n\nInstalled XEmacs Packages:\n"
+         "-------------------------\n")
+  (cl-prettyprint
+   (symbol-value 'packages-package-list))
+  (insert "\n")
+  ;; Insert a list of loaded features
+  (let ((before-features (point)))
+    (insert
+     (format "\n\nFeatures:\n--------\n\n%s" (symbol-value 'features)))
+    (save-restriction
+      (narrow-to-region before-features (point))
+      (fill-paragraph t)
+      (insert "\n\n")))
+  ;; Insert the contents of the user's init file if it exists 
+  ;; and the user wants it sent.
+  (if emchat-report-bug-send-init
+      (if (file-readable-p user-init-file)
+         (save-excursion
+           (message-goto-signature)
+           (forward-line -3)
+           (beginning-of-line)
+           (insert "\n\nUser Init File:\n--------------\n\n")
+           (insert-file-contents user-init-file))))
+  (emchat-report-pre-hook)
+  (emchat-report-post-hook)
+  (mail-text)
+  (insert
+   (aref emchat-report-salutations
+        (% (+ (% (random) 1000) 1000)
+           (length emchat-report-salutations))) "\n")
+  (re-search-forward "EMchat variables of note:" nil t)
+  (forward-line 2)
+  (emchat-report-debug)
+  (goto-char final-resting-place)
+  (set-marker final-resting-place nil)
+  (message "Please enter your report.  Type C-c C-c to send, C-x k to abort."))
+
+;;;###autoload
+(defun emchat-report-bug (&optional blurb no-confirm)
+  "Submit a bug report for emchat.
+Optional argument BLURB is a string that adds a preamble to the bug report.
+Optional argument NO-CONFIRM if 't' will not ask for confirmation.
+
+If you have Gnus it will be used, otherwise the standard XEmacs mail
+command is used.
+
+Yes, it's all part of a secret plot to make more people use 
+the MUA of Gods.  Bwahahaha."
+  (interactive)
+  (if (or no-confirm
+         (y-or-n-p "Do you want to submit a bug report on EMchat? "))
+      (progn
+       (setq emchat-report-blurb blurb)
+       (if (featurep 'gnus)
+           (progn
+             (unless (gnus-alive-p)
+               (gnus))
+             (gnus-group-mail 1)
+             (emchat-prepare-report))
+         (mail)
+         (emchat-prepare-report)))))
+
+;;; email-author code
+
+(defconst emchat-email-salutations
+  ["Dear Steve,"
+   "Ciao Steve,"
+   "Guten Tag Steve,"
+   "To whom it may concern:"
+   "Bonjour Steve,"
+   "Yo! EMchat Dude!"
+   "G'day Steve,"
+   "Hey Man,"
+   "Greetings Earthling:"]
+  "A list of salutations used for `emchat-email-author'.")
+
+(defun emchat-prepare-email-author ()
+  "Prepare the mail buffer for `emchat-email-author'."
+  (message-goto-to)
+  (insert "Steve Youngs <steve@emchat.org>")
+  (message-goto-cc)
+  (insert "EMchat Users <emchat-users@emchat.org>")
+  (message-goto-subject)
+  (let ((subj (read-string "Subject header: ")))
+    (if (string-equal subj "")
+       (subst-char-in-region
+        (point)
+        (progn
+          (insert
+           (if (or (fboundp 'yow) (load "yow" t t)) (yow) ""))
+          (point))
+        ?\n ?\ )
+      (insert subj)))
+  (message-goto-body)
+  (emchat-version 1)
+  (insert "\n\n"
+         (aref emchat-email-salutations
+               (% (+ (% (random) 1000) 1000)
+                  (length emchat-email-salutations))) "\n\n\n")
+  (forward-line -1))
+
+;;;###autoload
+(defun emchat-email-author ()
+  "Email comments or money to author.
+
+Uses Gnus if available, otherwise standard mail command."
+  (interactive)
+  (if (y-or-n-p "Do you want to send comments to the EMchat author? ")
+      (progn
+       (if (featurep 'gnus)
+           (progn
+             (unless (gnus-alive-p)
+               (gnus))
+             (gnus-group-mail 1)
+             (emchat-prepare-email-author))
+         (mail)
+         (emchat-prepare-email-author)))))
+
+(provide 'emchat-report)
+
+;;; emchat-report.el ends here
diff --git a/emchat-setup.el b/emchat-setup.el
new file mode 100644 (file)
index 0000000..60ff118
--- /dev/null
@@ -0,0 +1,119 @@
+;; emchat-setup.el --- Setup user directory and files for EMchat.
+
+;; Copyright (C) 2002 - 2007 Steve Youngs
+
+;; Author:        Steve Youngs <steve@emchat.org>
+;; Maintainer:    Steve Youngs <steve@emchat.org>
+;; Created:       2002-10-03
+;; Homepage:      http://www.emchat.org/
+;; Keywords:      comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(defconst emchat-world-user-file-template
+  "
+Literally you can put anything you like in this resource file, such as
+this introduction.  EMchat will only consider a line to be a valid buddy
+if...
+
+    -- `:icq' starts at column zero (there's no leading whitespace or
+       characters).
+
+    -- There is one space between `:icq' and a UIN.
+
+    -- There is one space between a UIN and a buddy name.
+
+    -- The buddy name does NOT contain any colon `:' characters.
+       Buddy names can contain whitespace anywhere except as the
+       first character.
+
+    -- There is one space between the buddy name and any group names.
+       Group names begin with a colon `:'.
+
+So, for example...
+
+:icq 34307457 emchat
+:icq 12345678 me
+:icq 88888888 the queen :royalty
+
+This way, it defines three buddies: \"emchat\", \"me\", and \"the
+queen\". It reads alias name until the end of the line, or until the
+first group name.  In that example, the buddy \"the queen\" is in
+the group `:royalty'.
+
+Adding your own UIN:
+
+Just change \"12345678 me\" above to your UIN/alias.  And don't
+forget to change the (setq emchat-user-alias \"me\") line in your
+`user-init-file' to match.
+
+BTW, that 1st buddy up there, 34307457 emchat, is a valid UIN, it's
+mine. :-)
+
+Remember to M-x emchat-world-update after changing this rc file.
+
+"
+  "Template used to create user's initial EMchat rc file.")
+
+(eval-when-compile
+  (defvar emchat-history-directory))
+
+;;;###autoload
+(defun emchat-setup ()
+  "Setup your personal EMchat directory.
+
+This directory, which defaults to '~/.emchat/', holds the resource file
+for your ICQ contacts and any log files.  It's also a good place to
+put your sound files."
+  (interactive)
+  (unless (featurep '(and emchat emchat-history emchat-world emchat-setup))
+    (require 'emchat)
+    (require 'emchat-history)
+    (require 'emchat-world)
+    (require 'emchat-setup))
+  ;; Create necessary directories.
+  (unless (file-directory-p emchat-directory)
+    (make-directory emchat-directory t))
+  (unless (file-directory-p emchat-sound-directory)
+    (make-directory emchat-sound-directory t))
+  (unless (file-directory-p emchat-history-directory)
+    (make-directory emchat-history-directory t))
+  ;; Create a world file if needed.
+  (unless (file-exists-p emchat-world-rc-filename)
+    (save-excursion
+      (switch-to-buffer (find-file emchat-world-rc-filename))
+      (insert (symbol-value 'emchat-world-user-file-template))
+      (save-buffer)
+      (kill-buffer nil)))
+  (message "Don't forget to edit %s to your requirements"
+          emchat-world-rc-filename))
+             
+(provide 'emchat-setup)
+;;; emchat-setup.el ends here
diff --git a/emchat-status.el b/emchat-status.el
new file mode 100644 (file)
index 0000000..d870eab
--- /dev/null
@@ -0,0 +1,509 @@
+;;; emchat-status.el --- Status code for EMchat
+
+;; Copyright (C) 2002 - 2007 Steve Youngs
+
+;; Author:        Steve Youngs <steve@emchat.org>
+;; Maintainer:    Steve Youngs <steve@emchat.org>
+;; Created:       2002-10-02
+;; Homepage:      http://www.emchat.org/
+;; Keywords:      comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(eval-and-compile
+  (require 'emchat-log)
+  (require 'emchat-world)
+  (require 'emchat-meta)
+  (require 'emchat)
+  (require 'wid-edit))
+
+(eval-when-compile
+  (defvar emchat-buddy-view)
+  (defvar emchat-wharf-frame-use-p))
+
+(autoload 'emchat-buddy-update-face "emchat-buddy")
+
+
+(defcustom emchat-buddy-status-color-hint-flag t
+  "*Non-nil means put status color hints."
+  :type 'boolean
+  :group 'emchat-buddy)
+
+;;;###autoload
+(defcustom emchat-status-window-height 8
+  "*Height of window for `emchat-status-buffer'."
+  :group 'emchat-interface)
+
+(defcustom emchat-status-use-gutter nil
+  "*When non-nil, display statuses in the gutter, not in a buffer."
+  :type 'boolean
+  :group 'emchat-interface)
+
+(defcustom emchat-status-gutter-orientation 'top
+  "Where to display the status gutter.
+
+Valid values are: top, bottom, left, right."
+  :type '(choice (item :tag "Top" :value top)
+                (item :tag "Bottom" :value bottom)
+                (item :tag "Left" :value left)
+                (item :tag "Right" :value right))
+  :group 'emchat-interface)
+
+;;;###autoload
+(defvar emchat-valid-statuses
+  '("online" "away" "occ" "dnd" "ffc" "na")
+  "All statuses valid for selection.
+Used by `emchat-change-status' and in `emchat-buddy-buffer'.")
+
+;;;###autoload
+(defcustom emchat-user-initial-status "online"
+  "*Initial user status when login."
+  :group 'emchat-option
+  :type
+  (cons 'choice
+        (mapcar
+         (lambda (x) (list 'item x))
+         emchat-valid-statuses)))
+
+(defcustom emchat-status-update-hook nil
+  "*Hooks to run when a buddy change his status.
+Dynamically ALIAS and STATUS are binded to be used in hooks."
+  :group 'emchat-option
+  :type 'hook)
+
+(defface emchat-face-online
+  '((((background dark))
+     (:foreground "green"))
+    (((background light))
+     (:foreground "green4")))
+  "Face for ONLINE status."
+  :group 'emchat-buddy)
+
+(defface emchat-face-away
+  '((((background dark))
+     (:foreground "red"))
+    (((background light))
+     (:foreground "red4")))
+  "Face for AWAY status."
+  :group 'emchat-buddy)
+
+(defface emchat-face-occ
+  '((((background dark))
+     (:foreground "orange"))
+    (((background light))
+     (:foreground "orange4")))
+  "Face for OCCUPIED status."
+  :group 'emchat-buddy)
+
+(defface emchat-face-dnd
+  '((((background dark))
+     (:foreground "lightblue"))
+    (((background light))
+     (:foreground "blue")))
+  "Face for DO NOT DISTURB status."
+  :group 'emchat-buddy)
+
+(defface emchat-face-ffc
+  '((((background dark))
+     (:foreground "yellow"))
+    (((background light))
+     (:foreground "yellow4")))
+  "Face for FREE FOR CHAT status."
+  :group 'emchat-buddy)
+
+(defface emchat-face-na
+  '((((background dark))
+     (:foreground "pink"))
+    (((background light))
+     (:foreground "deeppink")))
+  "Face for NOT AVAILABLE status."
+  :group 'emchat-buddy)
+
+(defface emchat-face-invisible
+  '((((background dark))
+     (:foreground "grey"))
+    (((background light))
+     (:foreground "grey40")))
+  "Face for OFFLINE status."
+  :group 'emchat-buddy)
+
+;;; Internal variables
+
+(defvar emchat-statuses
+  ;; basically status is only ONE byte (except for invisible?)
+  ;; byte after status byte is random
+  '((online "online" emchat-face-online)
+    (away "away" emchat-face-away emchat-auto-reply-away)
+    (na "na" emchat-face-na emchat-auto-reply-na)
+    (occupied "occ" emchat-face-occ emchat-auto-reply-occ)
+    (dnd "dnd" emchat-face-dnd emchat-auto-reply-dnd)
+    (ffc "ffc" emchat-face-ffc)
+    (offline "offline" nil)
+    (invisible "invisible" emchat-face-invisible))
+  "Status info: v8 status, text code, face, auto-reply.")
+
+(defun emchat-status-face (name)
+  "Return the face of status from its NAME."
+  (caddar
+   (member* name emchat-statuses
+            :key 'second
+            :test 'string=)))
+
+(defun emchat-status-v8 (name)
+  "Return the symbol for status NAME."
+  (caar
+   (member* name emchat-statuses
+           :key 'second
+           :test 'string=)))
+
+(defun emchat-status-auto-reply (name)
+  "Return the symbol of auto-reply of status from its NAME."
+  (fourth (car
+           (member* name emchat-statuses
+            :key 'second
+            :test 'string=))))
+
+(defun emchat-status-idle-reply (name)
+  "Return the symbol of idle-reply of status from its NAME."
+  (let ((sym (emchat-status-auto-reply name)))
+    (with-temp-buffer
+      (insert (symbol-name sym))
+      (while (search-backward "auto" nil t)
+       (replace-match "idle" nil t))
+      (intern (buffer-string)))))
+
+(defun emchat-status-name (proto-status)
+  "Return the name of status from its the binary string BIN."
+  (cadr (assoc proto-status emchat-statuses)))
+
+(defun emchat-buddy-update-status (alias status)
+  "Update ALIAS with new STATUS."
+  ;; update alias variables
+  (unless (member status (mapcar 'second emchat-statuses))
+    (push (cons 'unknown-status emchat-recent-packet)
+          emchat-error-packets)
+    (emchat-log-error "Unknown status: %s" status)
+    (setq status "online"))             ; assumed online
+
+  ;; kludge-o-matic
+  (when (and (equal alias emchat-user-alias)
+            (string= status "invisible"))
+    (setq status emchat-user-status))
+
+  (unless (emchat-world-getf alias 'status)
+    (emchat-world-putf alias 'status "offline"))
+
+  (unless (equal status (emchat-world-getf alias 'status))
+    (emchat-world-putf alias 'status status)
+    (emchat-log-buddy-status alias "***| %s" status)
+    (when (string= status "online")
+      (emchat-play-sound-maybe 'buddy-sound))
+    (if (string= status "offline")
+       (if (member alias emchat-connected-aliases)
+           (setq emchat-connected-aliases
+                 (delete alias emchat-connected-aliases))
+         (emchat-log-buddy-status alias "***| has been invisible"))
+      ;; if not offline
+      (add-to-list 'emchat-connected-aliases alias))
+
+    ;; update buffer
+
+    ;; view != all + offline -> delete
+    ;; view = all + offline -> offline-face
+    (if (and (string= status "offline")
+            (not (eq emchat-buddy-view 'emchat-all-aliases)))
+       (emchat-buddy-update-face alias 'delete)
+      (if (or (member alias (symbol-value emchat-buddy-view))
+             (string= status "offline"))
+         (emchat-buddy-update-face alias)))))
+
+;;;###autoload
+(defvar emchat-user-status "offline"
+  "Current user status.")
+
+(defun emchat-do-status-update (ectx uin status)
+  "Handle server command 01a4 in PACKET."
+  (let ((alias (emchat-uin-alias (emchat-stringular-uin uin)))
+        (status (emchat-status-name status)))
+    (emchat-buddy-update-status alias status)
+    (run-hooks 'emchat-status-update-hook)))
+
+(defun emchat-turn-on-invisibility ()
+  (emchat-v8-snac-cli-setstatus
+   emchat-ctx (append (list (emchat-status-v8 emchat-user-status))
+                   (and emchat-user-meta-web-aware '(web-aware))
+                   '(invisible)))
+  (emchat-log-buddy-status emchat-user-alias "***| %s (invisible)" emchat-user-status)
+  (setq emchat-user-meta-invisible t))
+
+(defun emchat-turn-off-invisibility ()
+  (emchat-v8-snac-cli-setstatus
+   emchat-ctx (append (list (emchat-status-v8 emchat-user-status))
+                   (and emchat-user-meta-web-aware '(web-aware))))
+  (emchat-log-buddy-status emchat-user-alias "***| %s (visible)" emchat-user-status)
+  (setq emchat-user-meta-invisible nil))
+
+(defun emchat-toggle-invisibility ()
+  "Toggle \"invisible\" status."
+  (interactive)
+  (setq emchat-user-meta-invisible (null emchat-user-meta-invisible))
+  (if emchat-user-meta-invisible
+      (emchat-turn-on-invisibility)
+    (emchat-turn-off-invisibility))
+  (with-current-buffer emchat-log-buffer
+    (emchat-log-update-modeline)))
+  
+(defun emchat-change-status (status &optional no-network)
+  "Change to new STATUS.
+Non-nil NO-NETWORK means not to send any network packet, only update
+variable and modeline."
+  (interactive
+   (list (emchat-completing-read "status: " emchat-valid-statuses nil t)))
+  (unless (equal status emchat-user-status)
+    (when emchat-user-auto-away-p
+      (setq emchat-user-auto-away-p nil))
+    (emchat-log-system "Changed status to %s" status)
+    (when (equal status "online")
+      (setq emchat-auto-reply-never emchat-auto-response-never-send-to)
+      (loop for alias in emchat-online-notifiers
+       do (emchat-v8-send-simple-message
+           emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias))
+           "I'm back online.
+You won't be notified again unless you re-request 
+it with \",,notify-me\".")
+       do (emchat-log-system (format "Online notification sent to: %s" alias)))
+      (setq emchat-online-notifiers nil))
+    (setq emchat-user-status status)
+    (when emchat-wharf-frame-use-p
+      (declare-fboundp (emchat-wharf-update-status)))
+    (redraw-modeline 'all)
+    (unless no-network
+      (emchat-v8-snac-cli-setstatus
+       emchat-ctx (append (list (emchat-status-v8 status))
+                       (and emchat-user-meta-web-aware '(web-aware))
+                       (and emchat-user-meta-invisible '(invisible)))))))
+
+;;;###autoload
+(defvar emchat-status-buffer nil
+  "Buffer for statuses.")
+
+;;;###autoload
+(defun emchat-status-show-buffer (&optional new no-select)
+  "Switch to `emchat-status-buffer'.
+Create buffer if buffer does not exists already or
+NEW is non-nil.
+Don't select status window if NO-SELECT is non-nil."
+  (interactive)
+  (when (or (not (buffer-live-p emchat-status-buffer))
+            new)
+    (setq emchat-status-buffer (get-buffer-create "*Status*"))
+    (set-buffer emchat-status-buffer)
+    (set-specifier horizontal-scrollbar-visible-p nil 
+                  (cons (current-buffer) nil))
+    (set-specifier vertical-scrollbar-visible-p nil
+                  (cons (current-buffer) nil))
+    (set-specifier has-modeline-p nil
+                  (cons (current-buffer) nil))
+    (erase-buffer)
+    (set (make-local-variable 'widget-button-face) 'emchat-face-online)
+    (widget-create 'link
+                  :help-echo "Change status to \"Online\""
+                  :action (lambda (&rest ignore)
+                            (emchat-change-status "online"))
+                  "Online")
+    (widget-insert "\n")
+    (set (make-local-variable 'widget-button-face) 'emchat-face-away)
+    (widget-create 'link
+                  :help-echo "Change status to \"Away\""
+                  :action (lambda (&rest ignore)
+                            (emchat-change-status "away"))
+                  "Away")
+    (widget-insert "\n")
+    (set (make-local-variable 'widget-button-face) 'emchat-face-occ)
+    (widget-create 'link
+                  :help-echo "Change status to \"Occupied\""
+                  :action (lambda (&rest ignore)
+                            (emchat-change-status "occ"))
+                  "Occupied")
+    (widget-insert "\n")
+    (set (make-local-variable 'widget-button-face) 'emchat-face-dnd)
+    (widget-create 'link
+                  :help-echo "Change status to \"Do Not Disturb\""
+                  :action (lambda (&rest ignore)
+                            (emchat-change-status "dnd"))
+                  "Do Not Disturb")
+    (widget-insert "\n")
+    (set (make-local-variable 'widget-button-face) 'emchat-face-na)
+    (widget-create 'link
+                  :help-echo "Change status to \"Not Available\""
+                  :action (lambda (&rest ignore)
+                            (emchat-change-status "na"))
+                  "Not Available")
+    (widget-insert "\n")
+    (set (make-local-variable 'widget-button-face) 'emchat-face-ffc)
+    (widget-create 'link
+                  :help-echo "Change status to \"Free For Chat\""
+                  :action (lambda (&rest ignore)
+                            (emchat-change-status "ffc"))
+                  "Free For Chat")
+    (widget-insert "\n")
+    (set (make-local-variable 'widget-button-face) 'emchat-face-invisible)
+    (widget-create 'link
+                  :help-echo "Toggle your visibility"
+                  :action (lambda (&rest ignore)
+                            (emchat-toggle-invisibility))
+                  "Invisible on/off")
+    (toggle-read-only 1)
+    (unless no-select
+      (switch-to-buffer emchat-status-buffer))))
+
+;;; Status gutter 
+;;; WARNING: This is experimental and unfinished.
+(defvar emchat-status-gutter-tab nil
+  "A tab widget in the gutter for switching online statuses.
+Do not set this.  Use `set-glyph-image' to change the properties of
+the tab.")
+
+(defun emchat-status-maybe-login ()
+  "Convenience function for the status gutter.
+If a connection to the ICQ server exists, just change status to
+online, otherwise login."
+  (if (emchat-connected-p emchat-ctx)
+      (emchat-change-status "online")
+    (emchat-login)))
+
+(defvar emchat-status-tabs
+  '(["Online" (emchat-status-maybe-login)
+     :selected (equal emchat-user-status "online")]
+    ["Away" (emchat-change-status "away")
+     :selected (equal emchat-user-status "away")]
+    ["Occupied" (emchat-change-status "occ")
+     :selected (equal emchat-user-status "occ")]
+    ["Do Not Disturb" (emchat-change-status "dnd")
+     :selected (equal emchat-user-status "dnd")]
+    ["Not Available" (emchat-change-status "na")
+     :selected (equal emchat-user-status "na")]
+    ["FFC" (emchat-change-status "ffc")
+     :selected (equal emchat-user-status "ffc")]
+    ["Inv on/off" (emchat-toggle-invisibility) :selected nil]
+    ["Offline" (emchat-logout)
+     :selected (equal emchat-user-status "offline")])
+  "Buttons for the EMchat status gutter.")
+
+;;; FIXME: Left and right gutters are broken, also, I don't like
+;;; setting `default-gutter-position' to change the orientation
+;;; although the docs seem to suggest that this is the only way to
+;;; do it... 
+;;   ,----[ C-h v right-gutter RET ]
+;;   | `right-gutter' is a built-in constant specifier variable.
+;;   | 
+;;   | Value: #<gutter-specifier global=<unspecified> fallback=((nil)) 0x145>
+;;   | 
+;;   | Documentation:
+;;   | Specifier for the gutter at the right edge of the frame.
+;;   | Use `set-specifier' to change this.
+;;   | See `default-gutter' for a description of a valid gutter instantiator.
+;;   | 
+;;   | Note that, unless the `default-gutter-position' is `right', by
+;;   | default the height of the right gutter (controlled by
+;;   | `right-gutter-width') is 0; thus, a right gutter will not be
+;;   | displayed even if you provide a value for `right-gutter'.
+;;   `----
+
+(defun emchat-add-tab-to-gutter ()
+  (let* ((gutter-string (copy-sequence "\n"))
+        (status-gutter-extent (make-extent 0 1 gutter-string)))
+    (set-extent-begin-glyph status-gutter-extent
+                           (setq emchat-status-gutter-tab
+                                 (make-glyph)))
+    (mapcar
+     (lambda (x)
+       (remove-gutter-element top-gutter 'status-tab emchat-frame x)
+       (remove-gutter-element bottom-gutter 'status-tab emchat-frame x)
+       (remove-gutter-element left-gutter 'status-tab emchat-frame x)
+       (remove-gutter-element right-gutter 'status-tab emchat-frame x))
+     (console-type-list))
+    (mapcar
+     (lambda (x)
+       (when (valid-image-instantiator-format-p 'tab-control x)
+        (cond ((eq emchat-status-gutter-orientation 'top)
+               (set-default-gutter-position 'top)
+               (set-specifier top-gutter-visible-p t emchat-frame x)
+               (set-specifier top-gutter-border-width 0 emchat-frame x)
+               (set-gutter-element top-gutter 'status-tab 
+                                   gutter-string emchat-frame x))
+              ((eq emchat-status-gutter-orientation 'bottom)
+               (set-default-gutter-position 'bottom)
+               (set-specifier bottom-gutter-visible-p t emchat-frame x)
+               (set-specifier bottom-gutter-border-width 0 emchat-frame x)
+               (set-gutter-element bottom-gutter 'status-tab
+                                   gutter-string emchat-frame x))
+              ((eq emchat-status-gutter-orientation 'left)
+               (set-default-gutter-position 'left)
+               (set-specifier left-gutter-visible-p t emchat-frame x)
+               (set-specifier left-gutter-border-width 0 emchat-frame x)
+               (set-gutter-element left-gutter 'status-tab
+                                   gutter-string emchat-frame x))
+              ((eq emchat-status-gutter-orientation 'right)
+               (set-default-gutter-position 'right)
+               (set-specifier right-gutter-visible-p t emchat-frame x)
+               (set-specifier right-gutter-border-width 0 emchat-frame x)
+               (set-gutter-element right-gutter 'status-tab
+                                   gutter-string emchat-frame x)))))
+     (console-type-list))))
+
+;;; FIXME: When the gutter code in (S)XEmacs can put different faces
+;;; on different buttons update this so that the status tabs have the
+;;; right faces... emchat-face-{online,away,na,occ,dnd,ffc,invisible}.
+(defun emchat-update-tab-in-gutter ()
+  "Update the tab control in the gutter area."
+  (unless (or (window-dedicated-p (frame-selected-window emchat-frame))
+             (frame-property emchat-frame 'popup))
+    (emchat-add-tab-to-gutter)
+    (when (valid-image-instantiator-format-p 'tab-control emchat-frame)
+      (set-glyph-image
+       emchat-status-gutter-tab
+       (vector 'tab-control :descriptor "Status"
+              :face 'bold
+              :orientation emchat-status-gutter-orientation
+              (if (or (eq emchat-status-gutter-orientation 'top)
+                      (eq emchat-status-gutter-orientation 'bottom))
+                  :pixel-width :pixel-height)
+              (if (or (eq emchat-status-gutter-orientation 'top)
+                      (eq emchat-status-gutter-orientation 'bottom))
+                  '(gutter-pixel-width) '(gutter-pixel-height)) 
+              :items (eval 'emchat-status-tabs))
+       emchat-frame)
+      ;; set-glyph-image will not make the gutter dirty
+      (set-gutter-dirty-p emchat-status-gutter-orientation))))
+
+(provide 'emchat-status)
+
+;;; emchat-status.el ends here
diff --git a/emchat-toolbar.el b/emchat-toolbar.el
new file mode 100644 (file)
index 0000000..de022c0
--- /dev/null
@@ -0,0 +1,281 @@
+;;; emchat-toolbar.el --- A toolbar for EMchat   -*-Emacs-Lisp-*-
+
+;; Copyright (C) 2000 - 2007 Steve Youngs
+
+;; Author:        Steve Youngs <steve@emchat.org>
+;; Maintainer:    Steve Youngs <steve@emchat.org>
+;; Keywords:      emchat, toolbar, comm
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;; 
+;;            A toolbar for emchat.
+;;
+
+(eval-and-compile
+  (require 'emchat-meta)
+  (require 'emchat-log))
+
+(autoload 'emchat-change-password "emchat" nil t)
+(autoload 'emchat-send-message-alias-here "emchat" nil t)
+(autoload 'emchat-send-message "emchat" nil t)
+(autoload 'emchat-send-url-alias-here "emchat" nil t)
+(autoload 'emchat-send-url "emchat" nil t)
+(autoload 'emchat-query-info-alias-around "emchat" nil t)
+(autoload 'emchat-query-info "emchat" nil t)
+(autoload 'emchat-search "emchat" nil t)
+(autoload 'emchat-authorize-alias-here "emchat" nil t)
+(autoload 'emchat-login "emchat" nil t)
+(autoload 'emchat-logout "emchat" nil t)
+(autoload 'emchat-exit "emchat" nil t)
+
+;;; Code:
+
+(defcustom emchat-use-toolbar (if (and (featurep 'toolbar)
+                                    (featurep 'xpm))
+                               'default-toolbar
+                             nil)
+  "*If nil, do not use a toolbar.
+If it is non-nil, it must be a toolbar.  The five valid values are
+`default-toolbar', `top-toolbar', `bottom-toolbar',
+`right-toolbar', and `left-toolbar'."
+  :type '(choice (const default-toolbar)
+                (const top-toolbar) (const bottom-toolbar)
+                (const left-toolbar) (const right-toolbar)
+                (const :tag "no toolbar" nil))
+  :group 'emchat-interface)
+
+(defvar emchat-password-icon
+  (toolbar-make-button-list
+   (expand-file-name "password.xpm" emchat-glyph-dir))
+  "A password toolbar icon.")
+
+(defvar emchat-send-message-here-icon
+  (toolbar-make-button-list
+   (expand-file-name "msg-here.xpm" emchat-glyph-dir))
+  "A send message toolbar icon.")
+
+(defvar emchat-send-message-around-icon
+  (toolbar-make-button-list
+   (expand-file-name "msg-around.xpm" emchat-glyph-dir))
+  "A send message toolbar icon.")
+
+(defvar emchat-send-url-here-icon
+  (toolbar-make-button-list
+   (expand-file-name "url-here.xpm" emchat-glyph-dir))
+  "A send URL toolbar icon.")
+
+(defvar emchat-send-url-around-icon
+  (toolbar-make-button-list
+   (expand-file-name "url-around.xpm" emchat-glyph-dir))
+  "A send URL toolbar icon.")
+
+(defvar emchat-query-info-here-icon
+  (toolbar-make-button-list
+   (expand-file-name "info-here.xpm" emchat-glyph-dir))
+  "A query info here toolbar icon.")
+
+(defvar emchat-query-info-around-icon
+  (toolbar-make-button-list
+   (expand-file-name "info-around.xpm" emchat-glyph-dir))
+  "A query info here toolbar icon.")
+
+(defvar emchat-update-info-icon
+  (toolbar-make-button-list
+   (expand-file-name "upd-info.xpm" emchat-glyph-dir))
+  "A update info toolbar icon.")
+
+(defvar emchat-search-icon
+  (toolbar-make-button-list
+   (expand-file-name "search.xpm" emchat-glyph-dir))
+  "A search toolbar icon.")
+
+(defvar emchat-authorize-here-icon
+  (toolbar-make-button-list
+   (expand-file-name "auth-here.xpm" emchat-glyph-dir))
+  "A authorize toolbar icon.")
+
+(defvar emchat-login-icon
+  (toolbar-make-button-list
+   (expand-file-name "login.xpm" emchat-glyph-dir))
+  "A login toolbar icon.")
+
+(defvar emchat-logout-icon
+  (toolbar-make-button-list
+   (expand-file-name "logout.xpm" emchat-glyph-dir))
+  "A logout toolbar icon.")
+
+(defvar emchat-exit-icon
+  (toolbar-make-button-list
+   (expand-file-name "exit.xpm" emchat-glyph-dir))
+  "A exit toolbar icon.")
+
+(defvar emchat-new-log-icon
+  (toolbar-make-button-list
+   (expand-file-name "new-log.xpm" emchat-glyph-dir))
+  "New log file toolbar icon.")
+
+(defvar emchat-help-icon
+  (toolbar-make-button-list
+   (expand-file-name "help.xpm" emchat-glyph-dir))
+  "A help toolbar icon.")
+
+;; Define the functions for the toolbar
+
+(defun emchat-toolbar-change-password (password)
+  "Change PASSWORD from the toolbar."
+  (interactive (list (read-passwd "Password: " 'confirm)))
+  (emchat-change-password password))
+
+(defun emchat-toolbar-send-message-here ()
+  "Send message from toolbar."
+  (interactive)
+  (emchat-send-message-alias-here))
+
+(defun emchat-toolbar-send-message-around ()
+  "Send message from toolbar."
+  (interactive)
+  (emchat-send-message))
+
+(defun emchat-toolbar-send-url-here ()
+  "Send URL from the toolbar."
+  (interactive)
+  (emchat-send-url-alias-here))
+
+(defun emchat-toolbar-send-url-around ()
+  "Send URL from the toolbar."
+  (interactive)
+  (emchat-send-url))
+
+(defun emchat-toolbar-query-info-here ()
+  "Query info from the toolbar."
+  (interactive)
+  (emchat-query-info-alias-around))
+
+(defun emchat-toolbar-query-info-around ()
+  "Query info from the toolbar."
+  (interactive)
+  (emchat-query-info))
+
+(defun emchat-toolbar-update-info ()
+  "Update meta info from the toolbar."
+  (interactive)
+  ;(emchat-update-meta-info))
+  (message-or-box "Sorry, this feature is not yet implemented"))
+
+(defun emchat-toolbar-search ()
+  "Search from the toolbar.
+
+Prompts for the search terms."
+  (interactive)
+  (let ((first (read-string "First Name [RET for null]: "))
+       (last (read-string "Last Name [RET for null]: "))
+       (nick (read-string "Nick Name [RET for null]: "))
+       (email (read-string "Email Address [RET for null]: ")))
+    (emchat-search nil first last nick email)))
+
+(defun emchat-toolbar-authorize-here ()
+  "Authorize from the toolbar."
+  (interactive)
+  (emchat-authorize-alias-here))
+
+(defun emchat-toolbar-login ()
+  "Login from the toolbar."
+  (interactive)
+  (emchat-login))
+
+(defun emchat-toolbar-logout ()
+  "Logout from the toolbar."
+  (interactive)
+  (emchat-logout))
+
+(defun emchat-toolbar-exit ()
+  "Exit from the toolbar."
+  (interactive)
+  (emchat-exit))
+
+(defun emchat-toolbar-new-log ()
+  "New log file from the toolbar."
+  (interactive)
+  (emchat-log-new-file))
+
+(defun emchat-toolbar-help ()
+  "Display the EMchat info documentation."
+  (interactive)
+  (Info-goto-node "(emchat.info)Top"))
+
+;; Now define the toolbar
+(defvar emchat-log-toolbar
+  '([emchat-password-icon
+     emchat-toolbar-change-password t "Change password"]
+    [emchat-send-message-here-icon
+     emchat-toolbar-send-message-here t "Send message here"]
+    [emchat-send-message-around-icon
+     emchat-toolbar-send-message-around t "Send message..."]
+    [emchat-send-url-here-icon
+     emchat-toolbar-send-url-here t "Send URL here"]
+    [emchat-send-url-around-icon
+     emchat-toolbar-send-url-around t "Send URL..."]
+    [emchat-query-info-here-icon
+     emchat-toolbar-query-info-here t "Query info here"]
+    [emchat-query-info-around-icon
+     emchat-toolbar-query-info-around t "Query info..."]
+    [emchat-search-icon
+     emchat-toolbar-search t "Search"]
+    [emchat-authorize-here-icon
+     emchat-toolbar-authorize-here t "Authorize here"]
+    [emchat-new-log-icon
+     emchat-toolbar-new-log t "New log file"]
+    [emchat-login-icon
+     emchat-toolbar-login t "Login"]
+    [emchat-logout-icon
+     emchat-toolbar-logout t "Logout"]
+    [emchat-exit-icon
+     emchat-toolbar-exit t "Exit"]
+    nil
+    [emchat-help-icon
+     emchat-toolbar-help t "Help"])
+  "A clickety click EMchat log buffer toolbar.")
+
+;;;###autoload
+(defun emchat-install-buddy-toolbar ()
+  "Install the toolbar for `emchat-buddy-mode' in EMchat."
+  (and emchat-use-toolbar
+       (set-specifier (symbol-value emchat-use-toolbar)
+                     (cons
+                      (current-buffer) emchat-log-toolbar))))
+
+;;;###autoload
+(defalias 'emchat-install-log-toolbar 'emchat-install-buddy-toolbar)
+
+(provide 'emchat-toolbar)
+
+;;; emchat-toolbar.el ends here
diff --git a/emchat-track.el b/emchat-track.el
new file mode 100644 (file)
index 0000000..0ea02a9
--- /dev/null
@@ -0,0 +1,181 @@
+;;; emchat-track.el --- Event tracking code for EMchat.
+
+;; Copyright (C) 2005 - 2007 Steve Youngs, Alexey Mikhailov
+
+;; Author:         Alexey Mikhailov <karma@sxemacs.org>
+;; Maintainer:     Alexey Mikhailov <karma@sxemacs.org>
+;; Created:        2005-04-25
+;; Homepage:       http://www.emchat.org/
+;; Keywords:       
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+
+;; emchat-track.el tracks ICQ channel activity and notifies user in modeline.
+;; To start with emchat-track add to your ~/.sxemacs/init.el:
+;; 
+;;     (require 'emchat-track)
+;;     (emchat-track-mode 1)
+;; 
+;; or simple:
+;; 
+;;     (setq emchat-track-enable t)
+;; 
+;; if you dont want emchat-track to be loaded
+;; 
+;; You may want to customize `emchat-track-events-type' and
+;; `emchat-track-indicator-type'
+
+;;; Code:
+\f
+(eval-when-compile
+  (defvar emchat-log-buffer))
+
+(defgroup emchat-track nil
+  "Track EMchat events and show activity in the modeline."
+  :group 'emchat)
+
+(defcustom emchat-track-enable nil
+  "*Enable tracking."
+  :group 'emchat-track
+  :type 'boolean)
+
+(defcustom emchat-track-events-type 'msg
+  "*What event types to track.
+
+Possible values are:
+    all      -- all events \(anything that gets logged will be tracked\)
+    incoming -- only incoming messages plus system and debug events
+    msg      -- incoming user messages only
+    nil      -- no events."
+  :group 'emchat-track
+  :type '(choice (item :tag "All Events" all)
+                 (item :tag "Incoming msg + sys + debug events" incoming)
+                (item :tag "Incoming user messages" msg)
+                 (item :tag "Nothing" nil)))
+
+(defcustom emchat-track-indicator-type 'name
+  "*What type of indicator is displayed in the modeline.
+
+Possible values are:
+
+    name -- [nick,nick2,nick3] \(ERC style\).
+            \"nick\" is shortened to `emchat-track-shorten-to'.
+    char -- [E] \(Riece style\)"
+  :type '(radio (item :tag "Multi names \(ERC style\)" name)
+               (item :tag "Single character \(Riece style\)" char))
+  :group 'emchat-track)
+
+(defcustom emchat-track-shorten-to 4
+  "*All nicks will be shortened to this number of chars."
+  :type 'integer
+  :group 'emchat-track)
+
+(defcustom emchat-track-activity-hook nil
+  "*Hooks run when `emchat-track-add-nick' is called."
+  :type 'hook
+  :group 'emchat-track)
+
+(defcustom emchat-track-clear-hook nil
+  "*Hooks run when `emchat-track-clear-modeline' is called."
+  :type 'hook
+  :group 'emchat-track)
+
+;;; Internal variables
+(defvar emchat-track-events-string "")
+
+(defun emchat-track-truncate-nick (nick)
+  "Return shortened nick."
+  (if (> (length nick) emchat-track-shorten-to)
+      (substring nick 0 emchat-track-shorten-to)
+    nick))
+
+(defun emchat-track-add-nick (nick)
+  "Add new nick to events strings."
+  (let ((snick (emchat-track-truncate-nick nick)))
+    (setq global-mode-string
+         (delq 'emchat-track-events-string global-mode-string))
+    (if (eq emchat-track-indicator-type 'char)
+       ;; Riece style indicator.
+       (setq emchat-track-events-string "[E]")
+      ;; ERC style indicator.
+      (if (equal emchat-track-events-string "") 
+         (setq emchat-track-events-string (format "[%s]" snick))
+       (and (not (search snick emchat-track-events-string))
+            (setq emchat-track-events-string
+                  (format "%s,%s]"
+                          (substring emchat-track-events-string 0
+                                     (1- (length emchat-track-events-string)))
+                          snick)))))
+    (setq global-mode-string (append global-mode-string
+                                    '(emchat-track-events-string)))
+    (run-hooks 'emchat-track-activity-hook)
+    (redraw-modeline t)))
+
+(defun emchat-track-clear-modeline () 
+  "Remove `emchat-track' messages from modeline."
+  (setq global-mode-string (delq 'emchat-track-events-string global-mode-string))
+  (setq emchat-track-events-string "")
+  (run-hooks 'emchat-track-clear-hook)
+  (redraw-modeline t))
+
+(defun emchat-track-check-log-buffer ()
+  (and (get-buffer-window emchat-log-buffer)
+       (emchat-track-clear-modeline)))
+
+(defun emchat-track-init ()
+  "Initialize `emchat-track', perform defadvices and hooks"
+  (defadvice switch-to-buffer (after emchat-update (&rest args) activate)
+    "After switching buffers, check to see if emchat-track should be cleared.
+The emchat-track modeline indicator will only be cleared if
+`emchat-log-buffer' is visible in the selected frame."
+    (emchat-track-check-log-buffer))
+  (add-hook 'select-frame-hook 'emchat-track-check-log-buffer)
+  (put 'emchat-track 'initialized t))
+
+(defun emchat-track-mode (&optional arg)
+  "Toggle emchat track mode."
+  (interactive "P")
+  (if (or (and (numberp arg) (< arg 0))
+          (and (null arg) emchat-track-enable))
+      (setq emchat-track-enable nil)
+    (setq emchat-track-enable t)))
+
+(defun emchat-track-enable ()
+  (interactive)
+  (emchat-track-mode 1))
+
+(defun emchat-track-disable ()
+  (interactive)
+  (emchat-track-mode -1))
+
+(provide 'emchat-track)
+;;; emchat-track.el ends here
diff --git a/emchat-utils.el b/emchat-utils.el
new file mode 100644 (file)
index 0000000..0d52a18
--- /dev/null
@@ -0,0 +1,156 @@
+;; emchat-utils.el --- misc utils for EMchat   -*- Emacs-Lisp -*-
+
+;; Copyright (C) 2007 Steve Youngs
+
+;; Author:     Steve Youngs <steve@emchat.org>
+;; Maintainer: Steve Youngs <steve@emchat.org>
+;; Created:    <2007-09-01>
+;; Homepage:   http://www.emchat.org/
+;; Keywords:   utils ICQ emchat
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;; 
+;;    This is where any general-purpose utils for EMchat go
+
+;;; Code:
+(eval-when-compile
+  (defvar emchat-all-aliases))
+
+(defcustom emchat-glyph-dir
+  (file-name-as-directory (or (locate-data-directory "emchat") ""))
+  "Directory where icons and logos live."
+  :type 'directory
+  :group 'emchat-interface)
+
+;;; Internal variables
+
+(defmacro emchat-do-in-xemacs (&rest body)
+  "Execute BODY if in XEmacs."
+  (when (featurep '(and xemacs (not sxemacs)))
+    `(progn ,@body)))
+
+(put 'emchat-do-in-xemacs 'lisp-indent-hook 'defun)
+
+(defmacro emchat-do-in-sxemacs (&rest body)
+  "Execute BODY if in SXEmacs."
+  (when (featurep 'sxemacs)
+    `(progn ,@body)))
+
+(put 'emchat-do-in-sxemacs 'lisp-indent-hook 'defun)
+
+(defun emchat-completing-read
+  (prompt table &optional predicate require-match initial-contents history)
+  "Args: PROMPT, TABLE, PREDICATE, REQUIRE-MATCH, INITIAL-CONTENTS, HISTORY.
+Same as `completing-read' but accepts strings as well as obarray."
+  (completing-read
+   prompt
+   (if (vectorp table)
+       table (mapcar 'list table))
+   predicate require-match initial-contents history))
+
+(defun emchat-numeric-uin (uin)
+  "Return UIN as number.
+UIN can be either a string or number."
+  (cond ((numberp uin) uin)
+       ((stringp uin) (string-to-number uin))
+       (t (error "Invalid UIN type" uin))))
+
+(defun emchat-stringular-uin (uin)
+  "Return UIN as a string.
+UIN can be either a string or a number."
+  (cond ((numberp uin) (number-to-string uin))
+       ((stringp uin) uin)
+       (t (error "Invalid UIN type" uin))))
+
+(defun emchat-valid-uin-p (uin)
+  "Return non-nil if UIN is a valid uin."
+  (not (zerop (emchat-numeric-uin uin))))
+
+(defun emchat-completing-aliases (prompt &optional single)
+  "Completing-read aliases/uin.
+PROMPT is the prompt for reading.
+SINGLE means read only one alias/uin.
+
+Must at least complete one alias, use RET (empty string) to finish
+entering. It first completing-reads from the union of `emchat-active-aliases'
+and `emchat-connected-aliases'. If you hit RET and the input string is not in
+the union it the completing-reads from `emchat-all-aliases'.
+
+Tips: You can also enter an uin in place of an alias."
+  (let ((aliases
+         ;; a must for first one
+         (cons (emchat-completing-alias prompt 'required)
+               (unless single
+                 (loop collect (emchat-completing-alias prompt nil)
+                       into aliases
+                       ;; empty string means abort
+                       until (string= (car (last aliases)) "")
+                       finally return (nbutlast aliases))))))
+    (delete-duplicates aliases :test 'string=)))
+
+(defun emchat-completing-alias (prompt required)
+  "Completing only one alias/uin.
+PROMPT is the prompt for reading.
+REQUIRED means cannot abort.
+Used by `emchat-completing-aliases'.
+No abortion when `** ' is in prompt.
+Abort by RET (empty string) when `++ ' is in prompt."
+  (let ((all emchat-all-aliases)
+        (alias
+          (emchat-completing-read
+           prompt
+          emchat-all-aliases
+           nil nil nil 'emchat-alias-history)))
+    (unless (or
+             ;; valid alias
+             (member alias all)
+             ;; valid uin
+             (emchat-valid-uin-p alias)
+             ;; abort
+             (and (string= alias "")
+                  (not required)))
+      (loop do
+        (setq alias
+              (emchat-completing-read
+               (concat (if required "** " "++ ") prompt)
+               all nil t alias 'emchat-alias-history))
+        while (and (string= alias "") required)))
+    alias))
+
+(defun emchat-switch-buffer (buffer)
+  (when buffer
+    (select-window (get-buffer-window buffer))))
+
+
+
+(provide 'emchat-utils)
+;;; emchat-utils.el ends here
diff --git a/emchat-v8.el b/emchat-v8.el
new file mode 100644 (file)
index 0000000..ea435c1
--- /dev/null
@@ -0,0 +1,2511 @@
+;;; emchat-v8.el --- ICQ v8 for emchat.
+
+;; Copyright (C) 2004 - 2008 Steve Youngs, Zajcev Evgeny
+
+;; Author:        Zajcev Evgeny <zevlg@yandex.ru>
+;; Maintainer:    Steve Youngs <steve@emchat.org>
+;; Created:       Mon Jun  7 16:20:56 MSD 2004
+;; Keywords:      emchat ICQ protocol
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+
+;; Testing UIN: 286012066, PASS: 123
+;;         UIN: 321529598, PASS: 123
+;;
+;;  The various network packets that make up the ICQv8 protocol.
+;;
+;;  See: <http://www.emchat.org/~steve/icq/docs/>
+;;       <http://iserverd1.khstu.ru/oscar/index.html>
+
+;;; Code:
+\f
+(eval-when-compile
+  (require 'cl)
+  (defvar emchat-add-user-success))
+
+;;;; Constants
+
+;; FLAP channel ids
+(defconst emchat-v8-FLAP-HELLO 1)
+(defconst emchat-v8-FLAP-SNAC 2)
+(defconst emchat-v8-FLAP-ERRORS 3)
+(defconst emchat-v8-FLAP-LOGOFF 4)
+(defconst emchat-v8-FLAP-PING 5)
+
+(defconst emchat-v8-client-id-string
+  "ICQ Inc. - Product of ICQ (TM).2002a.5.37.1.3728.85"
+  "A string to identify ourselves as a nice well behaved ICQ client.")
+
+(defconst emchat-v8-FLAP-VER-MAJOR 5)
+(defconst emchat-v8-FLAP-VER-MINOR 37)
+(defconst emchat-v8-FLAP-VER-LESSER 1)
+(defconst emchat-v8-FLAP-VER-BUILD 3828)
+(defconst emchat-v8-FLAP-VER-SUBBUILD 85)
+
+(defconst emchat-v8-message-types
+  '(normal
+    chat-request
+    url
+    request-auth
+    authorize
+    added
+    pager
+    email-express
+    email-check
+    card
+    contact-list)
+  "List of valid message types.")
+
+(defconst emchat-v8-valid-incoming-handlers
+  '(connected                          ; args: no
+    disconnected                       ; args: no
+    instant-message                    ; args: uin, msg &optional msg-type, time-stamp
+    offline-message                    ; args: uin, msg &optional msg-type, time-stamp
+    end-offline-messages               ;
+    about-general                       ; general info about user
+    about-more
+    about-about
+    srv-error
+    ;; TODO: add more
+    )
+  "List of valid incoming message handlers.
+
+To bind on to handle incoming part of icq v8 proto.")
+
+(defconst emchat-v8-valid-outgoing-handlers
+  '(
+    ;; TODO: add some handlers
+    )
+  "List of valid outgoing message handlers.
+
+To bind on to handle outgoing part of icq v8 proto.")
+
+(defstruct emchat-v8-ctx
+  host port                            ; host/port we are currently connected
+  proc                                 ; emchat network connection
+  (readingp 0)                         ; non-0 if we are currently reading from emchat context
+  sequence                             ; current flap sequence
+
+  incoming-buffer                              ; where incoming data stored
+  incoming-handlers
+  outgoing-buffer                      ; buffer for outgoing messages
+  outgoing-handles
+
+  state                                        ; current state, connecting, connected
+  userinfo                             ; plist of userinfo '(uin <num> password <passwd>)
+  plist                                        ; user defined plist
+  )
+
+(defun emchat-v8-ctx-get-prop (ectx prop)
+  "Get ECTX's property PROP value."
+  (plist-get (emchat-v8-ctx-plist ectx) prop))
+
+(defun emchat-v8-ctx-put-prop (ectx prop val)
+  "Put ECTX's property PROP value VAL."
+  (setf (emchat-v8-ctx-plist ectx)
+       (plist-put (emchat-v8-ctx-plist ectx) prop val)))
+(put 'emchat-v8-ctx-put-prop 'lisp-indent-function 2)
+
+(defun emchat-v8-ctx-rm-prop (ectx prop)
+  "Remove ECTX's property PROP."
+  (setf (emchat-v8-ctx-plist ectx)
+       (plist-remprop (emchat-v8-ctx-plist ectx) prop)))
+
+(defun emchat-v8-ctx-get-incoming-handlers (ectx h)
+  (plist-get (emchat-v8-ctx-incoming-handlers ectx) h))
+
+(defun emchat-v8-ctx-add-incoming-handler (ectx h f)
+  (setf (emchat-v8-ctx-incoming-handlers ectx)
+       (plist-put (emchat-v8-ctx-incoming-handlers ectx) h
+                  (cons f (emchat-v8-ctx-get-incoming-handlers ectx h)))))
+
+(defun emchat-v8-ctx-del-incoming-handler (ectx h f)
+  (setf (emchat-v8-ctx-incoming-handlers ectx)
+       (plist-put (emchat-v8-ctx-incoming-handlers ectx) h
+                  (delete f (emchat-v8-ctx-get-incoming-handlers ectx h)))))
+
+(defun emchat-v8-ctx-run-incoming-handler (ectx h &rest args)
+  (let ((ohs (emchat-v8-ctx-get-incoming-handlers ectx h))
+        (ih-arguments args))
+    (when ohs
+      (declare (special ih-arguments))
+      (apply 'run-hook-with-args (cons 'ohs (cons ectx args))))))
+(put 'emchat-v8-ctx-run-incoming-handler 'lisp-indent-function 2)
+
+(defun emchat-get-arg (kw)
+  (declare (special ih-arguments))
+  (plist-get ih-arguments kw))
+
+\f
+(defmacro emchat-v8-ctx-msg-to-send (ectx)
+  `(emchat-v8-ctx-get-prop ,ectx 'message-to-send))
+(defsetf emchat-v8-ctx-msg-to-send (ectx) (msg)
+  `(emchat-v8-ctx-put-prop ,ectx 'message-to-send ,msg))
+
+(defmacro emchat-v8-ctx-pause-p (ectx)
+  `(emchat-v8-ctx-get-prop ,ectx 'pause-p))
+(defsetf emchat-v8-ctx-pause-p (ectx) (pp)
+  `(if ,pp
+       (progn
+         (emchat-v8-ctx-put-prop ,ectx 'pause-p ,pp)
+         (setf (emchat-v8-ctx-msg-to-send ,ectx) ""))
+     (emchat-v8-ctx-rm-prop ,ectx 'pause-p)
+     (emchat-v8-send ,ectx (emchat-v8-ctx-msg-to-send ,ectx))
+     (setf (emchat-v8-ctx-msg-to-send ,ectx) "")))
+
+\f
+(defvar emchat-v8-default-ctx nil
+  "Internal variable, do not modify.")
+
+(defvar emchat-v8-connections nil
+  "List if emchat connections.
+Internal variable, do not modify.")
+
+(defcustom emchat-v8-debug t
+  "*Non-nil mean emchat protocol debugging is enabled."
+  :type 'boolean)
+
+\f
+(defvar emchat-debug-buffer "*emchat-debug*")
+
+(defun emchat-v8-debug (msg &rest args)
+  "Print debug MSG."
+  (when emchat-v8-debug
+    (with-current-buffer
+       (get-buffer-create emchat-debug-buffer)
+      (save-excursion
+       (goto-char (point-max))
+       (insert (apply 'format msg args) "\n")))))
+
+(defun emchat-v8-ctx ()
+  "Return default EMchat context."
+  emchat-v8-default-ctx)
+
+;; FLAP accessors
+(defsubst emchat-v8-flap-cid (flap)
+  (nth 0 flap))
+(defsubst emchat-v8-flap-seq (flap)
+  (nth 1 flap))
+(defsubst emchat-v8-flap-data (flap)
+  (nth 2 flap))
+
+;;; SNAC accessors
+(defsubst emchat-v8-snac-family (snac)
+  (nth 0 snac))
+(defsubst emchat-v8-snac-subtype (snac)
+  (nth 1 snac))
+(defsubst emchat-v8-snac-flags (snac)
+  (nth 2 snac))
+(defsubst emchat-v8-snac-rid (snac)
+  (nth 3 snac))
+
+;;; TLV accessors
+(defsubst emchat-v8-tlv-type (tlv)
+  (nth 0 tlv))
+(defsubst emchat-v8-tlv-len (tlv)
+  (nth 1 tlv))
+(defsubst emchat-v8-tlv-val (tlv)
+  (nth 2 tlv))
+(defsubst emchat-v8-tlv-str (tlv)
+  (aref (emchat-v8-tlv-val tlv) 0))
+(defsubst emchat-v8-tlv-num (tlv)
+  (truncate (emchat-v8-string->number
+   (aref (emchat-v8-tlv-val tlv) 0) (truncate (emchat-v8-tlv-len tlv)))))
+
+(defun emchat-v8-util-encrypt (password)
+  (let ((tb "\xf3\x26\x81\xc4\x39\x86\xdb\x92\x71\xa3\xb9\xe6\x53\x7a\x95\x7c")
+       (res (make-string (length password) ?\x00))
+       (idx 0))
+    (while (< idx (length password))
+      (aset res idx (logxor (aref password idx) (aref tb (mod idx 16))))
+      (setq idx (1+ idx)))
+    res))
+
+(defun emchat-v8-create-ctx (uin &optional password &rest plist)
+  "Create new emchat context using UIN/PASSWORD.
+PLIST is ectx properties list"
+  (let ((ectx (make-emchat-v8-ctx :state 'disconnected :plist plist)))
+    (setf (emchat-v8-ctx-userinfo ectx)
+         (list 'uin uin 'password password))
+    ectx))
+
+(defun emchat-v8-connect (ectx &optional server port)
+  "Connect to SERVER and PORT."
+  (unless server
+    (setq server (or (emchat-v8-ctx-host ectx) "login.icq.com")))
+  (unless port
+    (setq port (or (emchat-v8-ctx-host ectx) 5190)))
+
+  (setf (emchat-v8-ctx-host ectx) server)
+  (setf (emchat-v8-ctx-port ectx) port)
+
+  (let* ((proc (open-network-stream (format "emchat-v8-%s:%d" server port) nil
+                                   server port))
+        (state (emchat-v8-ctx-state ectx)))
+
+    (setf (emchat-v8-ctx-proc ectx) proc)
+    (setf (emchat-v8-ctx-sequence ectx) (random 65536))
+
+    ;; Store connection in emchat connections list
+    (push ectx emchat-v8-connections)
+
+    (set-process-filter proc 'emchat-v8-proc-filter-proccessing)
+    (set-process-sentinel proc 'emchat-v8-proc-sentinel)
+
+    (emchat-v8-debug "Connecting from state=%S" (emchat-v8-ctx-state ectx))
+
+    ;; Adjust ECTX state
+    (cond ((or (eq state 'connecting)
+               (eq state 'closed))
+          (setf (emchat-v8-ctx-state ectx) 'connected))
+         (t (setf (emchat-v8-ctx-state ectx) 'connecting)))
+    ectx))
+
+(defun emchat-v8-close (ectx)
+  "Close ECTX connection."
+  (setf (emchat-v8-ctx-state ectx) 'closed)
+  (emchat-v8-proc-sentinel (emchat-v8-ctx-proc ectx)))
+
+(defun emchat-v8-send (ectx msg)
+  "Using emchat context ECTX, send message MSG."
+  (if (not (emchat-v8-ctx-pause-p ectx))
+      (process-send-string (emchat-v8-ctx-proc ectx) msg)
+    ;; Add MSG to the pending data pending
+    (setf (emchat-v8-ctx-msg-to-send ectx)
+          (concat (emchat-v8-ctx-msg-to-send ectx) msg))))
+(put 'emchat-v8-send 'lisp-indent-function 1)
+
+(defun emchat-v8-send-flush (ectx)
+  "Flush ECTX's output buffer."
+  (when (> (length (emchat-v8-ctx-outgoing-buffer ectx)) 0)
+    (process-send-string
+     (emchat-v8-ctx-proc ectx)
+     (emchat-v8-ctx-outgoing-buffer ectx))))
+
+(defun emchat-v8-proc-find (proc)
+  "Find emchat context by PROC."
+  (let ((ecs emchat-v8-connections))
+    (while (and ecs (not (eq (emchat-v8-ctx-proc (car ecs)) proc)))
+      (setq ecs (cdr ecs)))
+    (car ecs)))
+
+(defun emchat-v8-proc-sentinel (proc &optional event)
+  "Sentinel for emchat PROC."
+  (let ((ectx (emchat-v8-proc-find proc)))
+    (when (emchat-v8-ctx-p ectx)
+
+      (emchat-v8-debug "Removing process %S, state=%S, c-t=%S"
+                     proc (emchat-v8-ctx-state ectx) (emchat-v8-ctx-get-prop ectx 'connect-tries))
+      (delete-process proc)
+      (setf (emchat-v8-ctx-incoming-buffer ectx) "") ;flush input buffer
+
+      (setq emchat-v8-connections (delq ectx emchat-v8-connections))
+      (when (eq (emchat-v8-ctx-state ectx) 'connected)
+        ;; Unexpected disconnection
+        (emchat-v8-ctx-run-incoming-handler ectx 'disconnect)))))
+
+(defun emchat-v8-proc-filter-accumulator (proc out)
+  "Filter for emchat connection to accumulate data."
+  (let ((ectx (emchat-v8-proc-find proc)))
+    (when (emchat-v8-ctx-p ectx)
+      (setf (emchat-v8-ctx-incoming-buffer ectx)
+           (concat (emchat-v8-ctx-incoming-buffer ectx) out)))))
+  
+(defun emchat-v8-proc-filter-proccessing (proc out)
+  "Filter for emchat connection."
+  (let ((ectx (emchat-v8-proc-find proc)))
+    (when (emchat-v8-ctx-p ectx)
+      (setf (emchat-v8-ctx-incoming-buffer ectx)
+           (concat (emchat-v8-ctx-incoming-buffer ectx) out))
+      (enqueue-eval-event 'emchat-v8-fetch-handle-flaps ectx))))
+
+(defvar emchat-v8-snacv-list
+  '((#x01 . #x04)
+    (#x13 . #x04)
+    (#x02 . #x01)
+    (#x03 . #x01)
+    (#x15 . #x01)
+    (#x04 . #x01)
+    (#x06 . #x01)
+    (#x09 . #x01)
+    (#x0A . #x01)
+    (#x0B . #x01)))
+
+(defconst emchat-v8-snac-list
+  '(
+    ;; Family 1, Service
+    ((#x01 . #x01) "SRV_GEN_ERROR"      emchat-v8-snac-srv-err)
+    ((#x01 . #x02) "CLI_READY"          nil)
+    ((#x01 . #x03) "SRV_FAMILIES"       emchat-v8-snac-srv-families)
+    ((#x01 . #x06) "CLI_RATESREQUEST"   emchat-v8-snac-cli-ratesrequest)
+    ((#x01 . #x07) "SRV_RATES"          emchat-v8-snac-srv-rates)
+    ;((#x01 . #x08) "CLI_ACKRATES"       nil) ; handled in SRV_RATES
+    ((#x01 . #x0A) "SRV_RATE_CHANGE"    emchat-v8-snac-srv-rate-change)
+    ((#x01 . #x0B) "SRV_SERVERPAUSE"    emchat-v8-snac-srv-pause)
+    ((#x01 . #x0C) "CLI_ACKSERVERPAUSE" nil)
+    ((#x01 . #x0E) "CLI_REQINFO"        nil)
+    ((#x01 . #x0F) "SRV_REPLYINFO"      emchat-v8-snac-srv-replyinfo)
+    ((#x01 . #x12) "SRV_MIGRATIONREQ"   emchat-v8-snac-srv-migrate)
+    ((#x01 . #x13) "SRV_MOTD"           emchat-v8-snac-srv-motd)
+    ((#x01 . #x17) "CLI_FAMILIES"       nil)
+    ((#x01 . #x18) "SRV_FAMILIES2"      emchat-v8-snac-srv-families2)
+    ((#x01 . #x1E) "CLI_SETSTATUS"      nil)
+    ((#x01 . #x21) "BART_REQUEST"       emchat-v8-snac-bart-request)
+    ;; Family 2, Location
+    ((#x02 . #x01) "SRV_GEN_ERROR"      emchat-v8-snac-srv-err)
+    ((#x02 . #x02) "CLI_REQLOCATION"    nil)
+    ((#x02 . #x03) "SRV_REPLYLOCATION"  emchat-v8-snac-srv-reply-location)
+    ((#x02 . #x04) "CLI_SETUSERINFO"    nil)
+    ;; Family 3, Buddy lists (looks like AOL has turned this off)
+    ((#x03 . #x01) "SRV_CONTACTERR"     emchat-v8-snac-srv-contact-err)
+    ((#x03 . #x02) "CLI_REQBUDDY"       nil)
+    ((#x03 . #x03) "SRV_REPLYBUDDY"     emchat-v8-snac-srv-reply-buddy)
+    ((#x03 . #x04) "CLI_ADDCONTACT"     nil)
+    ((#x03 . #x05) "CLI_REMCONTACT"     nil)
+    ((#x03 . #x0A) "SRV_REFUSE"         emchat-v8-snac-srv-cont-refused)
+    ((#x03 . #x0B) "SRV_USERONLINE"     emchat-v8-snac-srv-user-online)
+    ((#x03 . #x0C) "SRV_USEROFFLINE"    emchat-v8-snac-srv-user-offline)
+    ;; Family 4, ICBM
+    ((#x04 . #x01) "SRV_ICBMERR"        emchat-v8-snac-srv-icbm-err)
+    ((#x04 . #x02) "CLI_SETICBM"        nil)
+    ((#x04 . #x04) "CLI_REQICBM"        nil)
+    ((#x04 . #x05) "SRV_REPLYICBM"      emchat-v8-snac-srv-reply-icbm)
+    ((#x04 . #x06) "CLI_SENDMSG"        nil)
+    ((#x04 . #x07) "SRV_RECVMSG"        emchat-v8-snac-srv-recv-msg)
+    ((#x04 . #x0A) "SRV_MISSED_ICBM"    emchat-v8-snac-srv-missed-icbm)
+    ((#x04 . #x0B) "SRV/CLI_ACKMSG"     emchat-v8-snac-srv-ack-msg)
+    ((#x04 . #x0C) "SRV_SRVACKMSG"      emchat-v8-snac-srv-srv-ack-msg)
+    ;; Family 5, Advertising NOT USED (thank god!)
+    ;; Family 6, Invitation (Invite somebody to AIM) erm, EMchat won't!!
+    ;; Family 7, Admin (AIM)
+    ;; Family 8, Popup Notices (AIM)
+    ;; Family 9, Privacy
+    ((#x09 . #x01) "SRV_GEN_ERROR"      emchat-v8-snac-srv-err)
+    ((#x09 . #x02) "CLI_REQBOS"         nil)
+    ((#x09 . #x03) "SRV_REPLYBOS"       emchat-v8-snac-srv-reply-bos)
+    ((#x09 . #x05) "CLI_ADDVISIBLE"     emchat-v8-snac-cli-addvisible)
+    ((#x09 . #x06) "CLI_REMVISIBLE"     emchat-v8-snac-cli-remvisible)
+    ((#x09 . #x07) "CLI_ADDINVISIBLE"   emchat-v8-snac-cli-addinvisible)
+    ((#x09 . #x08) "CLI_REMINVISIBLE"   emchat-v8-snac-cli-reminvisible)
+    ;; Family a [10], User Lookup (AIM and no longer used)
+    ;; Family b [11], Usage Stats Interval
+    ((#x0B . #x01) "SRV_GEN_ERROR"      emchat-v8-snac-srv-err)
+    ((#x0B . #x02) "SRV_SETINTERVAL"    emchat-v8-snac-srv-set-interval)
+    ;; Family c [12], Translation Service (deprecated (AIM))
+    ;; Family d [13], Chat Navigation (AIM)
+    ;; Family e [14], Chat Service (AIM)
+    ;; Family f [15], Directory Search (AIM)
+    ;; Family 10 [16], Server Stored Buddy Icons
+    ;; Family 13 [19], Server Side Info
+    ((#x13 . #x01) "SRV_GEN_ERROR" emchat-v8-snac-srv-err)
+    ((#x13 . #x02) "CLI_SSI_RIGHTS_REQUEST" emchat-v8-snac-cli-ssi-right-request)
+    ((#x13 . #x03) "SRV_SSI_RIGHTS_REPLY" emchat-v8-snac-srv-ssi-rights-reply)
+    ((#x13 . #x04) "CLI_SSI_REQUEST" emchat-v8-snac-cli-ssi-request)
+    ((#x13 . #x05) "CLI_SSI_CHECKOUT" emchat-v8-snac-cli-ssi-checkout)
+    ((#x13 . #x06) "SRV_SSI_REPLY" emchat-v8-snac-srv-ssi-reply)
+    ((#x13 . #x07) "CLI_SSI_ACTIVATE" emchat-v8-snac-cli-ssi-activate)
+    ((#x13 . #x08) "CLI_SSI_ADD" emchat-v8-snac-cli-ssi-add) ; broken
+    ((#x13 . #x09) "CLI_SSI_UPDATE" emchat-v8-snac-cli-ssi-update) ; not implimented yet
+    ((#x13 . #x0A) "CLI_SSI_DELETE" emchat-v8-snac-cli-ssi-delete) ; not implimented yet
+    ((#x13 . #x0E) "SRV_SSI_MOD_ACK" emchat-v8-snac-srv-ssi-mod-ack)
+    ((#x13 . #x0F) "SRV_SSI_UP_TO_DATE" emchat-v8-snac-srv-ssi-up-to-date)
+    ((#x13 . #x11) "CLI_SSI_EDIT_BEGIN" emchat-v8-snac-cli-ssi-edit-begin)
+    ((#x13 . #x12) "CLI_SSI_EDIT_END" emchat-v8-snac-cli-ssi-edit-end)
+    ((#x13 . #x14) "CLI_SSI_FUTURE_AUTH_GRANT" emchat-v8-snac-cli-ssi-future-auth-grant)
+    ((#x13 . #x15) "SRV_SSI_FUTURE_AUTH_GRANTED" emchat-v8-snac-srv-ssi-future-auth-granted)
+    ((#x13 . #x16) "CLI_SSI_DEL_YOURSELF" emchat-v8-snac-cli-ssi-del-yourself)
+    ((#x13 . #x18) "CLI_SSI_SEND_AUTH_REQUEST" emchat-v8-snac-cli-ssi-send-auth-request)
+    ((#x13 . #x19) "SRV_SSI_AUTH_REQUEST" emchat-v8-snac-srv-ssi-auth-request)
+    ((#x13 . #x1A) "CLI_SSI_AUTH_REPLY" emchat-v8-snac-cli-ssi-auth-reply)
+    ((#x13 . #x1B) "SRV_SSI_AUTH_REPLY" emchat-v8-snac-srv-ssi-auth-reply)
+    ((#x13 . #x1C) "SRV_SSI_YOU_WERE_ADDED" emchat-v8-snac-srv-ssi-you-were-added)
+    ;; Family 15 [21], ICQ Specific
+    ((#x15 . #x01) "SRV_TOICQERR"       emchat-v8-snac-srv-toicqerr)
+    ;; This is like a family within a family... all the SNACS are #x15,#x02
+    ;; but they also have types and subtypes to differentiate between them.
+    ;; So we really don't need a function here.
+    ((#x15 . #x02) "CLI_TOICQSRV"       nil) 
+    ((#x15 . #x03) "SRV_FROMICQSRV"     emchat-v8-snac-srv-fromicqsrv)
+    ;; Family 17 [23], Authorisation/Registration
+    ((#x17 . #x01) "SRV_REGREFUSED"     emchat-v8-snac-srv-regrefused)
+    ((#x17 . #x05) "SRV_NEWUIN"         emchat-v8-snac-srv-newuin)
+    ((#x17 . #x04) "CLI_REGISTERUSER"   nil)
+
+    ((0 . 0)    "unknown"            nil))
+  "List of SNAC specs.")
+
+(defun emchat-v8-recv-message (ectx h-type data)
+  "Receive message."
+  (let* ((uin (emchat-v8-fetch-uin data))
+        (msg (emchat-v8-parse-message data
+               (list [2 number-swap]   ;year
+                     [1 number]        ;month
+                     [1 number]        ;day
+                     [1 number]        ;hour
+                     [1 number]        ;minutes
+                     )))
+        (tmsg (emchat-v8-parse-message data
+                (list [2 number-swap]
+                      [2 number])))
+        (ctext (substring (aref data 0) 0 (1- (length (aref data 0)))))
+        (time-stamp (list (truncate (nth 0 msg))
+                          (truncate (nth 1 msg))
+                          (truncate (nth 2 msg))
+                          (truncate (nth 3 msg))
+                          (truncate (nth 4 msg)))))
+
+    (emchat-v8-debug "Recv-message: '%S', tmsg='%S'" ctext tmsg)
+    
+    ;; XXX 'normal
+    (emchat-v8-ctx-run-incoming-handler ectx h-type
+      :uin uin :msg ctext :msg-type 'normal :time-stamp time-stamp)))
+
+(defmacro emchat-v8-get-alist-value (code alist)
+  `(cdr (assq ,code ,alist)))
+
+(defconst emchat-v8-countries-alist
+  '((0 . "Undefined")
+    (1 . "USA")
+    (101 . "Anguilla")
+    (102 . "Antigua")
+    (1021 . "Antigua & Barbuda")
+    (103 . "Bahamas")
+    (104 . "Barbados")
+    (105 . "Bermuda")
+    (106 . "British Virgin Islands")
+    (107 . "Canada")
+    (108 . "Cayman Islands")
+    (109 . "Dominica")
+    (110 . "Dominican Republic")
+    (111 . "Grenada")
+    (112 . "Jamaica")
+    (113 . "Montserrat")
+    (114 . "Nevis")
+    (1141 . "Saint Kitts and Nevis")
+    (115 . "St. Kitts")
+    (116 . "St. Vincent & the Grenadines")
+    (117 . "Trinidad & Tobago")
+    (118 . "Turks & Caicos Islands")
+    (120 . "Barbuda")
+    (121 . "Puerto Rico")
+    (122 . "Saint Lucia")
+    (123 . "Virgin Islands (USA)")
+    (178 . "Canary Islands")
+    (20 . "Egypt")
+    (212 . "Morocco")
+    (213 . "Algeria")
+    (216 . "Tunisia")
+    (218 . "Libyan Arab Jamahiriya")
+    (220 . "Gambia")
+    (221 . "Senegal")
+    (222 . "Mauritania")
+    (223 . "Mali")
+    (224 . "Guinea")
+    (225 . "Cote d'Ivoire")
+    (226 . "Burkina Faso")
+    (227 . "Niger")
+    (228 . "Togo")
+    (229 . "Benin")
+    (230 . "Mauritius")
+    (231 . "Liberia")
+    (232 . "Sierra Leone")
+    (233 . "Ghana")
+    (234 . "Nigeria")
+    (235 . "Chad")
+    (236 . "Central African Republic")
+    (237 . "Cameroon")
+    (238 . "Cape Verde Islands")
+    (239 . "Sao Tome & Principe")
+    (240 . "Equatorial Guinea")
+    (241 . "Gabon")
+    (242 . "Congo, (Rep. of the)")
+    (243 . "Congo, Democratic Republic of")
+    (244 . "Angola")
+    (245 . "Guinea-Bissau")
+    (246 . "Diego Garcia")
+    (247 . "Ascension Island")
+    (248 . "Seychelles")
+    (249 . "Sudan")
+    (250 . "Rwanda")
+    (251 . "Ethiopia")
+    (252 . "Somalia")
+    (253 . "Djibouti")
+    (254 . "Kenya")
+    (255 . "Tanzania")
+    (256 . "Uganda")
+    (257 . "Burundi")
+    (258 . "Mozambique")
+    (260 . "Zambia")
+    (261 . "Madagascar")
+    (262 . "Reunion Island")
+    (263 . "Zimbabwe")
+    (264 . "Namibia")
+    (265 . "Malawi")
+    (266 . "Lesotho")
+    (267 . "Botswana")
+    (268 . "Swaziland")
+    (269 . "Mayotte Island")
+    (2691 . "Comoros")
+    (27 . "South Africa")
+    (290 . "St. Helena")
+    (291 . "Eritrea")
+    (297 . "Aruba")
+    (298 . "Faeroe Islands")
+    (299 . "Greenland")
+    (30 . "Greece")
+    (31 . "Netherlands")
+    (32 . "Belgium")
+    (33 . "France")
+    (34 . "Spain")
+    (350 . "Gibraltar")
+    (351 . "Portugal")
+    (352 . "Luxembourg")
+    (353 . "Ireland")
+    (354 . "Iceland")
+    (355 . "Albania")
+    (356 . "Malta")
+    (357 . "Cyprus")
+    (358 . "Finland")
+    (359 . "Bulgaria")
+    (36 . "Hungary")
+    (370 . "Lithuania")
+    (371 . "Latvia")
+    (372 . "Estonia")
+    (373 . "Moldova, Republic of")
+    (374 . "Armenia")
+    (375 . "Belarus")
+    (376 . "Andorra")
+    (377 . "Monaco")
+    (378 . "San Marino")
+    (379 . "Vatican City")
+    (380 . "Ukraine")
+    (381 . "Yugoslavia")
+    (3811 . "Yugoslavia - Serbia")
+    (382 . "Yugoslavia - Montenegro")
+    (385 . "Croatia")
+    (386 . "Slovenia")
+    (387 . "Bosnia & Herzegovina")
+    (389 . "Macedonia (F.Y.R.O.M.)")
+    (39 . "Italy")
+    (40 . "Romania")
+    (41 . "Switzerland")
+    (4101 . "Liechtenstein")
+    (42 . "Czech Republic")
+    (4201 . "Slovakia")
+    (43 . "Austria")
+    (44 . "United Kingdom")
+    (441 . "Wales")
+    (442 . "Scotland")
+    (45 . "Denmark")
+    (46 . "Sweden")
+    (47 . "Norway")
+    (48 . "Poland")
+    (49 . "Germany")
+    (500 . "Falkland Islands")
+    (501 . "Belize")
+    (502 . "Guatemala")
+    (503 . "El Salvador")
+    (504 . "Honduras")
+    (505 . "Nicaragua")
+    (506 . "Costa Rica")
+    (507 . "Panama")
+    (508 . "St. Pierre & Miquelon")
+    (509 . "Haiti")
+    (51 . "Peru")
+    (52 . "Mexico")
+    (53 . "Cuba")
+    (54 . "Argentina")
+    (55 . "Brazil")
+    (56 . "Chile, Republic of")
+    (57 . "Colombia")
+    (58 . "Venezuela")
+    (590 . "Guadeloupe")
+    (5901 . "French Antilles")
+    (5902 . "Antilles")
+    (591 . "Bolivia")
+    (592 . "Guyana")
+    (593 . "Ecuador")
+    (594 . "French Guyana")
+    (595 . "Paraguay")
+    (596 . "Martinique")
+    (597 . "Suriname")
+    (598 . "Uruguay")
+    (599 . "Netherlands Antilles")
+    (60 . "Malaysia")
+    (61 . "Australia")
+    (6101 . "Cocos-Keeling Islands")
+    (6102 . "Cocos (Keeling) Islands")
+    (62 . "Indonesia")
+    (63 . "Philippines")
+    (64 . "New Zealand")
+    (65 . "Singapore")
+    (66 . "Thailand")
+    (670 . "Saipan Island")
+    (6701 . "Rota Island")
+    (6702 . "Tinian Island")
+    (671 . "Guam, US Territory of")
+    (672 . "Christmas Island")
+    (6722 . "Norfolk Island")
+    (673 . "Brunei")
+    (674 . "Nauru")
+    (675 . "Papua New Guinea")
+    (676 . "Tonga")
+    (677 . "Solomon Islands")
+    (678 . "Vanuatu")
+    (679 . "Fiji")
+    (680 . "Palau")
+    (681 . "Wallis & Futuna Islands")
+    (682 . "Cook Islands")
+    (683 . "Niue")
+    (684 . "American Samoa")
+    (685 . "Western Samoa")
+    (686 . "Kiribati")
+    (687 . "New Caledonia")
+    (688 . "Tuvalu")
+    (689 . "French Polynesia")
+    (690 . "Tokelau")
+    (691 . "Micronesia, Federated States of")
+    (692 . "Marshall Islands")
+    (7 . "Russia")
+    (705 . "Kazakhstan")
+    (706 . "Kyrgyzstan")
+    (708 . "Tajikistan")
+    (709 . "Turkmenistan")
+    (711 . "Uzbekistan")
+    (81 . "Japan")
+    (82 . "Korea, South")
+    (84 . "Viet Nam")
+    (850 . "Korea, North")
+    (852 . "Hong Kong")
+    (853 . "Macau")
+    (855 . "Cambodia")
+    (856 . "Laos")
+    (86 . "China")
+    (880 . "Bangladesh")
+    (886 . "Taiwan")
+    (90 . "Turkey")
+    (91 . "India")
+    (92 . "Pakistan")
+    (93 . "Afghanistan")
+    (94 . "Sri Lanka")
+    (95 . "Myanmar")
+    (960 . "Maldives")
+    (961 . "Lebanon")
+    (962 . "Jordan")
+    (963 . "Syrian Arab Republic")
+    (964 . "Iraq")
+    (965 . "Kuwait")
+    (966 . "Saudi Arabia")
+    (967 . "Yemen")
+    (968 . "Oman")
+    (971 . "United Arabian Emirates")
+    (972 . "Israel")
+    (973 . "Bahrain")
+    (974 . "Qatar")
+    (975 . "Bhutan")
+    (976 . "Mongolia")
+    (977 . "Nepal")
+    (98 . "Iran (Islamic Republic of)")
+    (994 . "Azerbaijan")
+    (995 . "Georgia")
+    (9999 . "other")))
+
+(defmacro emchat-v8-get-country (code)
+  "Return country name according to country CODE."
+  `(emchat-v8-get-alist-value ,code emchat-v8-countries-alist))
+
+(defconst emchat-v8-gender-alist
+   '((0 . "unspecified")
+     (1 . "female")
+     (2 . "male")))
+
+(defmacro emchat-v8-get-gender (code)
+  "Return gender name according to specified gender CODE."
+  `(emchat-v8-get-alist-value ,code emchat-v8-gender-alist))
+
+(defconst emchat-v8-languages-alist
+  '((0 . "not specified")
+    (1 . "Arabic")
+    (2 . "Bhojpuri")
+    (3 . "Bulgarian")
+    (4 . "Burmese")
+    (5 . "Cantonese")
+    (6 . "Catalan")
+    (7 . "Chinese")
+    (8 . "Croatian")
+    (9 . "Czech")
+    (10 . "Danish")
+    (11 . "Dutch")
+    (12 . "English")
+    (13 . "Esperanto")
+    (14 . "Estonian")
+    (15 . "Farsi")
+    (16 . "Finnish")
+    (17 . "French")
+    (18 . "Gaelic")
+    (19 . "German")
+    (20 . "Greek")
+    (21 . "Hebrew")
+    (22 . "Hindi")
+    (23 . "Hungarian")
+    (24 . "Icelandic")
+    (25 . "Indonesian")
+    (26 . "Italian")
+    (27 . "Japanese")
+    (28 . "Khmer")
+    (29 . "Korean")
+    (30 . "Lao")
+    (31 . "Latvian")
+    (32 . "Lithuanian")
+    (33 . "Malay")
+    (34 . "Norwegian")
+    (35 . "Polish")
+    (36 . "Portuguese")
+    (37 . "Romanian")
+    (38 . "Russian")
+    (39 . "Serbian")
+    (40 . "Slovak")
+    (41 . "Slovenian")
+    (42 . "Somali")
+    (43 . "Spanish")
+    (44 . "Swahili")
+    (45 . "Swedish")
+    (46 . "Tagalog")
+    (47 . "Tatar")
+    (48 . "Thau")
+    (49 . "Turkish")
+    (50 . "Ukarinian")
+    (51 . "Urdu")
+    (52 . "Vietnamese")
+    (53 . "Yiddish")
+    (54 . "Yoruba")
+    (55 . "Afriaans")
+    (56 . "Bosnian")
+    (57 . "Persian")
+    (58 . "Albanian")
+    (59 . "Armenian")
+    (60 . "Punjabi")
+    (61 . "Chamorro")
+    (62 . "Mongolian")
+    (63 . "Mandarin")
+    (64 . "Taiwanese")
+    (65 . "Macedonian")
+    (66 . "Sindhi")
+    (67 . "Welsh")
+    (68 . "Azerbaijani")
+    (69 . "Kurdish")
+    (70 . "Gujarati")
+    (71 . "Tamil")
+    (72 . "Belorussian")
+    (255 . "other")))
+
+(defmacro emchat-v8-get-language (code)
+  "Return language name according to language CODE."
+  `(emchat-v8-get-alist-value ,code emchat-v8-languages-alist))
+
+(defconst emchat-v8-marital-alist
+  '((0 . "not specified")
+    (10 . "single")
+    (11 . "in a long-term relationship")
+    (12 . "engaged")
+    (20 . "married")
+    (30 . "divorced")
+    (31 . "separated")
+    (40 . "widowed")))
+
+(defmacro emchat-v8-get-marital (code)
+  "Return marital name according to marital CODE."
+  `(emchat-v8-get-alist-value ,code emchat-v8-marital-alist))
+
+;;;; SRV
+
+;;; Family #x13 (SSI - Server Side Info)
+
+;;; FIXME: This should most likely be used to set some max values in
+;;; EMchat, but I'm not that concerned seeing as though max contacts
+;;; is 3000.
+(defun emchat-v8-snac-srv-ssi-rights-reply (ectx data &optional flags)
+  "SRV_SSI_RIGHTS_REPLY, SNAC(#x13, #x03)."
+  (let* ((tlvs (emchat-v8-fetch-tlvs data))
+        (limits (emchat-v8-tlv-val (emchat-v8-tlv-get tlvs 4)))
+        (mconts (emchat-v8-fetch-word limits))  ; max contacts
+        (mgrps (emchat-v8-fetch-word limits))   ; max groups
+        (mvconts (emchat-v8-fetch-word limits)) ; max visible contacts
+        (miconts (emchat-v8-fetch-word limits)) ; max invisible contacts
+        (mvibit (emchat-v8-fetch-word limits))  ; max vis/invis bitmasks
+        (mpres (emchat-v8-fetch-word limits))   ; max presence info fields
+        (mignores                               ; max ignore entries
+         (progn
+           (dotimes (i 8)
+             (emchat-v8-fetch-word limits))
+           (emchat-v8-fetch-word limits)))
+        ;; rest of the thing is ignored for now (unknown stuff)
+        )
+    ;; not sure what to do with this yet, lets just log it for now
+    (emchat-v8-debug "SRV_SSI_RIGHTS_REPLY: Max number of...
+Contacts=%d
+Groups=%d
+Visible Contacts=%d
+Invisible Contacts=%d
+Vis/Invis Bitmasks=%d
+Presense Info Fields=%d
+Ignore List Entries=%d"
+                    mconts mgrps mvconts miconts mvibit mpres mignores)))
+
+(defvar emchat-v8-ssi-count nil
+  "A place to store SSI entry count when it spans multiple packets.")
+
+;;; FIXME: handle BARTs
+(defun emchat-v8-snac-srv-ssi-reply (ectx data &optional flags)
+  "SRV_SSI_REPLY, SNAC(#x13, #x06)."
+  (let* ((count (progn
+                  (emchat-v8-fetch-byte data) ; skip, just a version number
+                  (emchat-v8-fetch-word data)))
+         lastupd)
+    (push count emchat-v8-ssi-count)
+    (dotimes (i count)
+      (let* ((name (emchat-v8-fetch-bstr data))
+             (group (emchat-v8-fetch-word data))
+             (id (emchat-v8-fetch-word data))
+             (type (emchat-v8-fetch-word data))
+             (tlvs-len (emchat-v8-fetch-word data))
+             (tlvs (emchat-v8-fetch-n-tlvs data tlvs-len))
+            ttype tlen tval)
+       (while tlvs
+         (setq ttype (emchat-v8-tlv-type (car tlvs)))
+         (setq tlen (emchat-v8-tlv-len (car tlvs)))
+         (setq tval (emchat-v8-tlv-val (car tlvs)))
+         (when (and (eq ttype #x131) (not (eq type #x14)))
+           (emchat-world-sync-ssi-maybe name group id tval))
+         (emchat-v8-debug "SSI_REPLY_TLV:
+name=%S group=%S id=%S type=%S
+ttype=%S tlength=%S tvalue=%S"
+                          name group id type ttype tlen tval)
+         (setq tlvs (cdr tlvs)))))
+    (with-current-buffer (find-file-noselect emchat-world-rc-filename)
+      (when (buffer-modified-p)
+       (save-buffer)))
+    (when (zerop (logand flags 1))
+      (when (> (length emchat-v8-ssi-count) 1)
+       (setq count (apply #'+ emchat-v8-ssi-count)))
+      (setq emchat-v8-ssi-count nil)
+      (setq lastupd (emchat-v8-fetch-time data))
+      (emchat-world-update-world-count count lastupd)
+      (emchat-v8-debug "SSI_REPLY: count=%S lastupd=%S" count lastupd))))
+
+(defun emchat-v8-snac-srv-ssi-mod-ack (ectx data &optional flags)
+  "Server ack for buddy add/del/mod.  SNAC(#x13, #x0E)."
+  (let ((retcodes '((#x0000 . "Success")
+                   (#x0002 . "Item not found")
+                   (#x0003 . "Item already exists")
+                   (#x000A . "Invalid data")
+                   (#x000C . "Limit exceeded")
+                   (#x000D . "Can't add ICQ contact to AIM list")
+                   (#x000E . "Authorisation required"))))
+    (setq emchat-add-user-success nil)
+    (while data
+      (let* ((code (emchat-v8-fetch-word data))
+            (retstr (cdr (assq code retcodes))))
+       (emchat-v8-debug "SRV_SSI_MOD_ACK: %s" retstr)
+       (if (zerop code)
+           (emchat-v8-ctx-run-incoming-handler 'ectx 'new-user)
+         (emchat-log-error "SSI Modifications Error: %s" retstr))))))
+
+(defun emchat-v8-snac-srv-ssi-up-to-date (ectx data &optional flags)
+  "Local copy of SSI is up to date.  SNAC(#x13, #x0F).
+
+This doesn't actually do anything because there isn't any point.  It
+sends back the mod time and item count, but you only get this packet
+if your local SSI has the same mod time and item count."
+  (emchat-log-info "Local copy of SSI is up to date!")
+  (emchat-v8-debug "SRV_SSI_UP_TO_DATE: local SSI is up to date."))
+  
+
+(defun emchat-v8-snac-srv-ssi-auth-reply (ectx data &optional flags)
+  "SRV_SSI_AUTH_REPLY, SNAC (#x13 . #x1B)"
+  (let ((buin (emchat-v8-fetch-buin data))
+       (accept (emchat-v8-fetch-byte data))
+       (reason (emchat-v8-fetch-bstr data)))
+    (emchat-v8-debug "AUTHREPLY: from %d %s" 
+                  buin 
+                  (if (zerop accept)
+                      "rejected"
+                    "accepted"))
+    (if (zerop accept)
+       (emchat-v8-ctx-run-incoming-handler ectx 'auth-reject
+         :uin buin :msg reason :msg-type 'auth-reject)
+      (emchat-v8-ctx-run-incoming-handler ectx 'auth-accept
+       :uin buin :msg reason :msg-type 'auth-accept))))
+
+(defun emchat-v8-snac-srv-ssi-you-were-added (ectx data &optional flags)
+  "SRV_ADDEDYOU, SNAC (#x13 . #x1C)"
+  (let ((buin (emchat-v8-fetch-buin data))
+       (msg "has added you to their contact list."))
+    (emchat-v8-debug "ADDEDYOU: by %d" buin)
+    (emchat-v8-ctx-run-incoming-handler ectx 'added-you
+       :uin buin :msg msg :msg-type 'added)))
+
+(defun emchat-v8-snac-srv-ssi-future-auth-granted (ectx data &optional flags)
+  "Future auth has been given.  SNAC(#x13, #x15)."
+  (let ((uin (emchat-v8-fetch-buin data))
+       (reason (emchat-v8-fetch-bstr data)))
+    (emchat-v8-debug "SRV_SSI_FUTURE_AUTH_GRANTED: %s grants auth because: %s"
+                    uin reason)
+    (emchat-v8-ctx-run-incoming-handler ectx 'auth-accept
+      :uin uin :msg reason :msg-type 'auth-accept)))
+
+(defun emchat-v8-snac-srv-ssi-auth-request (ectx data &optional flags)
+  "SRV_SSI_AUTH_REQUEST, SNAC (#x13 . #x19)"
+  (let ((buin (emchat-v8-fetch-buin data))
+       (reason (emchat-v8-fetch-bstr data)))
+    (emchat-v8-debug "AUTHREQ: from %d Reason: %S" buin reason)
+    (emchat-v8-ctx-run-incoming-handler ectx 'auth-request
+      :uin buin :msg reason :msg-type 'auth-request)))
+
+;;; Family #x15 (Old ICQ)
+
+;;; FIXME: complete this, a fair bit is still missing.  Might need
+;;; splitting up into several functions
+(defun emchat-v8-snac-srv-fromicqsrv (ectx data &optional flags)
+  "SRV_FROMICQSRV, SNAC(#x15, #x03)"
+  (let* ((tlv1 (emchat-v8-tlv-val (emchat-v8-fetch-single-tlv data)))
+        (len (emchat-v8-fetch-word-le tlv1))
+        (my-uin (emchat-v8-fetch-uin tlv1))
+        (type (emchat-v8-fetch-word-le tlv1))
+         (seq (emchat-v8-fetch-word-le tlv1))
+         (his-uin (cdr (assq seq (emchat-v8-ctx-get-prop ectx 'about-query-seq-uin)))))
+    ;; Shutup compiler
+    (setq len len my-uin my-uin)
+
+    (emchat-v8-debug "FROMICQSRV: UIN: %S, Type=%d, seq=%d, tlv1=%S, data=%S"
+                   his-uin type seq tlv1 data)
+
+    (cond ((= type 65)
+          (emchat-v8-recv-message ectx 'offline-message tlv1))
+
+         ((= type 66)
+          ;; Ack end of offline messages
+          (emchat-v8-send ectx
+             (emchat-v8-pack-meta-snac ectx 62))
+          (emchat-v8-ctx-run-incoming-handler ectx 'end-offline-messages))
+
+          ((= type 2010)
+           (let ((subtype (emchat-v8-fetch-word-le tlv1))
+                 (result (emchat-v8-fetch-byte tlv1)))
+             (emchat-v8-debug "SRV_META: Subtype=%d, result=%d, tlv1=%S" subtype result tlv1)
+
+             (when (= result 10)
+               (cond ((= subtype 200)
+                      ;; -- Start --
+                      ;; GENERAL
+                      (let ((nick (emchat-v8-fetch-lnts tlv1))
+                            (fname (emchat-v8-fetch-lnts tlv1))
+                            (sname (emchat-v8-fetch-lnts tlv1))
+                            (email (emchat-v8-fetch-lnts tlv1))
+                            (city (emchat-v8-fetch-lnts tlv1))
+                            (state (emchat-v8-fetch-lnts tlv1))
+                            (phone (emchat-v8-fetch-lnts tlv1))
+                            (fax (emchat-v8-fetch-lnts tlv1))
+                            (street (emchat-v8-fetch-lnts tlv1))
+                            (cellular (emchat-v8-fetch-lnts tlv1))
+                            (zip (emchat-v8-fetch-lnts tlv1))
+                            (country (emchat-v8-get-country
+                                      (emchat-v8-fetch-word-le tlv1)))
+                            ;; The timezone the user lives in, as
+                            ;; multiples of 30minutes relative to UTC.
+                            (tz (emchat-v8-fetch-byte tlv1))
+                            (flags (emchat-v8-fetch-byte tlv1))
+                            (web-ind (= (emchat-v8-fetch-word-le tlv1) 1)))
+
+                        (emchat-v8-debug "GENERAL-Info: UIN: %d, Nick: %s"
+                                       his-uin nick)
+
+                        (emchat-v8-ctx-run-incoming-handler ectx 'about-general
+                          :uin his-uin
+                          :nick nick :first-name fname :second-name sname
+                          :email email :city city :state state :phone phone
+                          :fax fax :street street :cellular cellular
+                          :zip-code zip :country country :tz tz
+                          :flags flags :web-indicator web-ind)))
+
+                     ((= subtype 210)
+                      ;; WORK
+                      ;; Hey!  Does anybody actually care about this? --lg
+                      )
+                     ((= subtype 220)
+                      ;; MORE
+                      (let ((age (emchat-v8-fetch-word-le tlv1))
+                            (gender (emchat-v8-get-gender
+                                     (emchat-v8-fetch-byte tlv1)))
+                            (homepage (emchat-v8-fetch-lnts tlv1))
+                            (birth-year (emchat-v8-fetch-word-le tlv1))
+                            (birth-month (emchat-v8-fetch-byte tlv1))
+                            (birth-day (emchat-v8-fetch-byte tlv1))
+                            (lang1 (emchat-v8-get-language
+                                    (emchat-v8-fetch-byte tlv1)))
+                            (lang2 (emchat-v8-get-language
+                                    (emchat-v8-fetch-byte tlv1)))
+                            (lang3 (emchat-v8-get-language
+                                    (emchat-v8-fetch-byte tlv1)))
+                            (ocity (progn
+                                     (emchat-v8-fetch-word-le tlv1) ; skip
+                                     (emchat-v8-fetch-lnts tlv1)))
+                            (ostate (emchat-v8-fetch-lnts tlv1))
+                            (ocountry (emchat-v8-get-country
+                                       (emchat-v8-fetch-word-le tlv1)))
+                            (marital (emchat-v8-get-marital
+                                      (emchat-v8-fetch-word-le tlv1))))
+                        (emchat-v8-ctx-run-incoming-handler ectx 'about-more
+                          :uin his-uin :age age :gender gender :homepage homepage
+                          :birth-year birth-year :birth-month birth-month
+                          :birth-day birth-day :lang1 lang1 :lang2 lang2
+                          :lang3 lang3 :ocity ocity :ostate ostate
+                          :ocountry ocountry :marital marital)))
+
+                     ((= subtype 235)
+                      ;; EMAILS
+                      )
+                     ((= subtype 270)
+                      ;; META270
+                      )
+                     ((= subtype 230)
+                      ;; ABOUT
+                      (let ((about-user (emchat-v8-fetch-lnts tlv1)))
+                        (emchat-v8-debug "USER ABOUT-Info: %S" about-user)
+                        (emchat-v8-ctx-run-incoming-handler ectx 'about-about
+                          :uin his-uin :about about-user)))
+
+                     ((= subtype 240)
+                      ;; INTEREST
+                      )
+                     ((= subtype 250)
+                      ;; BACKGROUND
+                      )
+
+                    ((= subtype 420)
+                     ;; Search found a user
+                      (let ((uin (progn (emchat-v8-fetch-word-le tlv1)
+                                        (emchat-v8-fetch-uin tlv1)))
+                            (nick (emchat-v8-fetch-lnts tlv1))
+                            (first-name (emchat-v8-fetch-lnts tlv1))
+                            (last-name (emchat-v8-fetch-lnts tlv1))
+                            (email (emchat-v8-fetch-lnts tlv1))
+                            (auth (emchat-v8-fetch-byte tlv1))
+                            (status (emchat-v8-fetch-word-le tlv1))
+                            (gender (emchat-v8-get-gender
+                                     (emchat-v8-fetch-byte tlv1)))
+                            (age (emchat-v8-fetch-word-le tlv1))
+                            (missed (emchat-v8-fetch-word-le tlv1)))
+                        (emchat-v8-debug "FOUND USER: UIN=%d, Nick=%s, missed=%d" uin nick missed)
+                        (emchat-v8-ctx-run-incoming-handler ectx 'search-found
+                          :uin uin :nick nick
+                          :first-name first-name :last-name last-name
+                          :email email :auth auth :status status :gender gender
+                          :age age :missed missed)))
+
+                     ((= subtype 430)
+                      ;; Search found a user (the last match from the search)
+                      (let ((uin (progn (emchat-v8-fetch-word-le tlv1)
+                                        (emchat-v8-fetch-uin tlv1)))
+                            (nick (emchat-v8-fetch-lnts tlv1))
+                            (first-name (emchat-v8-fetch-lnts tlv1))
+                            (last-name (emchat-v8-fetch-lnts tlv1))
+                            (email (emchat-v8-fetch-lnts tlv1))
+                            (auth (emchat-v8-fetch-byte tlv1))
+                            (status (emchat-v8-fetch-word-le tlv1))
+                            (gender (emchat-v8-get-gender
+                                     (emchat-v8-fetch-byte tlv1)))
+                            (age (emchat-v8-fetch-word-le tlv1))
+                            (missed (emchat-v8-fetch-word-le tlv1)))
+                        (emchat-v8-debug "FOUND USER: UIN=%d, Nick=%s, missed=%d" uin nick missed)
+                        (emchat-v8-ctx-run-incoming-handler ectx 'search-found-last
+                          :uin uin :nick nick
+                          :first-name first-name :last-name last-name
+                          :email email :auth auth :status status :gender gender
+                          :age age :missed missed)))
+                     )))))
+    ))
+
+(defun emchat-v8-snac-srv-toicqerr (ectx data &optional flags)
+  "SRV_TOICQERR, SNAC(0x15, 0x01)"
+  (let ((ecode (emchat-v8-fetch-word data))
+        (tlv1 (emchat-v8-fetch-single-tlv data)))
+    (error "Malformed TOICQ request" ecode tlv1)))
+        
+(defun emchat-v8-snac-srv-set-interval (ectx data &optional flags)
+  "SRV_SETINTERVAL, SNAC(0x0B, 0x02)"
+  (let ((ival (emchat-v8-fetch-word data)))
+    (emchat-v8-debug "User info interval: %S" ival)
+    (emchat-v8-ctx-put-prop ectx 'user-info-interval ival)))
+
+(defun emchat-v8-snac-srv-icbm-err (ectx data &optional flags)
+  "SRV_ICBMERR"
+  (let* ((ival (emchat-v8-fetch-word data))
+        (err (cond ((= ival 4) "User offline")
+                   ((= ival 9) "Client does not understand type-2 mesasges")
+                   ((= ival 14) "Packet was malformed")
+                   (t "Unknown"))))
+    (emchat-v8-debug "ICBMERR: %d/%s" ival err)))
+
+(defun emchat-v8-snac-srv-reply-icbm (ectx data &optional flags)
+  "SRV_REPLICBM, SNAC(#x04, #x05)"
+  )
+
+(defun emchat-v8-snac-srv-replyinfo (ectx data &optional flags)
+  "SRV_REPLYINFO, SNAC(1, f)"
+  ;; BUIN      xx ..                   UIN        The UIN this information is about.
+  ;; WORD.B    00 00                   WARNING    Probably a warning level left over from OSCAR.
+  ;; WORD.B    00 xx                   COUNT      Total number of TLVs to follow.
+  ;; TLV(1)    00 01 00 02 00 80       UNKNOWN    Unknown.
+  ;; TLV(12)   00 0c 00 25 ...         CLI2CLI    Direct connection info, see CLI_SETSTATUS SNAC(1,30).
+  ;; TLV(15)   00 0f 00 04 xx xx xx xx UNKNOWN    Number of seconds that user has been online?
+  ;; TLV(2)    00 02 00 04 TIME        MEMBERTIME The member since time.
+  ;; TLV(3)    00 03 00 04 TIME        ONLINETIME The online since time.
+  ;; TLV(5)    00 05 00 04 TIME        UNKNOWN    Some unknown time.
+  ;; TLV(6)    00 06 00 04 xx xx xx xx STATUS     The current online status.
+  ;; TLV(30)   00 1e 00 04 00 00 00 00 UNKNOWN    Unknown: empty.
+;  (let* ((uin (emchat-v8-fetch-buin data))
+;         (tlvs (progn
+;                 (emchat-v8-fetch-word data) ; skip (warning)
+;                 (emchat-v8-fetch-word data) ; skip (tlv count)
+;                 (emchat-v8-fetch-tlvs data)))
+;         (tlv12 (emchat-v8-tlv-get tlvs 12))) ;  CLI2CLI
+
+;    (emchat-v8-debug "SRV_REPLYINFO: UIN=%d tlv12=%S" uin tlv12)
+;    ))
+  )
+
+(defun emchat-v8-snac-srv-reply-buddy (ectx data &optional flags)
+  "SRV_REPLYBUDDY, SNAC(0x03, 0x03)"
+  (let* ((tlvs (emchat-v8-fetch-tlvs data))
+        (muaicl (emchat-v8-tlv-get tlvs 1)) ;maximum uins allowed in contact list
+        (mpchuu (emchat-v8-tlv-get tlvs 2))) ;maximum number of people that can have our uin in contact list
+    (when muaicl
+      (emchat-v8-ctx-put-prop ectx 'maximum-uins (emchat-v8-tlv-num muaicl)))
+    (when mpchuu
+      (emchat-v8-ctx-put-prop ectx 'maximum-people (emchat-v8-tlv-num mpchuu)))))
+
+(defun emchat-v8-snac-srv-user-online (ectx data &optional flags)
+  "SRV_USERONLINE, SNAC(0x03, 0x0B)."
+  (let* ((buin (emchat-v8-fetch-buin data))
+        (tlvs (progn
+                 (emchat-v8-fetch-data data 4) ; skip
+                (emchat-v8-fetch-tlvs data)))
+        (ts (emchat-v8-tlv-get tlvs 6))
+         ;; XXX use only last 2 bytes of status
+         (new-status (and ts (emchat-v8-find-status
+                              (progn
+                                (emchat-v8-fetch-word (emchat-v8-tlv-val ts))
+                                (emchat-v8-fetch-word (emchat-v8-tlv-val ts)))))))
+    (emchat-v8-debug "SRV_USERONLINE: uin=%d status=%S/%S"
+                  buin ts new-status)
+    (when new-status
+      (emchat-v8-ctx-run-incoming-handler ectx 'status-update
+        buin new-status))))
+
+(defun emchat-v8-snac-srv-user-offline (ectx data &optional flags)
+  "SRV_USEROFFLINE, SNAC(0x03, 0x0C)"
+  (let ((buin (emchat-v8-fetch-buin data)))
+    (emchat-v8-debug "SRV_USEROFFLINE: uin=%d" buin)
+    (emchat-v8-ctx-run-incoming-handler ectx 'status-update
+      buin 'offline)))
+
+(defun emchat-v8-snac-srv-reply-location (ectx data &optional flags)
+  "SRV_REPLYLOCATION, SNAC(0x02, 0x03)."
+  ;; TODO: -write me
+  (let* ((tlvs (emchat-v8-fetch-tlvs data))
+        (mcap (emchat-v8-tlv-get tlvs 2)))
+    (when mcap
+      ;; Set maximum capabilities
+      (emchat-v8-debug "max capabilities: %S" (emchat-v8-tlv-num mcap))
+      (emchat-v8-ctx-put-prop ectx 'maximum-capabilities (emchat-v8-tlv-num mcap)))))
+
+(defun emchat-v8-snac-srv-families (ectx data &optional flags)
+  "SRV_FAMILIES, SNAC(0x01, 0x03)."
+  (let (srv-families)
+    (while (> (length (aref data 0)) 0)
+      (setq srv-families
+            (cons (emchat-v8-fetch-word data) srv-families)))
+    (emchat-v8-ctx-put-prop ectx 'server-families srv-families))
+
+  (emchat-v8-debug "SRV-FAMILIES %S" (emchat-v8-ctx-get-prop ectx 'server-families))
+  (emchat-v8-snac-cli-families ectx))
+
+(defun emchat-v8-snac-srv-families2 (ectx data &optional flags)
+  "SRV_FAMILIES2, SNAC(0x01, 0x12)."
+  (emchat-v8-debug "SRV-FAMILIES2 %S" data)
+  )
+
+(defun emchat-v8-snac-bart-request (ectx data &optional flags)
+  "BART_REQUEST, SNAC(0x01, 0x21)."
+  (let* ((type (emchat-v8-fetch-word data))
+        (flag (emchat-v8-fetch-byte data))
+        (len_opaque (emchat-v8-fetch-byte data))
+        (opaque (emchat-v8-fetch-data data len_opaque)))
+    (emchat-v8-debug "[BART]...
+Type: %S
+Flag: %S
+len:  %S
+opaque: %S"
+                    type flag len_opaque opaque)))
+
+(defun emchat-v8-snac-srv-rates (ectx data &optional flags)
+  "SRV_RATES, SNAC(0x01, 0x07)."
+  (let ((nr (emchat-v8-parse-message
+            data
+            (list
+             [2 emchat-v8-length-1]
+             [emchat-v8-length-1
+              ([2 number]              ; Rate class ID
+               [4 number]              ; Window size
+               [4 number]              ; Clear level
+               [4 number]              ; Alert level
+               [4 number]              ; Limit level
+               [4 number]              ; Disconnect level
+               [4 number]              ; Current level
+               [4 number]              ; Max level
+               [4 number]              ; last time
+               [1 number])]            ; current state
+             [emchat-v8-length-1
+              ([2 number]              ; Rate class ID
+               [2 emchat-v8-length-2]  ; number of pairs in group
+               [emchat-v8-length-2 ([4 number])])]))))
+
+    (emchat-v8-debug "SRV_RATES: %S" nr)
+
+    ;; Send a reply
+    (when (cadr nr)
+      (emchat-v8-send ectx
+       (emchat-v8-pack-snac ectx '(#x01 . #x08)
+          (apply 'concat
+                 (mapcar 'emchat-v8-pack-word (mapcar 'car (nth 1 nr)))))))
+    ))
+
+(defun emchat-v8-snac-srv-rate-change (ectx data &optional flags)
+  "SRV_RATE_CHANGE, SNAC(#x01, #x0A)."
+  (let ((code (emchat-v8-fetch-word data))
+       (rateid (emchat-v8-fetch-word data))
+       (winsize (emchat-v8-fetch-dword data))
+       (clear (emchat-v8-fetch-dword data))
+       (alert (emchat-v8-fetch-dword data))
+       (limit (emchat-v8-fetch-dword data))
+       (discon (emchat-v8-fetch-dword data))
+       (currl (emchat-v8-fetch-dword data))
+       (max (emchat-v8-fetch-dword data))
+       (ltime (emchat-v8-fetch-dword data))
+       (currs (emchat-v8-fetch-byte data)))
+    (emchat-v8-debug
+     "[SRV_RATE_EXCEEDED]:
+    Message Code: %d
+   Rate Class ID: %d
+     Window Size: %d
+     Clear Level: %d
+     Alert Level: %d
+     Limit Level: %d
+Disconnect Level: %d
+   Current Level: %d
+       Max Level: %d
+       Last Time: %d
+   Current State: %d"
+     code rateid winsize clear alert limit discon currl max ltime currs)
+    (ecase code
+      (1 #'ignore)
+      (2 (emchat-log-info "You've reached the rate limit: %d
+Chill out, take a break, have a coffee." alert))
+      (3 (emchat-log-error "Rate limit passed: %d
+Hope you get to read this before you get disconnected" discon))
+      (4 #'ignore))))
+
+(defun emchat-v8-snac-srv-pause (ectx data &optional flags)
+  "SRV_SERVERPAUSE, SNAC(1, B)."
+  ;; Send CLI_ACKSERVERPAUSE snac
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x09 . #x02)
+      (apply 'concat (mapcar #'(lambda (fam)
+                                 (emchat-v8-pack-word (car fam)))
+                             emchat-v8-snacv-list))))
+  
+  ;; Mark ECTX as in pause, until SRV_MIGRATIONREQ is received
+  (setf (emchat-v8-ctx-pause-p ectx) t))
+
+(defun emchat-v8-snac-srv-migrate (ectx data &optional flags)
+  "SRV_MIGRATIONREQ, SNAC(1, 12)."
+  (let* ((tlvs (progn
+                 (emchat-v8-fetch-word data)
+                 (emchat-v8-fetch-tlvs data)))
+         (tlv5 (emchat-v8-tlv-get tlvs 5))
+         (tlv6 (emchat-v8-tlv-get tlvs 6)))
+
+    ;; Close current connection
+    (emchat-v8-close ectx)
+
+    (let* ((nsrv (split-string (emchat-v8-tlv-str tlv5) ":"))
+           (addr (nth 0 nsrv))
+           (port (string-to-int (nth 1 nsrv))))
+      (emchat-v8-debug "Migrating to new server: %s:%d" addr port)
+      ;; Store cookie and reconnect
+      (emchat-v8-ctx-put-prop ectx 'cli-cookie (emchat-v8-tlv-str tlv6))
+      (emchat-v8-connect ectx addr port))))
+
+(defun emchat-v8-snac-srv-motd (ectx data &optional flags)
+  "SRV_MOTD, SNAC(1, 13)."
+  (emchat-v8-debug "SRV_MOTD")
+
+  (emchat-v8-snac-cli-ratesrequest ectx)
+  (emchat-v8-snac-cli-reqinfo ectx)
+  
+  ;; TODO: roster
+  (emchat-v8-snac-cli-reqlocation ectx)
+  (emchat-v8-snac-cli-reqbuddy ectx)
+  (emchat-v8-snac-cli-reqicbm ectx)
+  (emchat-v8-snac-cli-reqbos ectx)
+
+  (emchat-v8-ctx-run-incoming-handler ectx 'connected))
+
+(defconst emchat-v8-msg-types
+  '((0 . automatic)                     ; An automatic message
+    (1 . normal)                        ; A plain normal message
+    (2 . chat-request)                  ; A chat request
+    (3 . file-transfer-request)         ; A file transfer request
+    (4 . url)                          ; An URL message. The message consists of the description and the url
+    (6 . auth-request)                 ; An authorization request
+    (7 . auth-reject)                  ; An authorization reject message
+    (8 .  auth-accept)                 ; An authorization accept message
+    (12 . added)                       ; You were added to the sender's contact list
+    (13 . web-pager)                    ; A message sent through www.icq.com's web pager
+    (14 . email-pager)                 ; A message sent through the email pager ([uin]@pager.icq.com)
+    (19 . contact-list)                        ; A contact list message
+    (26 . extended)                    ; An extended message. The packet will contain more data
+    (1000 . get-away)                  ; A message requesting the "away" auto message
+    (1001 . get-occ)                   ; A message requesting the "occupied" auto message
+    (1002 . get-na)                    ; A message requesting the "not available" auto message
+    (1003 . get-dnd)                   ; A message requesting the "do not disturb" auto message
+    (1004 . get-ffc)                   ; A message requesting the "free for chat" auto message
+    )
+  "List of message types.")
+
+(defconst emchat-v8-msg-mass-flag #x8000
+  "If set, message was sent to several recipients.")
+
+(defun emchat-v8-snac-srv-recv-msg (ectx data &optional flags)
+  "SRV_RECVMSG, SNAC(4, 7)."
+  (emchat-v8-debug "data here: %S" data)
+  (let ((midtime (emchat-v8-fetch-time data))
+       (midrand (emchat-v8-fetch-dword data))
+       (type (emchat-v8-fetch-word data))
+       (uin (emchat-v8-fetch-buin data))
+       (warn (emchat-v8-fetch-word data))
+       (count (emchat-v8-fetch-word data))
+       (tlvs (emchat-v8-fetch-tlvs data)))
+    
+    ;; Fetch tlvs
+    (emchat-v8-debug "Got message from %S, mt/mr/t/w/c=%S/%S/%S/%S/%S, tlvs=%S"
+                   uin midtime midrand type warn count tlvs)
+
+    (cond ((= type 1)
+          ;; Normal message
+          (let* ((tlvals (emchat-v8-fetch-tlvs
+                           (emchat-v8-tlv-val (emchat-v8-tlv-get tlvs 2))))
+                  (caps (emchat-v8-fetch-byte
+                         (emchat-v8-tlv-val (emchat-v8-tlv-get tlvals 1281))))
+                  (mtlval (emchat-v8-tlv-val
+                           (emchat-v8-tlv-get tlvals 257)))
+                  (menc (emchat-v8-fetch-word mtlval))
+                  (msg (progn
+                         (emchat-v8-fetch-word mtlval) ; skip
+                         (emchat-v8-fetch-string mtlval))))
+
+             (emchat-v8-debug "Normal message: caps/menc=%d/%d, msg='%s'"
+                            caps menc msg)
+             (emchat-v8-ctx-run-incoming-handler ectx 'instant-message
+               :uin uin :msg msg :msg-type 'normal)))
+
+         ((= type 2)
+          ;; Advanced message
+          ;; TODO: -write me
+          (emchat-v8-debug "MSG[%d]: here" type))
+
+         ((= type 4)
+           ;; Server message
+           (let* ((tlv5 (emchat-v8-tlv-val (emchat-v8-tlv-get (nreverse tlvs) 5)))
+                  (uin (truncate (emchat-v8-fetch-uin tlv5)))
+                  (mtype (emchat-v8-fetch-word-le tlv5))
+                  (msg (emchat-v8-fetch-lnts tlv5))
+                  msg-type)
+             ;; Adjust MTYPE to remove flag fields (MSGF_MASS)
+             (setq mtype (logand mtype (lognot emchat-v8-msg-mass-flag)))
+             (setq msg-type (cdr (assoc mtype emchat-v8-msg-types)))
+
+             (emchat-v8-ctx-run-incoming-handler ectx 'instant-message
+                 :uin uin :msg msg :msg-type msg-type)))
+
+         (t (error "Unknown message type")))))
+
+(defun emchat-v8-snac-srv-missed-icbm (ectx data &optional flags)
+  "SRV_MISSED_ICBM, SNAC(4, 10)."
+  (let* ((buin (progn
+                 (emchat-v8-fetch-word data) ; skip channel
+                 (emchat-v8-fetch-buin data)))
+         (mmsgs (progn
+                  (emchat-v8-fetch-word data) ; skip warn
+                  (dotimes (n (emchat-v8-fetch-word data)) ; skip tlvs
+                    (emchat-v8-fetch-single-tlv data))
+                  (emchat-v8-fetch-word data)))
+         (rn (emchat-v8-fetch-word data))
+         (reasons '((0 . "Invalid message")
+                    (1 . "Message too large")
+                    (2 . "Message rate limit exceeded")
+                    (3 . "Sender too evil (sender warn level > your max_msg_sevil)")
+                    (4 . "You are too evil (sender max_msg_revil > your warn level)")))
+         (reason (or (cdr (assq rn reasons)) "Unknown reason")))
+    (emchat-v8-ctx-run-incoming-handler ectx 'missed-message
+      :uin buin :missed-messages mmsgs :reason reason)))
+
+(defun emchat-v8-snac-srv-contact-err (ectx data &optional flags)
+  "SRV_CONTACTERR, SNAC(3, #x01)."
+  (let* ((ercode (emchat-v8-fetch-word data))
+        (errmsg (cond ((= ercode #x0E) "Empty UIN list sent")
+                      ((= ercode #x14) "Non existant UIN")
+                      ((= ercode #x15) "Contact list full"))))
+    (emchat-v8-debug "[SRV_CONTACTERR]: Code=%d (0x%1$02X), Msg=%s" ercode errmsg)
+    (emchat-v8-ctx-run-incoming-handler ectx 'srv-contacterr :reason errmsg)))
+
+(defun emchat-v8-snac-srv-err (ectx data &optional flags)
+  "SRV_GEN_ERR, SNAC(1, #x01)."
+  (let* ((ercode (emchat-v8-fetch-word data))
+         (errmsg (cond ((= ercode #x01) "Invalid SNAC header.")
+                       ((= ercode #x02) "Server rate limit exceeded")
+                       ((= ercode #x03) "Client rate limit exceeded")
+                       ((= ercode #x04) "Recipient is not logged in")
+                       ((= ercode #x05) "Requested service unavailable")
+                       ((= ercode #x06) "Requested service not defined")
+                       ((= ercode #x07) "You sent obsolete SNAC")
+                       ((= ercode #x08) "Not supported by server")
+                       ((= ercode #x09) "Not supported by client")
+                       ((= ercode #x0A) "Refused by client")
+                       ((= ercode #x0B) "Reply too big")
+                       ((= ercode #x0C) "Responses lost")
+                       ((= ercode #x0D) "Request denied")
+                       ((= ercode #x0E) "Incorrect SNAC format")
+                       ((= ercode #x0F) "Insufficient rights")
+                       ((= ercode #x10) "In local permit/deny (recipient blocked)")
+                       ((= ercode #x11) "Sender too evil")
+                       ((= ercode #x12) "Receiver too evil")
+                       ((= ercode #x13) "User temporarily unavailable")
+                       ((= ercode #x14) "No match")
+                       ((= ercode #x15) "List overflow")
+                       ((= ercode #x16) "Request ambiguous")
+                       ((= ercode #x17) "Server queue full")
+                       ((= ercode #x18) "Not while on AOL")
+                       (t "Unknown error"))))
+    (emchat-v8-debug "SRV_GEN_ERR: %s" errmsg)
+    (emchat-v8-ctx-run-incoming-handler ectx 'srv-error :reason errmsg)))
+
+(defun emchat-v8-snac-srv-reply-bos (ectx data &optional flags)
+  "SRV_REPLYBOS, SNAC(9, 3)."
+  (emchat-v8-snac-cli-setuserinfo ectx)
+  (emchat-v8-snac-cli-setstatus
+   ectx (emchat-v8-ctx-get-prop ectx 'initial-status))
+  (emchat-v8-snac-cli-ready ectx)
+  ;; This is the now unsupported local-only type of contact list.
+  ;; (emchat-v8-snac-cli-add-contact ectx)
+  (emchat-v8-snac-cli-reqofflinemsgs ectx))
+
+(defun emchat-v8-snac-srv-srv-ack-msg (ectx data &optional flags)
+  "SRV_SRVACKMSG, SNAC (4 . #x0C)"
+  (let ((type (progn
+                (emchat-v8-fetch-data data 8) ; skip
+                (emchat-v8-fetch-word data)))
+       (buin (emchat-v8-fetch-buin data)))
+    (emchat-v8-debug "SRVACKMSG: type=%d uin=%d" type buin)
+    ))
+
+;;;; CLI
+
+;;; Family #x13 (SSI -- Server Side Info)
+
+(defun emchat-v8-snac-cli-ssi-right-request (ectx)
+  "Request rights/limitations for SSI. SNAC(#x13, #x02)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x13 . #x02))))
+
+(defun emchat-v8-snac-cli-ssi-request (ectx)
+  "Request server side info.  SNAC(#x13, #x04)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x13 . #x04))))
+
+(defun emchat-v8-snac-cli-ssi-checkout (ectx)
+  "Checkout SSI list if local copy is out of date.  SNAC(#x13, #x05)."
+  (let ((num (emchat-world-ssi-count))
+       (modt (emchat-world-ssi-mod-time)))
+    (emchat-v8-send ectx
+      (emchat-v8-pack-snac ectx '(#x13 . #x05)
+       (emchat-v8-pack-time modt)
+       (emchat-v8-pack-word num)))))
+
+(defun emchat-v8-snac-cli-ssi-activate (ectx)
+  "Activate SSI.  SNAC(#x13, #x07)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x13 . #x07))))
+
+;;; FIXME:  This isn't working.
+(defun emchat-v8-snac-cli-ssi-add (ectx uin grp id nick)
+  "Add contacts to SSI.  SNAC(#x13, #x08)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x13 . #x08)
+      (emchat-v8-pack-bstr uin)
+      (emchat-v8-pack-word grp)
+      (emchat-v8-pack-word id)
+      (emchat-v8-pack-word #x0000)
+      (emchat-v8-pack-tlv #x0131 nick))))
+
+;;; FIXME: Write me
+(defalias 'emchat-v8-snac-cli-ssi-update #'ignore)
+;; (defun emchat-v8-snac-cli-ssi-update (ectx &rest entries)
+;;   "Update existing SSI entries.  SNAC(#x13, #x09)."
+;;   (emchat-v8-debug "CLI_SSI_UPDATE: somebody impliment me"))
+
+;;; FIXME: Write me
+(defalias 'emchat-v8-snac-cli-ssi-delete #'ignore)
+;; (defun emchat-v8-snac-cli-ssi-delete (ectx &rest entries)
+;;   "Delete existing SSI entries.  SNAC(#x13, #x0A)."
+;;   (emchat-v8-debug "CLI_SSI_DELETE: somebody impliment me"))
+(defalias 'emchat-v8-snac-cli-ssi-edit-begin #'ignore)
+;; (defun emchat-v8-snac-cli-ssi-edit-begin (ectx &rest args)
+;;   "Begin SSI edits.  SNAC(#x13, #x11)."
+;;   (emchat-v8-send ectx
+;;     (emchat-v8-pack-snac ectx '(#x13 . #x11))))
+(defalias 'emchat-v8-snac-cli-ssi-edit-end #'ignore)
+;; (defun emchat-v8-snac-cli-ssi-edit-end (ectx &rest args)
+;;   "End SSI edits.  SNAC(#x13, #x12)."
+;;   (emchat-v8-send ectx
+;;     (emchat-v8-pack-snac ectx '(#x13 . #x12))))
+
+(defun emchat-v8-snac-cli-ssi-future-auth-grant (ectx uin reason)
+  "Give future auth grant.  SNAC(#x13, #x14)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x13 . #x14)
+      (emchat-v8-pack-byte (length (number-to-string uin)))
+      (emchat-v8-pack-buin uin)
+      (emchat-v8-pack-dword 0))))
+
+(defun emchat-v8-snac-cli-ssi-del-yourself (ectx uin)
+  "Delete yourself from someone's contact list.  SNAC(#x13, #x16)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x13 . #x16)
+      (emchat-v8-pack-buin uin))))
+
+(defun emchat-v8-snac-cli-ssi-send-auth-request (ectx uin msg)
+  "Send auth request.  SNAC(#x13, #x18)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x13 . #x18)
+      (emchat-v8-pack-buin uin)
+      (emchat-v8-pack-bstr msg))))
+
+(defun emchat-v8-snac-cli-ssi-auth-reply (ectx uin reply &optional reason)
+  "Reply to auth-request.  SNAC(#x13, #x1A)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x13 . #x1A)
+      (emchat-v8-pack-buin uin)
+      (emchat-v8-pack-byte reply)
+      (emchat-v8-pack-bstr reason)
+      (emchat-v8-pack-word 0))))
+  
+
+(defun emchat-v8-snac-cli-setuserinfo (ectx)
+  "Send userinfo."
+  )
+
+(defconst emchat-v8-status-alist
+  `((offline . ,(* 256.0 256 256 256))
+    (invisible . #x100)                        ;user is invisible
+    (dnd . #x02)                       ;user does not want to be disturbed
+    (occupied . #x10)                  ;user is occupied
+    (na . #x04)                                ;user not available
+    (away . #x01)                      ;user is away
+    (ffc . #x20)                       ;user is free for chat
+    (online . #x00)                    ;user is online
+    (set-invisible . #x100)
+    (set-dnd . #x13)
+    (set-occupied . #x11)
+    (set-na . #x05)
+    (set-away . #x01)
+    (set-ffc . #x20)
+    (web-aware . #x010000)
+    (allow-ip . #x020000)
+    (birthday . #x80000)
+    (dcauth . #x10000000)
+    (dccontact . #x20000000))
+  "Alist of states.")
+
+(defun emchat-v8-find-status (num)
+  "Find statu by NUM."
+  (setq num (logand num #x0000ffff))
+  (let ((statuses (cdr emchat-v8-status-alist)))
+    (while (and statuses
+               (zerop (logand num (cdar statuses))))
+      (setq statuses (cdr statuses)))
+    (or (caar statuses) 'online)))
+
+(defun emchat-v8-snac-cli-setstatus (ectx &optional status)
+  "Set status, SNAC(1, 30)."
+  (setq status (apply 'logior
+                      (mapcar #'(lambda (st)
+                                  (cdr (assoc st emchat-v8-status-alist)))
+                              status)))
+
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x01 . #x1E)
+      (emchat-v8-pack-tlv 6
+        (emchat-v8-pack-dword status))
+      (emchat-v8-pack-tlv 8
+        (emchat-v8-pack-word 0)))))
+
+(defun emchat-v8-snac-cli-add-contact (ectx &optional contacts)
+  "CLI_ADDCONTACT, SNAC(3,4)
+Send either CONTACTS or ECTX's contact list."
+  (unless contacts
+    (setq contacts (emchat-v8-ctx-get-prop ectx 'contacts)))
+  (emchat-v8-debug "Adding contacts: %S" contacts)
+  (when contacts
+    (emchat-v8-send ectx
+      (emchat-v8-pack-snac ectx '(#x03 . #x04)
+        (emchat-v8-pack-uinlist contacts)))))
+
+(defun emchat-v8-snac-cli-addvisible (ectx &optional uin-list)
+  "CLI_ADDVISIBLE SNAC(9, 5)."
+  (unless uin-list
+    (setq uin-list (emchat-v8-ctx-get-prop ectx 'visible-list)))
+  (emchat-v8-debug "Adding to visible: %S" uin-list)
+  (when uin-list
+    (emchat-v8-send ectx
+      (emchat-v8-pack-snac ectx '(#x09 . #x05)
+       (emchat-v8-pack-uinlist uin-list)))))
+
+(defun emchat-v8-snac-cli-remvisible (ectx uin-list)
+  "CLI_ADDVISIBLE SNAC(9, 6)."
+  (emchat-v8-debug "Removing from visible: %S" uin-list)
+  (when uin-list
+    (emchat-v8-send ectx
+      (emchat-v8-pack-snac ectx '(#x09 . #x06)
+       (emchat-v8-pack-uinlist uin-list)))))
+
+(defun emchat-v8-snac-cli-addinvisible (ectx &optional uin-list)
+  "CLI_ADDVISIBLE SNAC(9, 7)."
+  (unless uin-list
+    (setq uin-list (emchat-v8-ctx-get-prop ectx 'invisible-list)))
+  (emchat-v8-debug "Adding to invisible: %S" uin-list)
+  (when uin-list
+    (emchat-v8-send ectx
+      (emchat-v8-pack-snac ectx '(#x09 . #x07)
+       (emchat-v8-pack-uinlist uin-list)))))
+
+(defun emchat-v8-snac-cli-reminvisible (ectx uin-list)
+  "CLI_REMINVISIBLE SNAC(9, 8)."
+  (emchat-v8-debug "Removing from invisible: %S" uin-list)
+  (when uin-list
+    (emchat-v8-send ectx
+      (emchat-v8-pack-snac ectx '(#x09 . #x08)
+       (emchat-v8-pack-uinlist uin-list)))))
+
+(defun emchat-v8-snac-cli-keepalive (ectx)
+  "Send keep-alive flap."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-flap ectx 5)))
+
+(defun emchat-v8-pack-meta-snac (ectx sub &optional type &rest data)
+  "Create meta snac."
+  (setq data (apply 'concat data))
+
+  (let ((seq3 (emchat-v8-ctx-get-prop ectx 'our-seq3))
+        temp-data)
+    (if seq3
+       (emchat-v8-ctx-put-prop ectx 'our-seq3 (% (1+ seq3) 32767))
+      (emchat-v8-ctx-put-prop ectx 'our-seq3 2))
+    
+    (setq temp-data
+          (concat 
+           (emchat-v8-pack-uin (plist-get (emchat-v8-ctx-userinfo ectx) 'uin))
+           (emchat-v8-number->string-swap 2 sub)
+           (emchat-v8-number->string-swap 2 (emchat-v8-ctx-get-prop ectx 'our-seq3))
+           (when type
+             (emchat-v8-number->string-swap 2 type))
+           data))
+
+    (emchat-v8-pack-snac ectx '(#x15 . #x02)
+      (emchat-v8-pack-tlv 1
+        (emchat-v8-number->string-swap 2 (length temp-data))
+        temp-data))))
+
+(defun emchat-v8-snac-cli-reqofflinemsgs (ectx)
+  "CLI_REQOFFLINEMSGS, SNAC(15,2)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-meta-snac ectx 60)))
+
+(defun emchat-v8-snac-cli-metareqinfo (ectx uin)
+  "CLI_METAREQINFO, SNAC(15,2)/2000/1232."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-meta-snac ectx 2000 1232
+       (emchat-v8-pack-uin uin)))
+
+  ;; Save pair SEQ/UIN for later UIN extraction
+  (emchat-v8-ctx-put-prop ectx 'about-query-seq-uin
+    (cons (cons (emchat-v8-ctx-get-prop ectx 'our-seq3) uin)
+          (emchat-v8-ctx-get-prop ectx 'about-query-seq-uin))))
+
+(defun emchat-v8-snac-cli-searchbyuin (ectx uin)
+  "CLI_SEARCHBYUIN, SNAC(15,2)/2000/1385."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-meta-snac ectx 2000 1385
+       (emchat-v8-pack-word-le 310)       ; Search key (310 == uin)
+       (emchat-v8-pack-lnts (emchat-v8-pack-uin uin)))))
+
+(defun emchat-v8-snac-cli-searchbyemail (ectx email)
+  "CLI_SEARCHBYEMAIL, SNAC(15,2)/2000/1395."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-meta-snac
+     ectx 2000 1395
+     (emchat-v8-pack-word-le 350)              ; Search key (350 == email)
+     (emchat-v8-pack-llnts email))))
+
+(defun emchat-v8-snac-cli-searchbypersinf (ectx first last nick email online)
+  "CLI_SEARCHBYPERSINF, SNAC(15,2)/2000/1375."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-meta-snac
+     ectx 2000 1375
+     (emchat-v8-pack-word-le 320)      ; Search key (320 == first name)
+     (emchat-v8-pack-llnts first)
+     (emchat-v8-pack-word-le 330)      ; Search key (330 == last name)
+     (emchat-v8-pack-llnts last)
+     (emchat-v8-pack-word-le 340)      ; Search key (340 == nick name)
+     (emchat-v8-pack-llnts nick)
+     (emchat-v8-pack-word-le 350)      ; Search key (350 == email)
+     (emchat-v8-pack-llnts email)
+     (emchat-v8-pack-byte online))))
+
+;;; FIXME: this doesn't impliment direct connect or something called
+;;; "user kind"
+(defun emchat-v8-snac-cli-metasetsecurity (ectx auth web)
+  "CLI_METASETSECURITY. SNAC(#x15, #x02)/2000/1060."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-meta-snac 
+     ectx 2000 1060
+     (emchat-v8-pack-byte auth)                ; req auth 0 = no; 1 = yes
+     (emchat-v8-pack-byte web)         ; webaware 0 = yes; 1 = no
+     (emchat-v8-pack-byte #x02)                ; dc hard coded to only with auth
+     (emchat-v8-pack-byte 0))))                ; user kind (no idea, set to zero)
+
+(defun emchat-v8-snac-cli-ready (ectx)
+  "CLI_READY, SNAC(1, 2)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x01 . #x02)
+      (apply 'concat
+             (mapcar #'(lambda (sn)
+                         (concat
+                          (emchat-v8-pack-word (car sn))
+                          (emchat-v8-pack-word (cdr sn))
+                          (if (= (car sn) 2)
+                              (emchat-v8-pack-dword #x0101047B)
+                            (emchat-v8-pack-dword #x0110047B))))
+                     emchat-v8-snacv-list)))))
+
+(defun emchat-v8-snac-cli-families (ectx)
+  "CLI_FAMILIES, SNAC(1, 17)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x01 . #x17)
+      (apply 'concat
+             (mapcar #'(lambda (sn)
+                         (concat
+                          (emchat-v8-pack-word (car sn))
+                          (emchat-v8-pack-word (cdr sn))))
+                     emchat-v8-snacv-list)))))
+
+(defun emchat-v8-snac-cli-ratesrequest (ectx)
+  "CLI_RATESREQUEST, SNAC(1, 6)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x01 . #x06))))
+
+(defun emchat-v8-snac-cli-reqinfo (ectx)
+  "CLI_REQINFO, SNAC(1, E)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x01 . #x0E))))
+
+(defun emchat-v8-snac-cli-reqlocation (ectx)
+  "CLI_REQLOCATION, SNAC(2, 2)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x02 . #x02))))
+
+(defun emchat-v8-snac-cli-reqbuddy (ectx)
+  "CLI_REQBUDDY, SNAC(3, 2)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x03 . #x02))))
+
+(defun emchat-v8-snac-cli-reqicbm (ectx)
+  "CLI_REQICBM, SNAC(4, 4)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x04 . #x04))))
+
+(defun emchat-v8-snac-cli-sendmsg (ectx uin format msg)
+  "CLI_SENDMSG, SNAC(4, 6).
+UIN - Icq uin to send message to.
+FORMAT - format id, 1 - simple, 2 - advanced, 4 - typed.
+MSG - Message itself."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x04 . #x06)
+      (emchat-v8-pack-dword 0)            ; random
+      (emchat-v8-pack-dword 0)            ; random
+      (emchat-v8-pack-word format)
+      (emchat-v8-pack-buin uin)
+      msg
+      (emchat-v8-pack-tlv 6))))
+
+(defconst emchat-v8-msg-encodings
+  '((us-ascii . 0)
+    (utf-16 . 2)
+    (8bit . 3)))
+
+(defun emchat-v8-send-simple-message (ectx uin message)
+  "Send simple message."
+  (emchat-v8-snac-cli-sendmsg ectx uin 1
+    (emchat-v8-pack-tlv 2
+      (emchat-v8-pack-tlv 1281 (emchat-v8-pack-byte 1))
+      (emchat-v8-pack-tlv 257
+        (emchat-v8-pack-word 3)
+        (emchat-v8-pack-word (+ 4 (length message)))
+        message))))
+
+(defun emchat-v8-send-typed-message (ectx uin type message)
+  "Send typed message."
+  (emchat-v8-snac-cli-sendmsg ectx uin 4
+    (emchat-v8-pack-tlv 5
+      (emchat-v8-pack-uin (plist-get (emchat-v8-ctx-userinfo ectx) 'uin))
+      (emchat-v8-pack-word-le
+       (car (find type emchat-v8-msg-types :key 'cdr :test 'eq)))
+      (emchat-v8-pack-lnts message))))
+
+(defun emchat-v8-send-advanced-message (ectx uin &rest add-arguments-here-for-advanced-message)
+  ;; Advanced message:
+  ;; TLV(5):
+  ;;    2 ACKTYPE :  0 - normal, 1 - abort, 2 - file ack
+  ;;    4 TIME : copy
+  ;;    4 ID : random id
+  ;;  TLV(11) UNKNOWN : Only if ACTYPE is 1
+  ;;   CAP
+  ;;  TLV(10) ACKTYPE2 : 1 - normal, 2 - file ack
+  ;;  TLV(5) PORT
+  ;;  TLV(3) IP
+  ;;  TLV15  UNKNOWN
+  ;;  TLV(1001) MESSAGE
+;  (emchat-v8-snac-cli-sendmsg ectx uin 2)
+  (emchat-v8-debug "TODO: `emchat-v8-send-advanced-message'")
+  )
+
+(defun emchat-v8-send-server-message (ectx uin &rest add-arguments-here-for-server-message)
+  ;; Server message:
+  ;; TLV(5)
+  ;;   4  UIN  : sender uin
+  ;;   2  MSGTYPE : message type
+  ;; LNTS MSG : message with unspecified encoding
+;  (emchat-v8-snac-cli-sendmsg ectx uin 3)
+  (emchat-v8-debug "TODO: `emchat-v8-send-advanced-message'")
+  )
+
+(defun emchat-v8-snac-cli-reqbos (ectx)
+  "CLI_REQBOS, SNAC(9, 2)."
+  (emchat-v8-send ectx
+    (emchat-v8-pack-snac ectx '(#x09 . #x02))))
+
+(defun emchat-v8-handle-flap (ectx-flap)
+  (let* ((ectx (car ectx-flap))
+         (flap (cdr ectx-flap))
+         (cid (emchat-v8-flap-cid flap)))
+    (cond ((= cid emchat-v8-FLAP-HELLO)
+           ;; XXX Login channel
+           (emchat-v8-debug "Got HELLO cid")
+           (let ((cmd (emchat-v8-fetch-dword (emchat-v8-flap-data flap)))
+                 (cli-cook (emchat-v8-ctx-get-prop ectx 'cli-cookie)))
+             (cond ((= cmd 1)
+                    (if cli-cook
+                        ;; Already logged in, send Cookie
+                        (emchat-v8-send ectx
+                          (emchat-v8-pack-flap ectx emchat-v8-FLAP-HELLO
+                            (emchat-v8-pack-dword 1)
+                            (emchat-v8-pack-tlv 6 cli-cook)))
+                         
+                      ;; Not logged in yet
+                      (emchat-v8-login ectx)))
+
+                   (t (error (format "Unknown FLAP CMD(%) in login channel." cmd))))
+             ))
+           
+          ((= cid emchat-v8-FLAP-SNAC)
+           ;; SNAC channel
+           ;; TODO:
+           ;;  - Write me
+           (let ((snac (emchat-v8-fetch-snac (emchat-v8-flap-data flap)))
+                 (snacs emchat-v8-snac-list))
+             (while (and snacs
+                         (or (not (= (emchat-v8-snac-family snac)
+                                     (car (caar snacs))))
+                             (not (= (emchat-v8-snac-subtype snac)
+                                     (cdr (caar snacs))))))
+               (setq snacs (cdr snacs)))
+
+             (emchat-v8-debug "SNAC %S (%S)" snac (when (car snacs) (nth 1 (car snacs))))
+
+             (unless snacs
+               (error 'invalid-argument "Unknown SNAC" snac))
+
+             ;; Call snac handler
+             (funcall (nth 2 (car snacs))
+                     ectx                           ; context
+                     (emchat-v8-flap-data flap)     ; data
+                     (emchat-v8-snac-flags snac)))) ; snac flags
+
+          ((= cid emchat-v8-FLAP-ERRORS)
+           ;; ERRORS channel
+           (emchat-v8-debug "ERROR")
+           )
+
+          ((= cid emchat-v8-FLAP-LOGOFF)
+           ;; LOGOFF channel
+           (let* ((tlvs (emchat-v8-fetch-tlvs (emchat-v8-flap-data flap)))
+                  (tlv (emchat-v8-tlv-get tlvs 5)))
+
+             (emchat-v8-debug "LOGOFF tlv_t5=%S" tlv)
+             ;; Close connection
+             (emchat-v8-close ectx)
+
+             (if (not tlv)
+                 ;; Another user with same UIN
+                 (emchat-v8-ctx-run-incoming-handler ectx 'logoff)
+
+               ;; Redirected
+               (let* ((nsrv (split-string (emchat-v8-tlv-str tlv) ":"))
+                      (addr (nth 0 nsrv))
+                      (port (string-to-int (nth 1 nsrv))))
+                 (emchat-v8-debug "Redirected to new server: %s:%d" addr port)
+                 ;; Store cookie and reconnect
+                 (emchat-v8-ctx-put-prop ectx 'cli-cookie
+                   (emchat-v8-tlv-str (emchat-v8-tlv-get tlvs 6)))
+                 (emchat-v8-connect ectx addr port)))))
+
+          ((= cid emchat-v8-FLAP-PING)
+           ;; PING channel
+           (emchat-v8-debug "PING")
+           )
+           
+          (t (error (format "Unknown FLAP cid(%d)." cid))))
+    ))
+
+(defun emchat-v8-fetch-handle-flaps (ectx)
+  (while (> (length (emchat-v8-ctx-incoming-buffer ectx)) 0)
+    ;; Do not do anything in filter function
+    (emchat-v8-handle-flap (cons ectx (emchat-v8-fetch-flap ectx)))))
+
+\f
+(defun emchat-v8-number->string (size val)
+  "Convert number value VAL to string of SIZE."
+  (cond ((= size 1)
+        (setq val (truncate val))
+        (char-to-string val))
+       ((= size 2)
+        (setq val (truncate val))
+        (concat (char-to-string (ash (mod val 65536) -8))
+                (char-to-string (logand val 255))
+                ))
+       ((= size 4)
+        ;; XXX remove this
+        (setq val (truncate val))
+        (mapconcat 'identity
+                   (nreverse 
+                    (list (char-to-string (int-to-char (% val 256)))
+                          (char-to-string (int-to-char (% (setq val (/ val 256)) 256)))
+                          (char-to-string (int-to-char (% (setq val (/ val 256)) 256)))
+                          (char-to-string (int-to-char (% (setq val (/ val 256)) 256)))
+                          ))
+                   ""))
+       
+       (t (error "Invalid SIZE" size))))
+
+(defun emchat-v8-number->string-swap (size val)
+  "Convert number VAL to string of SIZE."
+  (let ((ss (emchat-v8-number->string size val))
+       tt)
+    (cond ((= size 2)
+          (setq tt (aref ss 0))
+          (aset ss 0 (aref ss 1))
+          (aset ss 1 tt))
+         ((= size 4)
+          (setq tt (aref ss 0))
+          (aset ss 0 (aref ss 3))
+          (aset ss 3 tt)
+          (setq tt (aref ss 1))
+          (aset ss 1 (aref ss 2))
+          (aset ss 2 tt)))
+    ss))
+
+(defun emchat-v8-create-message (&rest UNIPREFIX-message-spec)
+  "Create emchat message according to SPEC."
+  (let (UNIPREFIX-value-spec UNIPREFIX-value)
+    (mapconcat (lambda (UNIPREFIX-element)
+                (setq UNIPREFIX-value-spec (eval (aref UNIPREFIX-element 0)))
+                (setq UNIPREFIX-value (eval (aref UNIPREFIX-element 1)))
+                
+                (cond ((numberp UNIPREFIX-value)
+                       (emchat-v8-number->string UNIPREFIX-value-spec UNIPREFIX-value))
+                      ((stringp UNIPREFIX-value)
+                       (substring  UNIPREFIX-value 0 UNIPREFIX-value-spec))
+                      ((null UNIPREFIX-value)
+                       (make-string UNIPREFIX-value-spec ?\x00))
+                      (t (error "Invalid SPEC" UNIPREFIX-value-spec))))
+              UNIPREFIX-message-spec "")
+    ))
+  
+(defun emchat-v8-string->number-le-flt (str &optional len)
+  "Convert STR to number."
+  (unless len
+    (setq len (length str)))
+
+  (let ((ret 0.0) (i 0))
+    (while (< i len)
+      (setq ret (+ ret (* (char-int (aref str i)) (expt 256.0 i)))
+           i (1+ i)))
+    ret))
+
+(defun emchat-v8-string->number-flt (str &optional len)
+  "Convert STR to number."
+  (unless len
+    (setq len (length str)))
+
+  (let ((ret 0.0) (i 0))
+    (while (< i len)
+      (setq ret (+ (* 256.0 ret) (char-int (aref str i)))
+           i (1+ i)))
+    ret))
+
+(defun emchat-v8-string->number-le-bigz (str &optional len)
+  "Convert STR to number."
+  ;; optimise for common cases
+  (cond ((eq len 4)
+         (+ (* (aref str 3) 16777216)
+            (* (aref str 2) 65536)
+            (* (aref str 1) 256)
+            (aref str 0)))
+        ((eq len 2)
+         (+ (* (aref str 1) 256)
+            (aref str 0)))
+        ((eq len 1)
+         (char-to-int (aref str 0)))
+        (t
+         (let* ((len (or len (length str)))
+                (ret (char-int (aref str 0)))
+                (i 1))
+           (while (< i len)
+             (setq ret (+ ret (* (char-int (aref str i))
+                                 (2^ (* 8 i))))
+                   i (1+ i)))
+           ret))))
+
+(defun emchat-v8-string->number-bigz (str &optional len)
+  "Convert STR to number."
+  ;; optimise for common cases
+  (cond ((eq len 4)
+         (+ (* (aref str 0) 16777216)
+            (* (aref str 1) 65536)
+            (* (aref str 2) 256)
+            (aref str 3)))
+        ((eq len 2)
+         (+ (* (aref str 0) 256)
+            (aref str 1)))
+        ((eq len 1)
+         (char-to-int (aref str 0)))
+        (t
+         (let* ((len (or len (length str)))
+                (ret 0)
+                (i 0))
+           (while (< i len)
+             (setq ret (+ (lsh ret 8) (char-int (aref str i)))
+                   i (1+ i)))
+           ret))))
+
+;; do the right thing at the right time, the wrong otherwise
+(cond
+ ((featurep 'bigz)
+  (defalias #'emchat-v8-string->number #'emchat-v8-string->number-bigz)
+  (defalias #'emchat-v8-string->number-le #'emchat-v8-string->number-le-bigz)
+  'using-bigz)
+ (t
+  (defalias #'emchat-v8-string->number #'emchat-v8-string->number-flt)
+  (defalias #'emchat-v8-string->number-le #'emchat-v8-string->number-le-flt)
+  'using-flt))
+
+(defvar emchat-v8-timeout 15
+  "Receive timeout in seconds.")
+
+(defun emchat-v8-grab-bytes (ectx len)
+  "Grab LEN bytes from ECTX's incoming buffer."
+  (setq len (truncate len))            ;for sure
+
+  (let (rstr)
+    (while (< (length (emchat-v8-ctx-incoming-buffer ectx)) len)
+      (when (null (accept-process-output (emchat-v8-ctx-proc ectx)
+                                         emchat-v8-timeout))
+        (error "EMCHAT: Timeout")))
+    (setq rstr (substring (emchat-v8-ctx-incoming-buffer ectx) 0 len))
+    (setf (emchat-v8-ctx-incoming-buffer ectx)
+         (substring (emchat-v8-ctx-incoming-buffer ectx) len))
+    rstr))
+
+(defun emchat-v8-grab-bytes-1 (vmsg len)
+  "Grab LEN bytes from VMSG."
+  (setq len (truncate len))
+
+  (let (rstr)
+    ;; Check LEN
+    (when (> len (length (aref vmsg 0)))
+      (error 'invalid-argument "Invalid len" len))
+
+    (setq rstr (substring (aref vmsg 0) 0 len))
+    (aset vmsg 0 (substring (aref vmsg 0) len))
+    rstr))
+
+;; Generic length storers
+(defvar emchat-v8-length-1 nil)
+(defvar emchat-v8-length-2 nil)
+(defvar emchat-v8-length-3 nil)
+(defvar emchat-v8-length-4 nil)
+
+(defun emchat-v8-parse-message (ectx-msg spec)
+  "Parse ECTX-MSG according to SPEC.
+ECTX-MSG is either EMchat context to grab bytes from, or string.
+
+SPEC is one of
+ - Vector         specifies one value.
+ - List           specifies multiple values.
+ - List of Lists  specifies list of lists of multiple values."
+  (when (stringp ectx-msg)
+    (setq ectx-msg (vector ectx-msg)))
+
+  (let ((accessor (if (emchat-v8-ctx-p ectx-msg) 'emchat-v8-grab-bytes 'emchat-v8-grab-bytes-1))
+       vlen vtype rlist)
+
+    (cond ((vectorp spec)
+          ;; Vector
+          (setq vlen (truncate (eval (aref spec 0))))
+          (setq vtype (aref spec 1))
+          (if (numberp vtype)
+              (when (not (= (emchat-v8-string->number (funcall accessor ectx-msg vlen) vlen)
+                             vtype))
+                (error 'invalid-argument "Invalid argument in MSG"))
+
+            ;; Normal type
+            (cond ((or (eq vtype 'number) (eq vtype 'integer))
+                   (setq rlist (emchat-v8-string->number (funcall accessor ectx-msg vlen) vlen)))
+
+                  ((or (eq vtype 'number-swap) (eq vtype 'integer-swap))
+                   (setq rlist (emchat-v8-string->number-le (funcall accessor ectx-msg vlen) vlen)))
+
+                  ((eq vtype 'string)
+                   (setq rlist (funcall accessor ectx-msg vlen)))
+
+                  ((and (symbolp vtype) (not (keywordp vtype))
+                        (member vtype '(emchat-v8-length-1 emchat-v8-length-2 emchat-v8-length-3 emchat-v8-length-4)))
+                   ;; If symbol - set it
+                   (set vtype (emchat-v8-string->number (funcall accessor ectx-msg vlen) vlen))
+                   (setq rlist (symbol-value vtype)))
+
+                  ((listp vtype)
+                   (setq rlist (mapcar #'(lambda (not-used)
+                                            (emchat-v8-parse-message ectx-msg vtype))
+                                       (make-list vlen nil))))
+
+                  ((null vtype) ;; Skip
+                   )
+
+                  (t (error 'invalid-argument "Invalid type in SPEC" vtype)))))
+
+         ((and (listp spec)
+               (not (member nil (mapcar (lambda (l) (listp l)) spec))))
+          ;; List of Lists
+          )
+
+         ((listp spec)
+          ;; List
+          (setq rlist (mapcar (lambda (e) (emchat-v8-parse-message ectx-msg e)) spec)))
+
+         (t (error 'invalid-argument "Invalid SPEC" spec)))
+
+    rlist))
+
+
+(put 'emchat-v8-parse-message 'lisp-indent-function 1)
+
+(defun emchat-v8-fetch-data (data len)
+  (vector (funcall (if (emchat-v8-ctx-p data)
+                       'emchat-v8-grab-bytes
+                     'emchat-v8-grab-bytes-1)
+                   data len)))
+
+(defun emchat-v8-fetch-string (data &optional len)
+  (aref (emchat-v8-fetch-data data (or len (length (aref data 0)))) 0))
+
+(defun emchat-v8-fetch-byte (data)
+  (char-to-int (string-to-char (emchat-v8-fetch-string data 1))))
+(defun emchat-v8-pack-byte (byte)
+  (char-to-string byte))
+
+(defun emchat-v8-fetch-word (data)
+  (truncate (emchat-v8-string->number
+             (emchat-v8-fetch-string data 2))))
+(defun emchat-v8-pack-word (word)
+  (emchat-v8-number->string 2 word))
+
+(defun emchat-v8-fetch-word-le (data)
+  (truncate (emchat-v8-string->number-le
+             (emchat-v8-fetch-string data 2))))
+(defun emchat-v8-pack-word-le (word)
+  (emchat-v8-number->string-swap 2 word))
+
+(defun emchat-v8-fetch-dword (data)
+  (emchat-v8-string->number
+   (emchat-v8-fetch-string data 4)))
+(defun emchat-v8-pack-dword (dword)
+  (emchat-v8-number->string 4 dword))
+
+(defun emchat-v8-fetch-time (data)
+  (cons (emchat-v8-fetch-word data)
+       (emchat-v8-fetch-word data)))
+
+(defun emchat-v8-pack-time (time)
+  (concat
+   (emchat-v8-pack-word (car time))
+   (emchat-v8-pack-word (cdr time))))
+
+(defun emchat-v8-fetch-uin (data)
+  (truncate
+   (emchat-v8-string->number-le
+    (emchat-v8-fetch-string data 4))))
+
+(defun emchat-v8-fetch-uinlist (count uinlist)
+  (let (result)
+    (dotimes (i count)
+      (append (emchat-v8-fetch-uin uinlist) result))))
+
+(defun emchat-v8-pack-uin (uin)
+  (emchat-v8-number->string-swap 4 uin))
+
+(defun emchat-v8-fetch-buin (data)
+  "Fetch BUIN and return uin number."
+  (string-to-number (emchat-v8-fetch-string data (emchat-v8-fetch-byte data))))
+(defun emchat-v8-pack-buin (uin)
+  (let ((suin (number-to-string uin)))
+    (concat (emchat-v8-pack-byte (length suin)) suin)))
+
+(defun emchat-v8-fetch-bstr (data)
+  (let* ((len (emchat-v8-fetch-word data))
+        (str (emchat-v8-fetch-string data len)))
+    (substring str 0 len)))
+
+(defun emchat-v8-pack-bstr (str)
+  (concat (emchat-v8-pack-word (length str)) str))
+
+;; Various packers
+(defun emchat-v8-pack-uinlist (uin-list)
+  (apply 'concat (mapcar 'emchat-v8-pack-buin uin-list)))
+
+(defun emchat-v8-pack-nts (string)
+  (concat string (char-to-string 0)))
+
+(defun emchat-v8-pack-lnts (string)
+  (let ((nts (emchat-v8-pack-nts string)))
+    (concat
+     (emchat-v8-pack-word-le (length nts))
+     nts)))
+
+(defun emchat-v8-pack-llnts (string)
+  (let ((nts (emchat-v8-pack-nts string)))
+    (concat
+     (emchat-v8-pack-word-le (+ (length nts) 2))
+     (emchat-v8-pack-word-le (length nts))
+     nts)))
+
+(defun emchat-v8-fetch-lnts (data)
+  (let* ((len (emchat-v8-fetch-word-le data))
+         (str (emchat-v8-fetch-string data len)))
+    (substring str 0 (1- len))))
+
+;; FLAP
+(defun emchat-v8-fetch-flap (data)
+  "Get next queued FLAP from emchat context ECTX."
+  (set-process-filter
+   (emchat-v8-ctx-proc data) 'emchat-v8-proc-filter-accumulator)
+
+  (unwind-protect 
+      (progn
+        (let ((bb (emchat-v8-fetch-byte data)))
+          (unless (= bb #x2A)
+            (error "Unexpected data while fetching FLAP")))
+  
+        (let* ((cin (emchat-v8-fetch-byte data))
+               (seq (emchat-v8-fetch-word data))
+               (flen (emchat-v8-fetch-word data))
+               (fdata (emchat-v8-fetch-data data flen)))
+          (list cin seq fdata)))
+
+    (set-process-filter
+     (emchat-v8-ctx-proc data) 'emchat-v8-proc-filter-proccessing)))
+
+(defun emchat-v8-pack-flap (ectx chan-id &rest flap-data)
+  "Create FLAP packet of channel id CHAN-ID and DATA."
+  (setq flap-data (apply 'concat flap-data))
+
+  (prog1
+      (concat
+       (emchat-v8-pack-byte #x2A)
+       (emchat-v8-pack-byte chan-id)
+       (emchat-v8-pack-word (emchat-v8-ctx-sequence ectx))
+       (emchat-v8-pack-word (length flap-data))
+       flap-data)
+    
+    ;; Increase sequence number
+    (incf (emchat-v8-ctx-sequence ectx))
+    (when (> (emchat-v8-ctx-sequence ectx) 65535)
+      (setf (emchat-v8-ctx-sequence ectx)
+           (% (emchat-v8-ctx-sequence ectx) 65536)))))
+(put 'emchat-v8-pack-flap 'lisp-indent-function 2)
+
+;; SNAC
+(defun emchat-v8-fetch-snac (data)
+  "Get next SNAC."
+  (let ((family (emchat-v8-fetch-word data))
+        (subtype (emchat-v8-fetch-word data))
+       (flags (emchat-v8-fetch-word data))
+        (rid (emchat-v8-fetch-dword data)))
+
+    ;; If 15th bit is set in FLAGS then DATA contains some additional
+    ;; data in format LENGTH [WORD], DATA [LENGTH]
+    (unless (zerop (logand flags 32768))
+      (let ((len (emchat-v8-fetch-word data)))
+        (emchat-v8-fetch-data data len)))
+
+    (list family subtype flags rid)))
+
+(defun emchat-v8-pack-snac (ectx family-subtype &rest snac-data)
+  "Create SNAC packet."
+  (setq snac-data (apply 'concat snac-data))
+  (emchat-v8-pack-flap ectx 2
+    (emchat-v8-pack-word (car family-subtype))
+    (emchat-v8-pack-word (cdr family-subtype))
+    (emchat-v8-pack-word 0)               ; XXX flags
+    (emchat-v8-pack-dword 0)              ; XXX rid
+    snac-data))
+(put 'emchat-v8-pack-snac 'lisp-indent-function 2)
+
+;; TLVs
+(defun emchat-v8-fetch-single-tlv (data)
+  (let* ((type (emchat-v8-fetch-word data))
+         (len (emchat-v8-fetch-word data))
+         (value (emchat-v8-fetch-data data len)))
+    (list type len value)))
+  
+(defun emchat-v8-fetch-tlvs (data)
+  "From VMSG extract TLV list."
+  (let ((tlvs nil))
+    (while (> (length (aref data 0)) 0)
+      (setq tlvs (cons (emchat-v8-fetch-single-tlv data) tlvs)))
+    (nreverse tlvs)))
+
+(defun emchat-v8-fetch-n-tlvs (data n)
+  "Read TLVs of total length N and return a list."
+  (let ((tlvs nil))
+    (while (> n 0)
+      (let* ((tlv (emchat-v8-fetch-single-tlv data)))
+        (setq n (- n (emchat-v8-tlv-len tlv) 4)
+              tlvs (cons tlv tlvs))))
+    (nreverse tlvs)))
+
+(defun emchat-v8-tlv-get (tlv-list type)
+  "From TLV list TLV-LIST get tlv of TYPE."
+  (while (and tlv-list (not (= (emchat-v8-tlv-type (car tlv-list)) type)))
+    (setq tlv-list (cdr tlv-list)))
+  (car tlv-list))
+
+(defun emchat-v8-pack-tlv (type &rest values)
+  "Create TLV."
+  (let ((val (apply 'concat values)))
+    (concat
+     (emchat-v8-pack-word type)
+     (emchat-v8-pack-word (length val))
+     val)))
+(put 'emchat-v8-pack-tlv 'lisp-indent-function 1)
+
+\f
+(defun emchat-v8-login (ectx &optional uin password)
+  "In ECTX context send UIN/PASSWORD to ICQ server."
+  (emchat-v8-debug "Logging in ..")
+
+  (unless uin
+    (setq uin (plist-get (emchat-v8-ctx-userinfo ectx) 'uin)))
+  (unless password
+    (setq password (plist-get (emchat-v8-ctx-userinfo ectx) 'password)))
+
+  ;; Remove password (for somekind of security)
+  (setf (emchat-v8-ctx-userinfo ectx)
+        (plist-remprop (emchat-v8-ctx-userinfo ectx) 'password))
+
+  (emchat-v8-send ectx
+    (emchat-v8-pack-flap ectx emchat-v8-FLAP-HELLO
+      (emchat-v8-pack-dword 1)
+      (emchat-v8-pack-tlv 1
+        (number-to-string uin))
+      (emchat-v8-pack-tlv 2 (emchat-v8-util-encrypt password))
+      (emchat-v8-pack-tlv 3 emchat-v8-client-id-string)
+      (emchat-v8-pack-tlv #x16
+        (emchat-v8-pack-word #x010A))
+      (emchat-v8-pack-tlv #x17
+        (emchat-v8-pack-word emchat-v8-FLAP-VER-MAJOR))
+      (emchat-v8-pack-tlv #x18
+        (emchat-v8-pack-word emchat-v8-FLAP-VER-MINOR))
+      (emchat-v8-pack-tlv #x19
+        (emchat-v8-pack-word emchat-v8-FLAP-VER-LESSER))
+      (emchat-v8-pack-tlv #x1A
+        (emchat-v8-pack-word emchat-v8-FLAP-VER-BUILD))
+      (emchat-v8-pack-tlv #x14
+        (emchat-v8-pack-dword emchat-v8-FLAP-VER-SUBBUILD))
+      (emchat-v8-pack-tlv #x0F "en")
+      (emchat-v8-pack-tlv #x0E "us"))))
+
+\f
+(provide 'emchat-v8)
+
+;;; emchat-v8.el ends here
diff --git a/emchat-wharf.el b/emchat-wharf.el
new file mode 100644 (file)
index 0000000..909abcc
--- /dev/null
@@ -0,0 +1,218 @@
+;;; emchat-wharf.el --- DockApp/status window for EMchat
+
+;; Copyright (C) 2001 - 2008 Steve Youngs, Erik Arneson
+
+;; Author:        Erik Arneson <erik@aarg.net>
+;; Maintainer:    Erik Arneson <erik@aarg.net>
+;; Created:       Aug 10, 2001
+;; Homepage:      http://www.emchat.org/
+;; Keywords:      comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+(defvar emchat-wharf-frame nil
+  "Frame in which EMchatWharf is running.")
+
+(defvar emchat-wharf-frame-props
+  '((name . "EMchatWharf")
+    (height . 5)
+    (width . 8)
+    (unsplittable . t)
+    (minibuffer . none)
+    (menubar-visible-p . nil)
+    (has-modeline-p . nil)
+    (default-gutter-visible-p . nil)
+    (default-toolbar-visible-p . nil)
+    (scrollbar-height . 0)
+    (scrollbar-width . 0)
+    (text-cursor-visible-p . nil))
+  "Frame properties for EMchatWharf.")
+
+(defvar emchat-wharf-buf nil
+  "Buffer in which EMchatWharf is running.")
+
+(defgroup emchat-wharf nil
+  "Miniature EMchat status window."
+  :prefix "emchat-wharf-"
+  :group 'emchat)
+
+(defface emchat-wharf-default-face
+  '((((class color))
+     (:foreground "Green" :family "fixed" :size "9pt"))
+    (t
+     (:family "fixed" :size "9pt")))
+  "Face used in EMchatWharf window.
+
+If you want this to be dockable, make sure you use a small but readable
+font."
+  :group 'emchat-wharf)
+
+(defcustom emchat-wharf-notice-riece-flag nil
+  "When non-nil, indicate Riece activity in EMchatWharf.
+
+This requires riece-biff to be set up and active."
+  :type 'boolean
+  :group 'emchat-wharf)
+
+;; Riece activity indicator face
+(make-face 'emchat-wharf-riece-active-face
+          "Face used in EMchat Wharf when there is activity from Riece.")
+(set-face-parent 'emchat-wharf-riece-active-face
+                'emchat-wharf-default-face)
+(set-face-foreground 'emchat-wharf-riece-active-face "Red")
+
+(make-face 'emchat-wharf-riece-inactive-face
+          "Face used in EMchat Wharf when there is no activity from Riece.")
+(set-face-parent 'emchat-wharf-riece-inactive-face
+                'emchat-wharf-default-face)
+(set-face-foreground 'emchat-wharf-riece-inactive-face "Black")
+
+
+;;;###autoload
+(defcustom emchat-wharf-frame-use-p nil
+  "If non-NIL, start up the EMchatWharf mini-frame."
+  :type 'boolean
+  :group 'emchat-wharf
+  :tag "EMchatWharf mini-frame")
+
+;;; Internal variables
+
+;;; Riece integration
+(defvar emchat-riece-activity nil
+  "This is non-nil when riece-biff has been triggered.")
+
+;; Advise a couple of Riece functions to run some hooks for us.
+(defadvice riece-biff-after-display-message-function (after biffon (&rest args) activate)
+  "Update the EMchatWharf Riece indicator."
+  (when (eq riece-biff-mode-string 'riece-biff-biff-mode-string)
+    (run-hooks 'riece-biff-activity-hook)))
+
+(defadvice riece-biff-clear (after biffoff (&rest args) activate)
+  "Update the EMchatWharf Riece indicator."
+  (when (eq riece-biff-mode-string 'riece-biff-default-mode-string)
+    (run-hooks 'riece-biff-clear-hook)))
+
+(defun emchat-wharf-riece-active ()
+  "Make the EMchatWharf Riece indicator active."
+  (let ((emchat-riece-activity t))
+    (emchat-wharf-update-riece)))
+
+(defun emchat-wharf-riece-inactive ()
+  "Make the EMchatWharf Riece indicator inactive."
+  (let ((emchat-riece-activity nil))
+    (emchat-wharf-update-riece)))
+
+(defun emchat-wharf-update-riece ()
+  "Update the status line in EMchatWharf."
+  (when emchat-wharf-buf
+    (save-excursion
+      (set-buffer emchat-wharf-buf)
+      (goto-line 4)
+      (delete-region (point-at-bol) (point-at-eol))
+      (insert-face "Riece" (if emchat-riece-activity
+                              'emchat-wharf-riece-active-face
+                            'emchat-wharf-riece-inactive-face)))))
+
+;;;###autoload
+(defun emchat-wharf-new-frame ()
+  "Create new EMchatWharf frame."
+  (unless (frame-live-p emchat-wharf-frame)
+    (setq emchat-wharf-frame (new-frame emchat-wharf-frame-props))
+    (select-frame emchat-wharf-frame)
+    (unless (buffer-live-p emchat-wharf-buf)
+      (setq emchat-wharf-buf (get-buffer-create "*EMchatWharf*"))
+      (set-buffer-dedicated-frame emchat-wharf-buf emchat-wharf-frame)
+      (save-excursion
+        (set-buffer emchat-wharf-buf)
+        (insert "New 000\nSys 000\n")
+        (set-extent-face (make-extent (point-min) (point-max) emchat-wharf-buf)
+                         'emchat-wharf-default-face)
+       (insert-face emchat-user-status (emchat-status-face emchat-user-status))
+       (when emchat-wharf-notice-riece-flag
+         (insert "\n")
+         (insert-face "Riece" (if emchat-riece-activity
+                                  'emchat-wharf-riece-active-face
+                                'emchat-wharf-riece-inactive-face)))
+        ))
+    (if (fboundp 'set-specifier)
+        (progn
+          (set-specifier horizontal-scrollbar-visible-p nil
+                         (cons emchat-wharf-frame nil))
+          (set-specifier vertical-scrollbar-visible-p nil
+                         (cons emchat-wharf-frame nil))))
+    (set-face-font 'default
+                   (face-font-name 'emchat-wharf-default-face)
+                   emchat-wharf-frame)
+    (set-window-buffer nil emchat-wharf-buf)))
+
+(defun emchat-wharf-change-messages (type num)
+  (let (oldnum newnum)
+    (if emchat-wharf-buf
+        (save-excursion
+          (set-buffer emchat-wharf-buf)
+          (goto-char (point-min))
+          (if (re-search-forward (concat "^\\("
+                                         type
+                                         " *\\([0-9]+\\)\\)$")
+                                 nil t)
+              (progn
+                (setq oldnum (string-to-int (match-string 2))
+                      newnum (+ oldnum num))
+                (if (> 0 newnum)
+                    (setq newnum 0))
+                (replace-match (format "%-3s %03d" type newnum))))))))
+
+(defun emchat-wharf-inc-messages ()
+  "Increment number of new messages in EMchatWharf."
+  (emchat-wharf-change-messages "New" 1))
+
+(defun emchat-wharf-dec-messages ()
+  "Decrement number of new messages in EMchatWharf."
+  (emchat-wharf-change-messages "New" -1))
+
+(defun emchat-wharf-inc-system ()
+  "Increment number of system messages in EMchatWharf."
+  (emchat-wharf-change-messages "Sys" 1))
+
+(defun emchat-wharf-dec-system ()
+  "Decrement number of system messages in EMchatWharf."
+  (emchat-wharf-change-messages "Sys" -1))
+
+(defun emchat-wharf-update-status ()
+  "Update the status line in EMchatWharf."
+  (when emchat-wharf-buf
+    (save-excursion
+      (set-buffer emchat-wharf-buf)
+      (goto-line 3)
+      (delete-region (point-at-bol) (point-at-eol))
+      (insert-face emchat-user-status (emchat-status-face emchat-user-status)))))
+
+(provide 'emchat-wharf)
+;;; emchat-wharf.el ends here
diff --git a/emchat-world.el b/emchat-world.el
new file mode 100644 (file)
index 0000000..1211bd6
--- /dev/null
@@ -0,0 +1,515 @@
+;;; emchat-world.el --- EMchat contact list management
+
+;; Copyright (C) 2002 - 2007 Steve Youngs
+
+;; Author:        Steve Youngs <steve@emchat.org>
+;; Maintainer:    Steve Youngs <steve@emchat.org>
+;; Created:       2002-10-01
+;; Homepage:      http://www.emchat.org/
+;; Keywords:      comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;;
+
+(eval-and-compile
+  (require 'emchat-meta)
+  (require 'emchat-menu))
+
+(autoload 'emchat-search-by-uin "emchat" nil t)
+(autoload 'emchat-buddy-show-buffer "emchat-buddy" nil t)
+(autoload 'emchat-process-alias-input "emchat")
+(autoload 'emchat-buddy-update-face "emchat-buddy")
+(autoload 'emchat-completing-aliases "emchat")
+(autoload 'emchat-valid-uin-p "emchat")
+
+(eval-when-compile
+  (require 'font-lock)
+  (require 'sort))
+
+(defcustom emchat-world-rc-filename (expand-file-name "world" emchat-directory)
+  "*Filename for resource file."
+  :type 'file
+  :group 'emchat-info)
+
+(defcustom emchat-recently-added-by-filename
+  (expand-file-name "recent-adds" emchat-directory)
+  "*File containing UIN's of people who have added you to their list."
+  :type 'file
+  :group 'emchat-info)
+
+(defcustom emchat-world-track-all-adds nil
+  "*When non-nil, every UIN of people adding you is tracked.
+
+The default, nil, means that only people who are not in your contact
+list will be tracked."
+  :type 'boolean
+  :group 'emchat-info)
+
+(defvar emchat-world-recently-added-by nil
+  "Contains the UIN's of anyone who adds you to their list.
+
+This is for the current session only.  But these people are saved in
+`emchat-recently-added-by-filename' for future reference.")
+
+;;; Internal variables
+
+(defcustom emchat-user-alias "me"
+  "*Your alias in `emchat-world'.
+Run `emchat-world-update' after modifying this variable."
+  :group 'emchat-info)
+
+(defvar emchat-user-bin nil
+  "User alias in binary string.
+The mere purpose is to speed up operations.
+Updated by `emchat-world-update'.")
+
+(defvar emchat-all-uin nil
+  "All uin in `emchat-world'.
+The mere purpose is to speed up operations.
+Updated by `emchat-world-update'.")
+
+(defvar emchat-world nil
+  "List of alias, uin, and plist.")
+
+(defvar emchat-all-aliases nil
+  "All aliases in `emchat-world'.
+The mere purpose is to speed up operations.
+Updated by `emchat-world-update'.")
+
+(defvar emchat-add-user-p nil)
+(defvar emchat-new-buddy nil)
+(defvar emchat-world-new-user-hash nil)
+
+(eval-and-compile
+  (unless (featurep 'sxemacs)
+    (defalias #'defregexp #'defconst)))
+
+(defregexp emchat-world-ssi-LastUpdateTime-regexp
+  (if (featurep '(or sxemacs raw-strings))
+      #r"^::LastUpdateTime:\s-(\([0-9]+\)\s-.\s-\([0-9]+\))$"
+    "^::LastUpdateTime:\\s-(\\([0-9]+\\)\\s-.\\s-\\([0-9]+\\))$")
+  "Regular expression to match the last update time in world.")
+
+(defregexp emchat-world-ssi-count-regexp
+  (if (featurep '(or sxemacs raw-strings))
+      #r"^::Count:\s-\(.*\)$"
+    "^::Count:\\s-\\(.*\\)$")
+  "Regular expression to match the entries count in world.")
+
+(defregexp emchat-world-ssi-id-regexp
+  (if (featurep '(or sxemacs raw-strings))
+      #r"\(?:[         ]{SSIgrp=\([0-9]+\)[    ]SSIid=\([0-9]+\)}\)"
+    "\\(?:[    ]{SSIgrp=\\([0-9]+\\)[  ]SSIid=\\([0-9]+\\)}\\)")
+  "Regular expression matching SSI id numbers in world.")
+
+(defregexp emchat-world-rc-regexp
+  (if (featurep '(or sxemacs raw-strings))
+      #r"^:icq[        ]+\([0-9]+\)[   ]+\([^:]+?\)[   ]?\(:.*\)*$"
+    "^:icq[    ]+\\([0-9]+\\)[         ]+\\([^:]+?\\)[         ]?\\(:.*\\)*$")
+  "Regular expression for rc file.
+Format: :icq uin alias group(s)
+Group is prefixed by a colon :.  Anything between uin and group including
+white spaces is alias.  For example,
+
+:icq 409533 fire :linux :emchat
+:icq 123456 the hatter :unreal
+
+The regexp paren groupings are as follows:
+
+  1 -- UIN
+  2 -- Alias
+  3 -- groups \(local, not SSI\)")
+
+(defun emchat-world-ssi-mod-time ()
+  "Extract and return the last update time from local copy of SSI.
+
+This time is kept in `emchat-world-rc-filename', if it doesn't exist,
+return zero."
+  (let ((modt (cons 0 0)))
+    (with-current-buffer (find-file-noselect emchat-world-rc-filename)
+      (goto-char (point-max))
+      (when (re-search-backward emchat-world-ssi-LastUpdateTime-regexp nil t)
+       (setq modt (cons (string-to-number (match-string 1))
+                        (string-to-number (match-string 2)))))
+      modt)))
+
+(defun emchat-world-ssi-count ()
+  "Extract and return the item count from local copy of SSI.
+
+This count is kept in `emchat-world-rc-filename', if it doesn't exist,
+return zero."
+  (let ((count 0))
+    (with-current-buffer (find-file-noselect emchat-world-rc-filename)
+      (goto-char (point-max))
+      (when (re-search-backward emchat-world-ssi-count-regexp nil t)
+       (setq count (string-to-number (match-string 1))))
+      count)))
+
+(defun emchat-world-update-world-count (count time)
+  "Update the entries COUNT and LastUpdateTime TIME in world."
+  (with-current-buffer (find-file-noselect emchat-world-rc-filename)
+    (goto-char (point-max))
+    (condition-case nil
+       (progn
+         (save-excursion
+           (re-search-backward emchat-world-ssi-LastUpdateTime-regexp)
+           (replace-string
+            (substring (match-string 0)
+                       (- (+ 5 (length (match-string 1))
+                             (length (match-string 2)))))
+            (format "%S" time)))
+         (re-search-backward emchat-world-ssi-count-regexp)
+         (replace-string (match-string 1) (format "%d" count)))
+      ;; count/time markers don't exist, add em.
+      (t
+       (goto-char (point-at-bol))
+       (insert (format "::Count: %d\n" count)
+              (format "::LastUpdateTime: %S" time))))
+    (save-buffer)
+    (kill-buffer nil)))
+
+(defun emchat-world-ssi-grp ()
+  "Return the first non-zero SSI group ID to use for new contacts."
+  (let ((buf (find-file-noselect emchat-world-rc-filename))
+       (id nil))
+    (with-current-buffer buf
+      (goto-char (point-min))
+      (while (not id)
+       (re-search-forward emchat-world-ssi-id-regexp nil t)
+       (unless (zerop (string-to-number (match-string 1)))
+         (setq id (string-to-number (match-string 1))))))
+    id))
+
+(defun emchat-world-next-ssi-id ()
+  "Return the next server side contact ID number."
+  (let ((buf (find-file-noselect emchat-world-rc-filename))
+       (idlist nil))
+    (with-current-buffer buf
+      (goto-char (point-min))
+      (while (re-search-forward emchat-world-ssi-id-regexp nil t)
+       (push (string-to-number (match-string 2)) idlist)))
+    (1+ (apply #'max idlist))))
+
+(defun emchat-world-sync-ssi-maybe (uin grpid id alias)
+  "Possibly synchronise entries from SSI to local world.
+
+UIN is the UIN of the contact.
+GRPID is the SSI group id number \(needed for modifying/deleting\).
+ID is the SSI id of this contact \(needed for modifying/deleting\).
+ALIAS is the \"nick\" of the contact as listed in your SSI.
+
+Note that you shouldn't call this function directly, it doesn't
+save any changes it makes to your world file.  That is done by
+`emchat-v8-snac-srv-ssi-reply', which calls this."
+  (let ((world (find-file-noselect emchat-world-rc-filename))
+       (known-uin (member (emchat-stringular-uin uin) emchat-all-uin)))
+    (with-current-buffer world
+      (goto-char (point-min))
+      (if known-uin
+         (when (re-search-forward (regexp-quote (emchat-stringular-uin uin)))
+           (if (re-search-forward emchat-world-ssi-id-regexp (point-at-eol) t)
+               (progn
+                 (or (= grpid (string-to-number (match-string 1)))
+                     (replace-match (match-string 1) (format "%s" grpid)))
+                 (or (= id (string-to-number (match-string 2)))
+                     (replace-match (match-string 2) (format "%s" id))))
+             (goto-char (point-at-eol))
+             (insert (format " {SSIgrp=%s SSIid=%s}" grpid id))))
+       (or (and (re-search-forward emchat-world-ssi-count-regexp nil t)
+                (forward-line -1))
+           (goto-char (point-max)))
+       (insert (format "\n:icq %s %s {SSIgrp=%s SSIid=%s}\n"
+                       uin (aref alias 0) grpid id))
+       (emchat-add-new-user-to-buddy-buffer
+        (emchat-stringular-uin uin) (aref alias 0))))))
+      
+(defun emchat-world-add-new-user ()
+  "Add a new user to world."
+  (let ((uin (gethash :uin emchat-world-new-user-hash))
+       (nick (gethash :nick emchat-world-new-user-hash))
+       (ssi-grp (gethash :ssi-grp emchat-world-new-user-hash))
+       (id (gethash :id emchat-world-new-user-hash))
+       (egrps (gethash :egrps emchat-world-new-user-hash))
+       (status (gethash :status emchat-world-new-user-hash)))
+    (set-buffer
+     (find-file-noselect (expand-file-name emchat-world-rc-filename)))
+    (goto-char (point-max))
+    (if (re-search-backward emchat-world-ssi-count-regexp nil t)
+       (progn
+         (insert (format ":icq %d %s %s {SSIgrp=%d SSIid=%d}\n\n"
+                         uin nick egrps ssi-grp id))
+         (save-buffer (current-buffer))
+         (kill-buffer (current-buffer))
+         ;; Inform the user in the log.
+         (emchat-log-info
+          (emchat-decode-string
+           (format "Alias: %s, UIN: %d added to contact list."
+                   nick uin)))
+         (emchat-add-new-user-to-buddy-buffer
+          (emchat-stringular-uin uin) nick status))
+      (emchat-log-error "Malformed world file"))))
+
+(defun emchat-add-new-user-to-buddy-buffer (uin nick &optional status)
+  "Push the nick name from `emchat-add-user' into the buddy buffer.
+Sort of a cut-down version or `emchat-world-update'"
+  (if (member uin emchat-all-uin)
+      (emchat-log-error "%s is already in your contact list" nick)
+    (if (or (null status)
+           (and (eq status 'online)
+                (not (eq emchat-buddy-view 'emchat-active-aliases)))
+           (and (eq status 'offline)
+                (eq emchat-buddy-view 'emchat-all-aliases)))
+       (add-to-list (symbol-value 'emchat-buddy-view) nick))
+
+    (let* ((bhelp (format "%s (%s)\n\n Status: %s\n Groups: %s\nHistory: %s\n"
+                         nick 
+                         uin
+                         (or (emchat-world-getf nick 'status) "offline")
+                         (or (emchat-world-getf nick 'group) "none")
+                         (or (emchat-world-getf nick 'history) "none"))))
+      (set-extent-properties
+       (make-extent 0 (length nick) nick)
+       `(highlight t duplicable t start-open t keymap ,emchat-alias-map
+                  balloon-help ,bhelp)))
+    (save-excursion
+      (set-buffer (find-file-noselect emchat-world-rc-filename))
+      (goto-char (point-max))
+      (search-backward-regexp emchat-world-rc-regexp nil t)
+      (let* ((buddy (list nick uin 'rc-index (point))))
+       (push buddy emchat-world)))
+    (setq emchat-all-aliases (mapcar 'first emchat-world))
+    (setq emchat-all-uin (mapcar 'second emchat-world))
+    (emchat-buddy-show-buffer 'new 'no-select)
+    (setq emchat-add-user-p nil)))
+
+;;; Code - group:
+
+(defun emchat-group-put (group name)
+  "Put something into GROUP.
+NAME can be either an alias or another group name."
+  (let ((list (assoc group emchat-world)))
+    (cond
+     (list
+      (setcdr list (list (pushnew name (cadr list) :test 'equal))))
+     (t
+      (push (list group (list name)) emchat-world)))))
+
+(defun emchat-group-get (group)
+  "Get members from GROUP."
+  (cadr (assoc group emchat-world)))
+
+(defun emchat-group-get-all-aliases (group)
+  "Recursively get all aliases from GROUP."
+  (loop for x in (emchat-group-get group)
+    as expanded-x = (emchat-group-get x)
+    if (atom expanded-x) collect x
+    else append (emchat-group-get-all-aliases x)))
+
+(defun emchat-group-select-aliases (state &rest aliases)
+  "Select aliases and update buddy buffer.
+Nil STATE means deselect, 'toggle means invert current state, and other
+non-nil means select.
+
+See `emchat-process-alias-input'."
+  (interactive '(select))
+  (emchat-process-alias-input 'aliases)
+  (loop for x in aliases
+    do (when (eq state 'toggle)
+        (setq state (not (emchat-world-getf x 'selected))))
+    do (emchat-world-putf x 'selected state)
+    do (emchat-buddy-update-face x))
+  (emchat-buddy-show-buffer 'new 'noselect))
+
+(defun emchat-world-getf (alias tag)
+  "For ALIAS get property of TAG.
+If TAG is 'all, return the plist."
+  (let ((plist (cddr (assoc alias emchat-world))))
+    (if (eq tag 'all)
+        plist
+      (getf plist tag))))
+
+(defun emchat-world-putf (alias tag value)
+  "For ALIAS put property of TAG with VALUE."
+  (let* ((buddy (assoc alias emchat-world))
+         (plist (cddr buddy)))
+    (if buddy (setcdr (cdr buddy) (putf plist tag value)))))
+
+(defun emchat-alias-uin (alias)
+  "Return an uin from an ALIAS in `emchat-world'.
+Return uin if ALIAS is already an uin.
+Return 0 if no corresponding uin or invalid uin.
+If called interactively, display and push uin into `kill-ring'."
+  (interactive (emchat-completing-aliases "UIN from alias: " 'single))
+  (let ((uin (second (assoc alias emchat-world))))
+    (unless uin
+      (when (emchat-valid-uin-p alias)
+        (setq uin alias)))
+    (when (interactive-p)
+      (message uin)
+      (kill-new uin))
+    uin))
+
+(defun emchat-uin-alias (uin)
+  "Return an alias from an UIN in `emchat-world'.
+Return UIN if no corresponding ALIAS.
+If called interactively, display and push alias into `kill-ring'."
+  (interactive (list (read-string "alias from uin: ")))
+  (let ((alias (or (first (find uin emchat-world :key 'second :test 'string=))
+                   ;; not found, return uin
+                   uin)))
+    (when (interactive-p)
+      (message alias)
+      (kill-new alias))
+    alias))
+
+;;;###autoload
+(defun emchat-world-update ()
+  "Read `emchat-world-rc-filename' and update various user variables.
+Need to call this whenever RC is modified and to be updated.
+RC file is not closed if it is the buffer of current window or it is modified."
+  (interactive)
+  (save-excursion
+    (let (no-killing-at-last)
+      (setq emchat-world nil)
+      (set-buffer (find-file-noselect emchat-world-rc-filename))
+      ;; don't kill if rc file is buffer in current window
+      (setq no-killing-at-last
+            (or (buffer-modified-p)
+                (eq (window-buffer) (current-buffer))))
+      (goto-char (point-min))
+      (while (search-forward-regexp emchat-world-rc-regexp nil t)
+        (let* ((uin (match-string 1))
+               (alias (replace-regexp-in-string
+                      emchat-world-ssi-id-regexp ""
+                      (match-string 2)))
+               (group (replace-regexp-in-string
+                      emchat-world-ssi-id-regexp ""
+                      (or (match-string 3) "")))
+               buddy)
+
+          ;; idea from Erik Arneson <erik@starseed.com>
+          (set-extent-properties
+           ;; We may consider moving to emchat-uin-alias or somewhere else, if
+           ;; we don't want to waste enourmous unused extents.
+           (make-extent 0 (length alias) alias)
+           `(highlight t duplicable t start-open t keymap ,emchat-alias-map))
+
+          (setq buddy (list alias uin 'rc-index (point)))
+
+          ;; group stuff not used yet
+          (if group
+              (setq buddy
+                    (append buddy (read (format "(group (%s))" group)))))
+          (push buddy emchat-world)))
+      (setq emchat-world (nreverse emchat-world))
+      (unless no-killing-at-last
+       (kill-buffer (current-buffer)))))
+
+  (setq emchat-all-aliases (mapcar 'first emchat-world))
+  (setq emchat-all-uin (mapcar 'second emchat-world))
+  ;; Add history files to emchat-world if enabled
+  (when emchat-history-enabled-flag
+    (mapcar
+     #'(lambda (alias)
+        (emchat-world-putf alias 'history
+                           (expand-file-name alias emchat-history-directory)))
+     emchat-all-aliases)))
+
+(defun emchat-world-info (alias)
+  "Return local info of buddy ALIAS."
+  ;; TODO
+  (assoc alias emchat-world))
+
+;;; FIXME: Putting the rc file into `outline-minor-mode' is throwing a
+;;; "keymapp nil" error.
+(defun world-mode ()
+  "emchat resource file mode.
+Quick hack for font-lock. Each record is separated by \"==== \" at the
+beginning of the line."
+  (interactive)
+  (kill-all-local-variables)
+  (setq mode-name "world")
+  (setq major-mode 'world-mode)
+  (setq fill-column 100)
+  (auto-fill-mode 1)
+  ;; hiding details for privacy
+  ;(outline-minor-mode)
+  ;(set (make-local-variable 'outline-regexp)
+  ;     "==== ")
+  (setq font-lock-keywords
+       ;; highlight separator
+       '(("^==== " 0 font-lock-warning-face t)
+         ;; highlight keyword prefixed with :
+         (":\\(\\w\\|-\\)+" 0 font-lock-reference-face t)))
+  (font-lock-mode 1))
+
+(defun world-sort ()
+  (interactive)
+  (beginning-of-buffer)
+  (sort-subr nil 'world-next-friend 'world-end-friend))
+
+(defun world-next-friend ()
+  (interactive)
+  (let ((result (search-forward "====" nil t)))
+    ;; go back before ====
+    (if result (backward-char 4)
+      ;; required by sort-subr
+      (end-of-buffer))))
+
+(defun world-end-friend ()
+  (interactive)
+  ;; skip current friend
+  (forward-char 1)
+  (let ((result (search-forward "====" nil t)))
+    ;; go back before ====
+    (if result (backward-char 5)
+      (end-of-buffer))))
+
+(defun world-find (alias)
+  "Goto a friend record of ALIAS in `emchat-world-rc-filename'.
+Prefix argument means do not use (load) emchat completing alias feature."
+  (interactive
+   (if current-prefix-arg
+       (list (read-string "find: "))
+     (progn
+       (require 'emchat)
+       (emchat-completing-aliases "find: " 'single))))
+  (find-file emchat-world-rc-filename)
+  (goto-char (point-min))
+  (re-search-forward
+   (concat "^:icq.*?"
+           (regexp-quote alias)
+           "\\b.*$")))
+
+(provide 'emchat-world)
+
+;;; emchat-world.el ends here
diff --git a/emchat-xwem.el b/emchat-xwem.el
new file mode 100644 (file)
index 0000000..4dcffe2
--- /dev/null
@@ -0,0 +1,437 @@
+;; emchat-xwem.el --- Activity indicator for XWEM tray
+
+;; Copyright (C) 2005 - 2007 Steve Youngs
+
+;; Author:        Steve Youngs <steve@emchat.org>
+;; Maintainer:    Steve Youngs <steve@emchat.org>
+;; Created:       <2005-10-15>
+;; Homepage:      http://www.emchat.org/
+;; Keywords:      emchat, icq, xwem, dock, tray
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;; 
+;;    Puts a spiffy activity indicator into the XWEM systray.
+;;    To use this, add...
+;;
+;;          (require 'emchat-xwem)
+;;          (add-hook 'xwem-after-init-hook 'emchat-xwem-init)
+;;
+;;    ...to your ~/.xwem/xwemrc.el
+;;
+
+;;; Todo:
+;;
+;;     o Add more XWEM things... can't think of any right now.
+;;
+
+;;; Code:
+(require 'font) ;; for font-x-registry-and-encoding-regexp
+
+(eval-when-compile
+  (autoload 'xwem-dpy "xwem-struct" nil nil 'macro)
+  (autoload 'xwem-message "xwem-misc")
+  (autoload 'xwem-misc-find-cl-by-emacs-frame "xwem-misc")
+  (autoload 'xwem-osd-clear "xwem-osd")
+  (autoload 'xwem-osd-create "xwem-osd")
+  (autoload 'xwem-osd-create-dock "xwem-osd")
+  (autoload 'xwem-osd-destroy "xwem-osd")
+  (autoload 'xwem-osd-destroy-instances "xwem-osd")
+  (autoload 'xwem-osd-get-prop "xwem-osd")
+  (autoload 'xwem-osd-hide "xwem-osd")
+  (autoload 'xwem-osd-icon-data-add "xwem-osd")
+  (autoload 'xwem-osd-p "xwem-osd")
+  (autoload 'xwem-osd-put-prop "xwem-osd")
+  (autoload 'xwem-osd-rem-prop "xwem-osd")
+  (autoload 'xwem-osd-set-color "xwem-osd")
+  (autoload 'xwem-osd-set-font "xwem-osd")
+  (autoload 'xwem-osd-show "xwem-osd")
+  (autoload 'xwem-osd-text "xwem-osd")
+  (autoload 'xwem-osd-text-add "xwem-osd")
+  (autoload 'xwem-popup-menu "xwem-mouse")
+  (autoload 'xwem-select-client "xwem-clients")
+  (defvar xwem-current-cl)
+  )
+
+(defgroup emchat-xwem nil
+  "Group to customize emchat's xwem capabilities."
+  :group 'emchat
+  :prefix "emchat-xwem-")
+
+(defcustom emchat-xwem-osd-enable t
+  "*Non-nil to show incoming messages in OSD."
+  :group 'emchat-xwem
+  :type 'boolean)
+
+(defcustom emchat-xwem-dock-enable t
+  "*Non-nil to start emchat dock in system tray."
+  :group 'emchat-xwem
+  :type 'boolean)
+
+(defcustom emchat-xwem-osd-show-icon t
+  "*Non-nil to show ICQ icon in OSD as well as message."
+  :group 'emchat-xwem
+  :type 'boolean)
+
+(defcustom emchat-xwem-osd-font
+  (font-create-name (make-font :weight "bold" :size 32))
+  "Font to be used to display OSD message."
+  :group 'emchat-xwem
+  :type '(restricted-sexp :match-alternatives (nil try-font-name)))
+
+(defcustom emchat-xwem-osd-color "magenta3"
+  "*Default color for OSD messages."
+  :group 'emchat-xwem
+  :type 'color)
+  
+(defcustom emchat-xwem-osd-group-colors
+  '((:girls . "deeppink")
+    (:vip . "gold")
+    (:work . "red3")
+    (:friends . "green3"))
+  "*Alist of colors to be used in OSD for emchat groups.
+Each element is cons in form (GROUP . COLOR)."
+  :group 'emchat-xwem
+  :type '(repeat (cons (keyword :tag "group") color)))
+
+(defcustom emchat-xwem-osd-coordinates '(100 . 700)
+  "*Place on screen for OSD messages."
+  :group 'emchat-xwem
+  :type '(cons (number :tag "X") (number :tag "Y")))
+
+(defcustom emchat-xwem-osd-display-time 3
+  "*Time the OSD to be shown."
+  :group 'emchat-xwem
+  :type 'number)
+
+;;; Internal variables
+
+(defvar emchat-xwem-osd-icon
+  (concat "/* XPM */\n"
+"static char *icq[] = {\n"
+"/* columns rows colors chars-per-pixel */\n"
+"\"50 50 8 1\",\n"
+"\"  c #09090C\",\n"
+"\". c #385930\",\n"
+"\"X c #43FD32\",\n"
+"\"o c #33C326\",\n"
+"\"O c #ECE345\",\n"
+"\"+ c #C5C6C7\",\n"
+"\"@ c None\",\n"
+"\"# c #DC3129\",\n"
+"/* pixels */\n"
+"\"@@@@@@@@@@@@@@@@@@@@@@@@@@@@++.+.++@@@@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@@@@++++++@@@@@@++.      .+@@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@@@+     .+@@@@+.          +@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@@+       .+@@++    ....   .+@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@+    ..    +@.   oXXXXXo.   +@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@+   oXXo   .+   oXXXXXXXo   +@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@+  .XXXXo       XXXXXXXXXo  .+@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@.  oXXXXX.     oXXXXXXXXXo  .+@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@.  oXXXXXX     ooXXXXXXXXX   +@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@+  oXXXXXX.    oXXXXXXXXXo  .+@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@+   XXXXXXo    .XXXXXXXXX.  .@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@+   .XXXXoo    oXXXXXXXXX   ++++++@@@@@\",\n"
+"\"@@@@@@++...++   oXXXXo    .XXXXXXXX    ..  ..++@@@\",\n"
+"\"@@@+++   .       oXXXo    .XXXXXXX.     .     .+@@\",\n"
+"\"@@+.              oXXX     XXXXXX.             .+@\",\n"
+"\"@++    .....       oXX.    oXXXXo      .ooXo.   +@\",\n"
+"\"@+    XXXXXXo      .XXo    oXXXo      XXXXXXXo  .+\",\n"
+"\"+.  .XXXXXXXXo      .oo    oXXX     .XXXXXXXXo  .+\",\n"
+"\"+   XXXXXXXXXXX.      .    .XX     oXXXXXXXXXo  .+\",\n"
+"\"+  .XXXXXXXXXXXXo           ..    oXXXXXXXXXo   +@\",\n"
+"\".  .XXXXXXXXXXXXXX.             .oXXXXXXXXXo   .+@\",\n"
+"\".  .XXXXXXXXXXXXXX    .OOO.    .oXXXXXoooo     +@@\",\n"
+"\"+   oXXXXXXXXXXXoo   OOOOOOO   .oo..         .+@@@\",\n"
+"\"+.   ooXooooo...    .OOOOOOO.               .+@@@@\",\n"
+"\"@+.                 OOOOOOOOO                .+@@@\",\n"
+"\"@@+.                OOOOOOOOO                  +@@\",\n"
+"\"@@@++.              OOOOOOOO.       ..ooooo.    +@\",\n"
+"\"@@@@@+       # ###  .OOOOOOO.  .oXXXXXXXXXXXo.  .+\",\n"
+"\"@@@@+.    ########   .OOOOO.   oXXXXXXXXXXXXXo   +\",\n"
+"\"@@@+.   #########     .OOO.    .XXXXXXXXXXXXXX.  +\",\n"
+"\"@@@+   #########                .oXXXoXXXXXXXXo  .\",\n"
+"\"@@@+  #########     .       .    .oXXXXXXXXXXXo  .\",\n"
+"\"@@@+  ########      XXo   ooXo     oXXXXXXXXXXo  .\",\n"
+"\"@@@.   ######      oXXX   oXXX.     oXXXXXXXXX.  .\",\n"
+"\"@@@+              oXXXX   .XXXX.     .XXXXXXXo   +\",\n"
+"\"@@@@+.           oXXXXX.   oXXXX      .ooXXXo   ++\",\n"
+"\"@@@@@++.   .    ooXXXXX.   oXXXXX.       ..     +@\",\n"
+"\"@@@@@@@+++++   .XXXXXXX.   oXXXXXo            .+@@\",\n"
+"\"@@@@@@@@@@@.   XXXXXXXXo   .XXXXXo   ...     ++@@@\",\n"
+"\"@@@@@@@@@@+   oXXXXXXXX.   .XXXXXX.  +@++++++@@@@@\",\n"
+"\"@@@@@@@@@@+  .XXXXXXXXXo    XXXXXX.  .@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@.  .XXXXXXXXXo    .XXXXX   +@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@.  .XXXXXXXXXo     .XXXo   +@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@+  .XXXXXXXXX.      .oo.  .+@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@+   XXXXXXXXX   +.        +@@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@+.  .oXXXXXo.  .@+..    ..@@@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@+    ooXo.    +@@@++..++@@@@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@++           +@@@@@@@@@@@@@@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@@@+.       .+@@@@@@@@@@@@@@@@@@@@@@@@@@\",\n"
+"\"@@@@@@@@@@@@@@++.....++@@@@@@@@@@@@@@@@@@@@@@@@@@@\"\n"
+"};\n"))
+
+(defvar emchat-xwem-active
+  (concat "/* XPM */\n"
+"static char *noname[] = {\n"
+"/* columns rows colors chars-per-pixel */\n"
+"\"16 16 17 1\",\n"
+"\"  c #000100\",\n"
+"\". c #013200\",\n"
+"\"X c #31000b\",\n"
+"\"o c #2c2c00\",\n"
+"\"O c #035500\",\n"
+"\"+ c #037700\",\n"
+"\"@ c #4d0011\",\n"
+"\"# c #736f00\",\n"
+"\"$ c #068600\",\n"
+"\"% c #07ab00\",\n"
+"\"& c #09cb00\",\n"
+"\"* c #08ed00\",\n"
+"\"= c #a00024\",\n"
+"\"- c #d1002f\",\n"
+"\"; c #878200\",\n"
+"\": c #fff82a\",\n"
+"\"> c None\",\n"
+"/* pixels */\n"
+"\">>>>   >    >>>>\",\n"
+"\">>>  +   %&. >>>\",\n"
+"\">>> +*$ $**% >>>\",\n"
+"\">>>  *& +**$   >\",\n"
+"\">    O* +*%  .  \",\n"
+"\" O**O O..& .**$ \",\n"
+"\" &***$ oo O**%  \",\n"
+"\" O$+O #:: .    >\",\n"
+"\">   XX;::oO+++. \",\n"
+"\"> @--@ #o %***& \",\n"
+"\"> ==X $.OO +**& \",\n"
+"\">    $*OO*O O+. \",\n"
+"\">>> O**+.*&    >\",\n"
+"\">>> %**+ +& >>>>\",\n"
+"\">>> .&&    >>>>>\",\n"
+"\">>>>    >>>>>>>\>\"\n"
+"};\n"))
+
+(defvar emchat-xwem-inactive
+  (concat "/* XPM */\n"
+"static char *noname[] = {\n"
+"\"16 16 7 1\",\n"
+"\"    c None\",\n"
+"\".   c #000100 s foreground\",\n"
+"\"+   c #013200\",\n"
+"\"@   c #2C2C00\",\n"
+"\"#   c #000000\",\n"
+"\"$   c #31000B\",\n"
+"\"o   c gray s background\",\n"
+"/* pixels */\n"
+"\"    ... ....    \",\n"
+"\"   ..o...oo+.   \",\n"
+"\"   .ooo.oooo.   \",\n"
+"\"   ..oo.oooo... \",\n"
+"\" ....oo.ooo..+..\",\n"
+"\".oooo.o++o.oooo.\",\n"
+"\".ooooo.@@.oooo..\",\n"
+"\".oooo.ooo.+.... \",\n"
+"\" ...#$ooo@oooo+.\",\n"
+"\" .ooo#.o@.ooooo.\",\n"
+"\" .oo$oo+oo.oooo.\",\n"
+"\" ....ooo#oo.oo+.\",\n"
+"\"   .oooo#oo.... \",\n"
+"\"   .oooo.oo.    \",\n"
+"\"   .+oo....     \",\n"
+"\"    ....        \"\n"
+"};\n"))
+
+(defvar emchat-xwem-saved-client nil
+  "Saved selected xwem client.")
+
+(defvar emchat-xwem-keymap
+  (let ((map (make-sparse-keymap)))
+    (define-key map [button1] 'emchat-xwem-select-emchat)
+    (define-key map [button3] 'emchat-xwem-restore-client)
+    map)
+  "*Keymap for emchat dock.")
+
+(defvar emchat-xwem-osd nil)
+(defvar emchat-xwem-dock nil)
+
+\f
+(defun emchat-xwem-activity-off ()
+  "Make the EMchat/XWEM activity indicator inactive."
+  (emchat-xwem-dock-change-icon emchat-xwem-inactive)
+  (emchat-xwem-osd-hide))
+
+(defun emchat-xwem-activity-on ()
+  "Make the EMchat/XWEM activity indicator active."
+  (emchat-xwem-dock-change-icon emchat-xwem-active)
+
+  ;; NICK and MESSAGE are set by dynamic binding
+  (declare (special nick message))
+  (emchat-xwem-osd-show-message nick message))
+
+(defun emchat-xwem-init ()
+  "*Display EMchat activity indicator."
+  (interactive)
+
+  ;; Possible create dock
+  (emchat-xwem-dock-change-icon emchat-xwem-inactive)
+
+  (add-hook 'emchat-track-activity-hook 'emchat-xwem-activity-on)
+  (add-hook 'emchat-track-clear-hook 'emchat-xwem-activity-off))
+
+(defun emchat-xwem-fini ()
+  "Remove the EMchat activity indicator from the XWEM systray."
+  (interactive)
+
+  (emchat-xwem-dock-destroy)
+  (emchat-xwem-osd-destroy)
+
+  (remove-hook 'emchat-track-activity-hook 'emchat-xwem-activity-on)
+  (remove-hook 'emchat-track-clear-hook 'emchat-xwem-activity-off))
+
+\f
+;; OSD
+(defun emchat-xwem-osd-create ()
+  "Create OSD for emchat messages."
+  (setq emchat-xwem-osd
+        (xwem-osd-create (xwem-dpy) (car emchat-xwem-osd-coordinates)
+                             (cdr emchat-xwem-osd-coordinates)
+                             2048 1024))
+  (xwem-osd-set-font emchat-xwem-osd emchat-xwem-osd-font))
+
+(defun emchat-xwem-osd-destroy ()
+  "Destroy emchat OSD."
+  (when emchat-xwem-osd
+    (when (itimerp (xwem-osd-get-prop emchat-xwem-osd 'timer))
+      (delete-itimer (xwem-osd-get-prop emchat-xwem-osd 'timer)))
+    (xwem-osd-destroy emchat-xwem-osd)
+    (setq emchat-xwem-osd nil)))
+
+(defun emchat-xwem-osd-color-for-nick (nick)
+  "Return OSD color to use for NICK."
+  (let ((groups (plist-get (assoc nick emchat-world) 'group)))
+    (or (cdr (find groups emchat-xwem-osd-group-colors
+                   :key #'car :test #'(lambda (g i)
+                                        (member i g))))
+        emchat-xwem-osd-color)))
+
+(defun emchat-xwem-osd-show-message (nick message)
+  "Display NICK and MESSAGE in emchat OSD."
+  (when emchat-xwem-osd-enable
+    (unless emchat-xwem-osd
+      (emchat-xwem-osd-create))
+
+    ;; Find and set proper color
+    (xwem-osd-set-color emchat-xwem-osd (emchat-xwem-osd-color-for-nick nick))
+
+    ;; Just make sure OSD is clear
+    (xwem-osd-clear emchat-xwem-osd)
+
+    (when emchat-xwem-osd-show-icon
+      (xwem-osd-icon-data-add emchat-xwem-osd emchat-xwem-osd-icon))
+    (xwem-osd-text-add
+     emchat-xwem-osd
+     (if emchat-xwem-osd-show-icon
+         (glyph-width (make-glyph (vector 'xpm :data emchat-xwem-osd-icon)))
+       0) 0
+     (encode-coding-string
+      (format "%s: %s" nick message)
+      (and (string-match font-x-registry-and-encoding-regexp
+                         emchat-xwem-osd-font)
+           (intern (downcase (format "%s-%s"
+                                     (match-string 1 emchat-xwem-osd-font)
+                                     (match-string 2 emchat-xwem-osd-font)))))
+      ))
+
+    (xwem-osd-show emchat-xwem-osd)
+
+    (when (itimerp (xwem-osd-get-prop emchat-xwem-osd 'timer))
+      (delete-itimer (xwem-osd-get-prop emchat-xwem-osd 'timer)))
+    (xwem-osd-put-prop emchat-xwem-osd 'timer
+      (start-itimer "emchat-osd" #'emchat-xwem-osd-hide
+                    emchat-xwem-osd-display-time))))
+
+(defun emchat-xwem-osd-hide ()
+  "Hide emchat OSD."
+  (when (xwem-osd-p emchat-xwem-osd)
+     (xwem-osd-hide emchat-xwem-osd)
+     (xwem-osd-destroy-instances emchat-xwem-osd)
+    (when (itimerp (xwem-osd-get-prop emchat-xwem-osd 'timer))
+      (delete-itimer (xwem-osd-get-prop emchat-xwem-osd 'timer)))
+    (xwem-osd-rem-prop emchat-xwem-osd 'timer)))
+
+;; Dock
+(defun emchat-xwem-dock-create ()
+  "Create emchat dock."
+  (setq emchat-xwem-dock
+        (xwem-osd-create-dock (xwem-dpy) 16 16
+                              (list 'keymap emchat-xwem-keymap)))
+  (xwem-osd-show emchat-xwem-dock))
+
+(defun emchat-xwem-dock-destroy ()
+  "Destroy emchat dock."
+  (when (xwem-osd-p emchat-xwem-dock)
+    (xwem-osd-destroy emchat-xwem-dock))
+  (setq emchat-xwem-dock nil))
+
+(defun emchat-xwem-dock-change-icon (icon)
+  "Change emchat dock icon to ICON."
+  (when emchat-xwem-dock-enable
+    (unless emchat-xwem-dock
+      (emchat-xwem-dock-create))
+    (xwem-osd-icon-data-add emchat-xwem-dock icon)))
+
+\f
+;;; Commands
+
+;; Note: we can use ordinary Emacs commands here, because interactive
+;; form is empty, for complex commands we must use
+;; `define-xwem-command' and `xwem-interactive'.
+
+(defun emchat-xwem-select-emchat ()
+  "Make emchat be current client."
+  (interactive)
+  (let ((eicl (xwem-misc-find-cl-by-emacs-frame emchat-frame)))
+    (setq emchat-xwem-saved-client (xwem-cl-selected))
+    (xwem-select-client eicl)
+    (emchat-show-window)))
+
+(defun emchat-xwem-restore-client ()
+  "Display unseen senders."
+  (interactive)
+  (if (xwem-cl-alive-p emchat-xwem-saved-client)
+      (xwem-select-client emchat-xwem-saved-client)
+    (xwem-message 'warn "EMchat: Saved client dissapeared")))
+
+(provide 'emchat-xwem)
+;;; emchat-xwem.el ends here
+
diff --git a/emchat.el b/emchat.el
new file mode 100644 (file)
index 0000000..ef5eaca
--- /dev/null
+++ b/emchat.el
@@ -0,0 +1,2545 @@
+;;; emchat.el --- IM client for (S)XEmacs
+
+;; Copyright (C) 2000 - 2008 Steve Youngs
+
+;; Maintainer:     Steve Youngs <steve@emchat.org>
+;; Created:        Aug 08, 1998
+;; Homepage:       http://www.emchat.org/
+;; Keywords:       comm ICQ
+
+;; This file is part of EMchat.
+
+;; Redistribution and use in source and binary forms, with or without
+;; modification, are permitted provided that the following conditions
+;; are met:
+;;
+;; 1. Redistributions of source code must retain the above copyright
+;;    notice, this list of conditions and the following disclaimer.
+;;
+;; 2. Redistributions in binary form must reproduce the above copyright
+;;    notice, this list of conditions and the following disclaimer in the
+;;    documentation and/or other materials provided with the distribution.
+;;
+;; 3. Neither the name of the author nor the names of any contributors
+;;    may be used to endorse or promote products derived from this
+;;    software without specific prior written permission.
+;;
+;; THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
+;; IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+;; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+;; DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+;; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+;; CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+;; SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+;; BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+;; WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+;; OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+;; IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+;;; Commentary:
+;;
+;; Clone of Mirabilis ICQ communication client.
+;;
+;; Entry points:
+;;   emchat-login
+;;   emchat-show-window
+;;   emchat-customize
+;;
+;; See README & INSTALL which come with this package
+;;
+;; This project is done without the consent of Mirabilis.
+;;
+
+;;; Code:
+
+(eval-and-compile
+  (require 'emchat-utils)
+  (require 'timezone)
+  (require 'outline)
+  (require 'emchat-doctor))
+
+(eval-when-compile
+  (defvar emchat-add-user-success)
+  (defvar emchat-user-status)
+  (defvar emchat-user-initial-status)
+  (defvar emchat-buddy-buffer)
+  (defvar emchat-buddy-window-width)
+  (defvar emchat-status-buffer)
+  (defvar emchat-status-use-gutter)
+  (defvar emchat-status-window-height)
+  (defvar emchat-wharf-frame)
+  (defvar seq-num-bin)
+  (defvar seq-num)
+  (defvar user-bin)
+  (defvar local-year)
+  (defvar emchat-fix-nick)
+  (defvar emchat-wharf-frame-use-p)
+  (require 'ehelp)
+  (require 'cus-edit)
+  (require 'browse-url)
+  (require 'passwd)
+  (require 'regexp-opt)
+  (require 'toolbar-utils)
+  (autoload 'emchat-wharf-dec-messages "emchat-wharf"))
+
+(autoload 'emchat-status-auto-reply "emchat-status")
+(autoload 'emchat-status-idle-reply "emchat-status")
+(autoload 'emchat-status-name "emchat-status")
+(autoload 'emchat-change-status "emchat-status" nil t)
+(autoload 'emchat-status-show-buffer "emchat-status" nil t)
+(autoload 'emchat-update-tab-in-gutter "emchat-status")
+(autoload 'emchat-status-v8 "emchat-status")
+(autoload 'emchat-buddy-update-status "emchat-status")
+(autoload 'emchat-buddy-selected-in-view "emchat-buddy")
+(autoload 'emchat-buddy-show-buffer "emchat-buddy" nil t)
+(autoload 'emchat-buddy-select-all-in-view "emchat-buddy")
+
+;; Customize Groups.
+
+(defgroup emchat nil
+  "Mirabilis ICQ communication client."
+  :group 'comm)
+
+(defgroup emchat-info nil
+  "Essential account info."
+  :group 'emchat)
+
+(defgroup emchat-option nil
+  "System settings and general preferences."
+  :group 'emchat)
+
+(defgroup emchat-sound nil
+  "Sound preferences."
+  :group 'emchat)
+
+(defgroup emchat-interface nil
+  "Change the look and \"feel\"."
+  :group 'emchat)
+
+;; Customize.
+;;;###autoload
+(defcustom emchat-directory (file-name-as-directory
+                          (expand-file-name ".emchat" (user-home-directory)))
+  "*All EMchat support files and directories hang off this."
+  :type 'directory
+  :group 'emchat)
+
+;; Because of the incredibly complex and hairy twisted maze of
+;; inter-connections between the different EMchat libs, these
+;; emchat-history defcustoms are here instead of in
+;; emchat-history.el. --SY.
+(defgroup emchat-history nil
+  "History preferences."
+  :prefix "emchat-history-"
+  :group 'emchat)
+
+(defcustom emchat-history-enabled-flag nil
+  "*Non-nil means keep \"per-user\" histories."
+  :group 'emchat-history
+  :type 'boolean)
+
+(defcustom emchat-history-directory
+  (file-name-as-directory (expand-file-name "history" emchat-directory))
+  "*Directory path for storing \"per-user\" history files."
+  :type 'directory
+  :group 'emchat-history)
+
+(defcustom emchat-history-mode-hook nil
+  "*Hooks run in `emchat-history-mode'."
+  :type 'hook
+  :group 'emchat-history)
+
+;; This is here and not at the top because some of these libs use
+;; emchat-directory
+(eval-and-compile
+  (require 'emchat-log)
+  (require 'emchat-meta)
+  (require 'emchat-world)
+  (require 'emchat-v8)
+  (require 'emchat-version))
+
+(defcustom emchat-server "login.icq.com"
+  "*Server host to connect to."
+  :type 'string
+  :group 'emchat)
+
+(defcustom emchat-port 5401
+  "*Port to connect to."
+  :type 'number
+  :group 'emchat)
+
+;;;###autoload(autoload 'emchat-prefix "emchat-menu" nil nil 'keymap)
+(defun emchat-install-bindings (&optional sym value)
+  (when (eq (key-binding (symbol-value sym)) emchat-prefix)
+    (global-set-key (symbol-value sym) nil)) ; unbind old
+  (if (key-binding value)
+      (progn
+        (lwarn 'binding 'warning
+          "%S already bound, reseting `emchat-prefix-key'" value)
+        (set sym nil))
+    (global-set-key value emchat-prefix)
+    (set sym value)))
+
+(defcustom emchat-prefix-key [(meta ?`)]
+  "*Default global prefix key for EMchat.
+
+If you change this outside of the customize buffer you _MUST_ use
+`customize-set-variable', not `setq'."
+  :type 'sexp
+  :set 'emchat-install-bindings
+  :initialize 'custom-initialize-default
+  :group 'emchat)
+
+(defcustom emchat-use-sound-flag nil
+  "*Whether to use sound or not."
+  :group 'emchat-sound
+  :type 'boolean
+  :tag "Use Sound")
+
+(defcustom emchat-sound-directory
+  (file-name-as-directory (expand-file-name "sounds" emchat-directory))
+  "*Directory where sound files are kept."
+  :group 'emchat-sound
+  :type 'directory 
+  :tag "emchat-sound-directory")
+
+(defcustom emchat-sound-alist
+  '((message-sound . nil)
+    (chat-sound . nil)
+    (url-sound . nil)
+    (buddy-sound . nil)
+    (auth-sound . nil)
+    (emailx-sound . nil)
+    (pager-sound . nil)
+    (system-sound . nil))
+  "*Sound event to sound file alist.
+The possible sound events are:
+      \"message-sound\" - Incoming message sound.
+      \"chat-sound\"    - Incoming chat request sound.
+      \"url-sound\"     - Incoming url sound.
+      \"buddy-sound\"   - Online notify sound.
+      \"auth-sound\"    - Authorise sound.
+      \"emailx-sound\"  - Email express sound.
+      \"pager-sound\"   - Pager sound.
+      \"system-sound\"  - System message sound."
+  :group 'emchat-sound
+  :type '(repeat 
+         (cons (sexp :tag "Sound Event") 
+               (sexp :tag "Sound File")))
+  :tag "Sounds")
+
+(defcustom emchat-coding-system 
+  (when (featurep '(or mule file-coding))
+    (if (eq default-buffer-file-coding-system 'cyrillic)
+       (find-coding-system 'windows-1251)
+      default-buffer-file-coding-system))
+  "*Coding for incoming and outgoing messages.
+This feature is supported only in Emacs with MULE
+Nil means not to use any codings.
+See `list-coding-systems'."
+  :group 'emchat-option
+  :type (append '(choice (item nil))
+               (when (fboundp 'coding-system-list)
+                 (mapcar
+                  #'(lambda (x)
+                      (list 'item x))
+                  (coding-system-list)))))
+
+(defcustom emchat-auto-response-messages-p t
+  "Set this to non-NIL to send automatic messages.
+The automatic messages are those that are sent when somebody
+sends you a message while you are 'away', 'na', 'dnd', or 'occ'."
+  :tag "Send auto-response messages."
+  :type 'boolean
+  :group 'emchat-option)
+
+(defcustom emchat-auto-reply-away
+  "I am currently away from the computer.
+
+If you would like to be notified when I am back online
+send me a message with \",,notify-me\" in it.
+
+This message has been automatically sent to you
+by the (S)XEmacs IM client \"EMchat\".
+<http://www.emchat.org/>"
+  "Auto reply with this when you are away."
+  :group 'emchat-option)
+
+(defcustom emchat-auto-reply-occ
+  "I am currently occupied.
+
+If you would like to be notified when I am back online
+send me a message with \",,notify-me\" in it.
+
+This message has been automatically sent to you
+by the (S)XEmacs IM client \"EMchat\".
+<http://www.emchat.org/>"
+  "Auto reply with this when you are occupied."
+  :group 'emchat-option)
+
+(defcustom emchat-auto-reply-dnd
+  "Hey, the sign on the door says \"Do Not Disturb\"!
+
+Leave me a message, if you feel you must.
+I might get back to you.
+
+If you would like to be notified when I am back online
+send me a message with \",,notify-me\" in it.
+
+This message has been automatically sent to you
+by the (S)XEmacs IM client \"EMchat\".
+<http://www.emchat.org/>"
+  "Auto reply with this when you want to leave alone."
+  :group 'emchat-option)
+
+(defcustom emchat-auto-reply-na
+  "I am currently not available.
+
+If you would like to be notified when I am back online
+send me a message with \",,notify-me\" in it.
+
+This message has been automatically sent to you
+by the (S)XEmacs IM client \"EMchat\".
+<http://www.emchat.org/>"
+  "Auto reply with this when you are not available."
+  :group 'emchat-option)
+
+;; FIXME: How can I make this display how long we've been away
+(defcustom emchat-idle-reply-away
+   "I must be too busy to talk because I have
+been idle now for at least...seconds
+
+If you would like to be notified when I am back online
+send me a message with \",,notify-me\" in it.
+
+This message has been automatically sent to you
+by the (S)XEmacs IM client \"EMchat\".
+<http://www.emchat.org/>"
+  "Auto reply with this when you have idled away."
+  :group 'emchat-option)
+
+;; FIXME: How can I make this display how long we've been away
+(defcustom emchat-idle-reply-na
+   "I must be too busy to talk because I have
+been idle now for at least...seconds
+
+If you would like to be notified when I am back online
+send me a message with \",,notify-me\" in it.
+
+This message has been automatically sent to you
+by the (S)XEmacs IM client \"EMchat\".
+<http://www.emchat.org/>"
+  "Auto reply with this when you have idled to na."
+  :group 'emchat-option)
+
+(defcustom emchat-auto-response-never-send-to nil
+  "*This is a list of people that shouldn't get auto-responses.
+
+When you add someone's alias here and they send you a message while
+your status would cause an automatic response to be sent, they won't
+be sent one."
+  :type '(repeat (string :tag "Alias"))
+  :group 'emchat-option)
+
+(defcustom emchat-oops-msg-wrong-recipient
+  "That last message was meant for somebody else.
+Sorry about that. :-)"
+  "*The \"apology\" sent when you send to the wrong person."
+  :type 'string
+  :group 'emchat-option)
+
+(defcustom emchat-start-in-new-frame nil
+  "*If non-NIL, EMchat will start in its own frame."
+  :group 'emchat-interface
+  :type 'boolean)
+
+(defcustom emchat-new-message-hook nil
+  "*Hooks to run when there is an incoming message.
+Dynamically ALIAS and MESSAGE are binded to be used in hooks."
+  :group 'emchat-option
+  :type 'hook)
+
+(defcustom emchat-read-message-hook nil
+  "*Hooks run when a message is marked as \"read\"."
+  :group 'emchat-option
+  :type 'hook)
+
+(defcustom emchat-system-message-hook nil
+  "*Hooks run when a \"system\" message is received."
+  :group 'emchat-option
+  :type 'hook)
+
+(defcustom emchat-load-hook nil
+  "*Hooks run after EMchat has loaded everything up."
+  :type 'hook
+  :group 'emchat-option)
+
+(defcustom emchat-missed-message-hook nil
+  "*Hooks run when SRV_MISSED_ICBM packet comes in.
+
+This is usually when you are getting too many incoming messages at
+once.  You can use this hook, for example to send back a \"please
+resend\" message to the original sender.
+
+It is called with 3 arguments:
+
+  ALIAS -- The alias/UIN of the person who sent the message that
+           caused the SRV_MISSED_ICBM packet to be sent. \(string\)
+    NUM -- The number of missed messages. \(integer\)
+ REASON -- The reason that the messages were dropped. \(string\)"
+  :type 'hook
+  :group 'emchat-option)
+
+;; Some debugging counters.  Do NOT set any of these.
+(defvar emchat-dropped-packet-counter 0
+  "For debug purpose only.")
+
+(defvar emchat-resend-packet-counter 0
+  "For debug purpose only.")
+
+(defvar emchat-recent-packet nil
+  "The most recent incoming packet.
+For debug only.")
+
+(defvar emchat-trimmed-packet-counter 0
+  "For debug purpose only.")
+
+(defvar emchat-error-packets nil
+  "A list of error incoming packets.
+For debug only.")
+
+(defcustom emchat-about-fields
+  '((:nick . "Nick Name")
+    (:first-name . "First Name")
+    (:second-name . "Surname")
+    (:email . "Email")
+    (:country . "Country")
+    (:city . "City")
+    (:state . "State")
+    (:zip . "Postal Code")
+    (:phone . "Phone")
+    (:fax . "Fax")
+    (:cellular . "Cellular")
+    (:flags . "Flags")
+    (:web-indicator . "Web Indicator"))
+  "*Alist of field . field-name for basic info queries."
+  :type '(repeat (cons :tag "Field"
+                       (choice :tag "Field Keyword"
+                               (const :tag "Nick Name" :value :nick)
+                               (const :tag "First Name" :value :first-name)
+                               (const :tag "Second Name" :value :second-name)
+                               (const :tag "Email" :value :email)
+                               (const :tag "Country" :value :country)
+                               (const :tag "City" :value :city)
+                               (const :tag "State" :value :state)
+                               (const :tag "Phone" :value :phone)
+                               (const :tag "Fax" :value :fax)
+                               (const :tag "Street" :value :street)
+                               (const :tag "Cellular" :value :cellular)
+                               (const :tag "ZIP Code" :value :zip)
+                               (const :tag "Flags" :value :flags)
+                               (const :tag "Web Indicator" :value :web-indicator))
+                       (string :tag "Field Name")))
+  :group 'emchat)
+
+(defcustom emchat-about-more-fields
+  '((:age . "Age")
+    (:gender . "Gender")
+    (:homepage . "Homepage")
+    (:birth-year . "Birth Year")
+    (:birth-month . "Birth Month")
+    (:birth-day . "Birth Day")
+    (:lang1 . "Language")
+    (:lang2 . "Second Language")
+    (:lang3 . "Third Language")
+    (:ocity . "Old City")
+    (:ostate . "Old State")
+    (:ocountry . "Old Country")
+    (:marital . "Marital Status"))
+  "*Alist of field . fieldname for extended info queries."
+  :type '(repeat (cons :tag "Field"
+                       (choice :tag "Field Keyword"
+                               (const :tag "Age" :value :age)
+                               (const :tag "Gender" :value :gender)
+                               (const :tag "Homepage" :value :homepage)
+                               (const :tag "Birth Year" :value :birth-year)
+                               (const :tag "Birth Month" :value :birth-month)
+                               (const :tag "Birth Day" :value :birth-day)
+                               (const :tag "Language" :value :lang1)
+                               (const :tag "Second Language" :value :lang2)
+                               (const :tag "Third Language" :value :lang3)
+                               (const :tag "Originate City" :value :ocity)
+                               (const :tag "Originate State" :value :ostate)
+                               (const :tag "Originate Country" :value :ocountry)
+                               (const :tag "Marital" :value :marital))
+                       (string :tag "Documentation")))
+  :group 'emchat)
+
+(defcustom emchat-auth-accept-reason "You are AUTHORISED!"
+  "*Default reason for rejecting incoming auth requests."
+  :type 'string
+  :group 'emchat)
+
+(defcustom emchat-auth-reject-reason "Authorisation Rejected!"
+  "*Default reason for rejecting incoming auth requests."
+  :type 'string
+  :group 'emchat)
+
+(defcustom emchat-auth-request-reason "Please add me to your contact list"
+  "*Message to send with outgoing auth requests."
+  :type 'string
+  :group 'emchat)
+
+(defun emchat-init-visible-list (&rest args)
+  "Initialises the default value for `emchat-visible-contacts'."
+  (when (file-readable-p emchat-world-rc-filename)
+    (emchat-world-update)
+    (mapcar
+     #'(lambda (e)
+        (car e))
+     emchat-world)))
+
+(defcustom emchat-visible-contacts (emchat-init-visible-list)
+  "*List of contacts on your \"visible\" list."
+  :type '(repeat (string :tag "Contact Alias Name"))
+  :initialize #'custom-initialize-reset
+  :get #'emchat-init-visible-list
+  :set #'custom-set-default
+  :group 'emchat)
+
+(defcustom emchat-invisible-contacts nil
+  "*List of contacts on your \"invisible\" list."
+  :type '(repeat (string :tag "Contact Alias Name"))
+  :group 'emchat)
+
+;;; Internal variables
+(defcustom emchat-user-password nil
+  "*Password for your ICQ account.
+Nil means prompt for entering password every time you login."
+ :group 'emchat-info)
+
+(defvar emchat-ctx nil
+  "Current emchat context in emchat-v8 protocol.
+Internal variable, do not modify.")
+
+;;;###autoload
+(defun emchat-version (&optional arg)
+  "Return the version of emchat you are currently using.
+If ARG, insert version string at point."
+  (interactive "P")
+  (if arg
+      (insert (message "EMchat: %s" emchat-version))
+    (message "EMchat: %s" emchat-version)))
+
+;;;###autoload
+(defun emchat-copyright ()
+  "*Display the copyright notice for EMchat."
+  (interactive)
+  (with-electric-help
+   '(lambda ()
+      (insert
+       (with-temp-buffer
+        (erase-buffer)
+        (insert-file-contents (locate-library "emchat.el"))
+        (goto-char (point-min))
+        (re-search-forward ";;; Commentary" nil t)
+        (beginning-of-line)
+        (narrow-to-region (point-min) (point))
+        (while (re-search-backward "^;+ ?" nil t)
+          (replace-match "" nil nil))
+        (buffer-string (current-buffer)))))
+   "*EMchat Copyright Notice*"))
+
+(defconst emchat-donation-notice
+  "EMchat is an Open Source project and we have had a lot of fun in
+getting it into your hands.  But this project is NOT a \"for profit\"
+organisation.  We do not receive any funding, Government grants, or
+subsidies of any kind.  None of us who are involved with the project
+are remunerated in any fashion for what we do with EMchat.  We are all
+just volunteers, coding in our spare time.
+
+Often the end user doesn't realise that their \"free\" software has
+come at some considerable cost.  Costs and expenses like...
+
+    Bandwidth and ISP expenses
+    Hardware updates and maintenance expenses
+    Hosting expenses
+    Domain name registrations
+    Electricity and other utility expenses
+    Outrageous amounts of coffee for all-night coding sessions
+
+If you have found this software useful/cool/entertaining please
+consider dipping into your hard earned and making a donation.  Doing
+so will give you the eternal gratitude and thanks from the EMchat
+team, and think of the warm fuzzies you'll get.
+
+Seriously, even if you decide against making a donation at this time,
+I would like to sincerely thank you for at least taking the time to
+consider it.  I hope you enjoy EMchat as much as we have enjoyed writing
+it for you.
+
+Steve Youngs
+EMchat Project Lead.
+
+\t\t [Donate]\t\t\t [Cancel]
+
+\t\t"
+  "Contents of donation buffer.")
+
+(defconst emchat-paypal-glyph
+  "iVBORw0KGgoAAAANSUhEUgAAAG4AAAAXCAIAAABlFO2lAAAACXBIWXMAAAsTAAALEwEAmpwY
+AAAAB3RJTUUH1wsQEBYNmimKowAACOlJREFUWMPtmWtwVdUVx3/ncV/n3pubBAIhQF4QkgtJ
+6gMBrVhfUxSstkjHjlZ8jLUdxk5HRztTqzLUdsaCEsfx0arVqY7TUqfWajWlIqPQiGOLYIE8
+CI8QyDtc7vu8z+mHewMhxDGg0w+drDkf9pyz9//813+vtfY+ZwvtnLLapgiTdjbWcW/iZFto
+PylicYK5V1I0H6TxRgngfg7gmEcC8PmdvxDtHGw02ue1J/5eYWLkHVJH6HqL3khOUKE9p2Pd
+NBrXUFyPHJyMtYmarZHp5T/PsLu1496EDBBJUP8g0y/54sHuSMz9f9iXdEcOEqmh4YccvR2Q
+a5siyAmmXoiV/XKZ9ZWk5/+sJnx1gKEKps6sbUrLAFNnYqUR5AmME8H5PwrLr8Id12JKA+yQ
+AQQPRhrJc1oPXx3+RnBJvolrIsiErkUMYHaT/XgExUUYlSGemShfR92Nsf8sJ/ZqpGKsPjLb
+xz7K0wAcnAzGIfSOM5w5ncb4Do/0yTXEAN5qrGGsAQDPLJRL0Haj7z8XKR0XkAFcAzONM0rK
+QKP+YrH6yxZEIh3fEqzXXe/1qQv2OP2Gd2WJ0nQhqQ/HInrLzW3RzO0tgbWVvtUG6t6JUila
+lbrusL2rzXN1UfCli0m+Nw4NwCuKs32+W6b77ioiueXLxaLiJBcYm2T5fK+8UEP0mFtrM3e1
+BNZV+b6vo+47OzTHwtFHpDQz2BnsUQkeDNtt2Vwo2LvS8qIl+hMDTr8BiFEFoxtfA8F6RD+O
+TmY3qU/wh+19GUBqDCEEmHonmc9IbUcIEVmKrxxcsq0ktiEKuWkE8FebWyx7VxqwO1WkWRhp
+IN9nhIb/5xWCIunP9Ki/6MJf7Vs1B+0IBUvxzca1ye4j+U9EgaLr8VWQ3oUyH9cg9hZ2jOCS
+sVSLLrbeD2mPdyqPz6Xgmwz/QaxpUH5TK583jHqU8JV4Z+Vh0y04LlNuOA32xNsYw6dIujZG
+IlcsIJVA7cdKnrrkIrs1IyiSONNn7Uw6/aXab3uleQogRYNIhdrTUxONe+JlHyUWfKa9MJPQ
+hYgRuzUDSPVB/ffF8Rkt6q/ChC539FWZNUZi7s7EvE/VxyIUXoORwErlXxReqq3vFqd75SsK
+naMaVhA7i5XESJykAfhum+G7qV9pmguYfxkiEHXSKzM/0BLV/0pEd6sbiym8hsLlmTsy8dIW
+dUNhIro7uajDHlxB6NKxVIuv0zcVZn/cCWTvPxAv30Hh97R1Q9k1HcK0Gid5TeYu9RRswTKK
+V4yFHViO4D9FUhsg3jYiZQa6m1EH0WPocYw07hT7gCrWKfKisP3vtLq2S74gJNYEACmqoA8K
+paL/gfLAI1VCoayt73bdxXim2/syYoU/FzuBhysDD8uuVZle2e4c0Pz3zZYviegv9JoflSCX
+ocfRY3gqzWbT3pfx/WSWND+Ig31Aw/WiJ9ATGKk8jVKvoGQZbharA4CbtN1sUfrGNuvTlH9t
+pdQY0p/tMbcU4y2z2zKA4BM9N0x1enSzOYkUHktVL5cXeqS5ASRBeW5e8MVaRN1uy4gVfkxn
+orC+SvQ4egJ1kO53iWkjCQ4M7OXEXsKVBEoJzrUP6piuVKdIDUH1kcPYbnjzeZkfdQgFkljq
+OEfnm81DVksPtpvfVHgF1wg7RzREQXvqmPLcPO+lu+hrN7asco7pgPpoV75Gx0zSvQzuQOvj
+0ge1Dd3CFI/nqiLzneO5HJeicYZaAIJzcjTEWoV0G6k+J6kBYpXfeG3Q6TOUDXO83x4SQqXW
+9rh9QJVThU6fIS8p8D9QZL5rGK/0CxHZGSowm3vGUJXqfE7CEiv93hUiHevc9Eanz/Asn3IK
+9vpeITT7DNiI+a6VgyXeysDHAIMtGCO7zFP10YDjXdBFRbV9OJMLQHlhAabrvWW6WON3Dqvy
+wgLsrPpozNoWDzxaJc4JZO9oF2Z4BQas1jAuYqXfOag6B1W+dgwhnEtP5ckascybq7yS8jJ7
+mzBiVN1hvOXYnSqQXLwzX8E7s9TIHNsBUFGVpzFPQe+nZq1+dy/gXVlibj0BSAuCWD35qlKn
+5BryxRHie+zWWbkO6rq+sVSdY26izB0y5YsKSB/ieLudzjtr78/mYR13PNh9J2Hp+iuDLWdu
+rM6wwka7NZsri1Jkc+ChisA9utOh4iBFFRzb6dVzRdf885CrO9KCIPpgbs0J/KxCvqxQazpm
+Da8CSSz3A+aWmNNvWNuOG6+0CjPKMWIIMvWPaRuPiqXe4KvR4KvR4It1gL1fpSA6hoabtIz3
+FqRvHTD/EfOsmOK5ShXnBAD9d336phnGy33SgqDncnILlDRfQfLZ7XlRxqGaPuj0Grn8MD6s
+YMYt+YHR4MRhiX827h4VJPCMuooanLb8nLDnHt/lTwvJ53OIYlRh4G++u0uFiKw/1yNM8+YX
+ItfKT2NUUZ6sEkJSdk2Hq1zmuznpuWGqtTWevf+guTUpLyuj/008UHOn8YbjdGneW0s9dc2e
+4G2eawNCgeR0ZohEx9Aw/jSoru1yY2ZgXVVwg8GWet93h703lpjNx7WN3Z4VU0KvzWK4ecTn
+IIFSuy0tzvAKSmocqrEd4rQD8kVh65Oket9B5p6UUvHdlJwQrG8Q98RpikkAgtsUIZKgpPi0
+Xe5Ff2Ta1bxXl1/1gdk30/gUe3/KkZco+w71G7BS9L1N9Rr2r6dzPQ1PUH4bHyzGVrlsO1aS
+bd8Am4Ynmb4MQSbdyaGn6Xk9D1i+moaN7P81nRvyd5YdQu1h29KxNHCxsmQPc2wTXc/j2kgB
+GpooXY5rMbCZ1ocwjtOwkfLVfLCEzAGu2Ino4f3G8alKfha/QeFCHJ3NFdQ/TvlqPliM1jtR
+2DFf8okYgxHBbYpQkqCsHkGa/NdzTh+ODrE9HI3I+QQPVUxKea5S2iS7R1ZwFQqqJqU8d+t+
+ByJyx72J2mfB0Cg5f1KTc7HUYRKM/PrVI3S8Q2gm4XI8BYjipD4T+IvhYqXRhtj/d5IRSIw6
+2wknKJnJtEXI/kmhJlQih3cx2MmJUWc7J23yxPFsbfSJ438BQx3Q9K+c09sAAAAASUVORK5C
+YII="
+  "A base64 encoded paypal donate button.")
+
+(defconst emchat-maybe-later-glyph
+  "iVBORw0KGgoAAAANSUhEUgAAAG4AAAAXCAIAAABlFO2lAAAACXBIWXMAAAsTAAALEwEAmpwY
+AAAAB3RJTUUH1wsQEBEgkLdAEQAACKJJREFUWMPtmVuMXVUZx39r7X32PpeZc6YznXYudKa1
+lHZ6IdzaEGs0IL6CqPGFGKomQDAaagoYAtUEagwF2phSJQYURZEHCCLIRTAojJSCFux12qlz
+a2emc9ozs+dc9tm3tXw4ZzplOqUzxb40/bIfVr59vv9/rf/51rfXRRxg0pZuyXDRZmNd652T
+bXHgpIj1Dpdez5zlYEwXJUCfAXDKKwGc+cdnRTsHOxXtTO2Z84qZdV6R76P3JQYzFUHFgYqO
+y+Zx+Z3Ur8RMXcy1mVpUpjjIfx7no31d6x0TIOOw8j7mf/7swXoi5y4M+4zDMVNklrDqdgbW
+AebSLRlMh7lXE5ZmiWQg4ggbIrSH9hAWwgYT7aM9CGaMY4FZxSGawbwzEHEwIDxbiIGQADoE
+dV6KTE07c1uXbimYAHNbCQsIcwZxstohYSLrkA3IWnSIHkUXEDWIeoSBKqCyqCI6OLuOMo2R
+RsTRPvoEqoQOP7VSmcg6RB3SQrno3BlCBDKOSIENASqPck9TU57mOYfUDmlYBe+ZACKGX8CI
+zSJeJjFqMVsRNkBkQQKjDmMOgKxDldEu2AgTHaJKaB8RQ5joaCKFLYSBSGO2IDOoEqEgClHj
+KA8RQyYQcbRCu2i3+sdUqS9BJlB5vDxBCQEigUxM0gkgjdmKrEN7BANoH+Ui4sgEaLSLKoFE
+JhAWSLQPimhs1lIqDZgA2icooGYjpZnAbPUez7oP9SHJdF0rUnHtxvNrP1DDvvW1xuS2dpRG
+xpFx0ITjRA5CIBPoEOVj2BAHTaw5eCMqrutM/HihfXsb2ibMQhGZwGxA2KBRBYJhwmGUW6Xe
+fsJ9qC+x6XP2t5pQfcgk5jyMugm6PLqE2aSyc/zfj5ira80vLEBpZISRnsQMT4DArMdIoxWq
+RJhDlwhzs5BChShvQsqgSFQkOmWCS1FRerIxxSnqEXa0/xiAItqVN7+Y8bb2q2EfkB1JdIDV
+jpGsFnZjLsEQwsZqJsoTFZAJzDpUCSGjvVnAuLwGGcduw8ig8sgazAxUKl2AloQOQQ6pT1Ib
+y5MEPQRF4o3YSzBqqnSmR5DFaAzfHS0/MpB85FKM+ZguMolZO4kpkiCwWqq5LAyK/ahj+IWZ
+6qA0OsJ3qILmHdxhwvHJx3emNqY4ARGL9hVF0pCtdvivvOr1yk8MGpclAaMjhYiXNx93Vn4w
+1tLpdLxf3jpCrCX8KDXW1Ok9UyQ2L/xAjDV1lu4dAivaVwSC13LO4h3ja3dFPTaxJjWULH7n
+oLN4h7Nkh7vxCNZCSKICtECYlRCjI0V5AGIkVpQ35ybptowQa/J+e7z0/UNAaUP32IJ/IprU
+UPwTmLFWrJbiLQfHWjrdB/qdy94P3kxg1M9Ch3Cc8jHG9k9kZRH6X6XlOqQJ8pNrbAHRNM6k
+SSijbtdYVWO0x6MP8+5HBfOqGtEQiw6WjI4kIJqs+N1tuMp7eqj8cL/93WbzihSWjPYWEU3l
+x46IlJG4pw2I9hYBLGHd2uRtP+o9NpB4eHHh5o9F0oj/cEG4c9z71aD5pbrY6hqCMvEYoRF1
+u7LJEhnB8RBzHiIumoKpdGvSxqWJqKec3LZEpAxdjgo3756KeUNdtL+IQheixE8WGqtGGduJ
+n5upDspj8G1yZbAnJvWxPYzuoXYhiaZT1loSwD06jbNmbdTtEmhjWdJYlXI39hDp2tevKN7R
+JdKGbLXUUS/4Sy7sdIh0tSeWxCibl6ei3YXww3z4zlj87jaRPqFLjaqvbK7NJB5o107kbT+q
+Rnz/2WPqiAe4D/ZWi3suoDjIiY9JXV2hlh1JdESslViDOmaeTmd0JJUTyoVx66sNhHnv1yOn
+Y2onUkO+cWVNcssihp5n+M+Ueqcf8rTOkU78ic/HZH304UQv9E5XWk9zLt8a7a9MsaR5TZpA
+W7fMl0sSqsc1r0mjtbuxN/zHWOLBRXJxovTtA6LZEpaPO2isSftPDZU398smy75jPk5n1JdC
+Y6xIoXUlPY2lycr8TW5dIlusSjk22rvZv41wjDZ7gjqFMKnpQNruD/47lc6OdA6dDczVaXSE
+CqbBXKEqzth1c8j9mw83UDpyxiGf0XmqtOe0Z4r2lSrjMS4ZSNzfntiQUV0lFEZHEh2pQa9S
+mIPns9pTxooUXpZg3Fxdq8sq/PtY/J42MfoyQaEiX/DWqP9s1r33MJa01jXJtjgQvJlTw374
+zpj/7BFRJyn1EhQQZoU62ld0Nw24P8sFr45PQ+fn1KBfST3/JQe3PB2mEe0vAcbyFLmdBOOf
+ZX0pK8tkYrN8DEtVUmNZkr132V/5nSg9V+mW7Eji7LJvaxYZ0/vFUTHPmvg+DGKmjKtqK1HW
+11N0P4qU1by4YY67sUd7OvXUMiPxon2riN00N/zbWGnD4eCtUfPLcxh+mSgLzknq8O0xb9sR
+b9uRqLts394ylS63Qy4YNVfXhjvH3fWHqJlv32p8ErMeL1uVsiNJ9nVEadY6VNUAEHpLhoxD
+Yz1iltvRtW9QdxXvXs/4HrTCSLLoNpbez6HN9D5J6ze47EdELrn3aL6Ro88RFiLnm/4Lx71f
+Dtb8cYXZ8gSHf46RYNWjNN/E8Ms0fplwnK6fMvgC1lxWPUrDWoTEPUrvk/T/hsgFsBq4+mnq
+r53sSd9TlAdZfNckXd+THNhELMM1z5BejvJ5+1pgKubQiyzfRPON7LiZ3Htn2WV9yk7eyTGS
+EXpLhkaHlpUI4zweHNiNrPmTs2I3Stt3XhJfN8TeewlyXACmFbndDGTM6gSvaT+/UgJ7vpfZ
++zhCkv0rPX/ArsWuvSCkjBjvn/iCu5BedN6lBA7fV22k5l9QB5f9r0DG7FrvLN0OfpnGKy8e
+5p6L5XtwmDj69TJ0vUJNK7VtxNJIeVGfGZxiaMIC5SwHX2M8A84pdzu1Do2tzFuDGb8o1IxK
+5PFdjBxi9JS7nYs3jv+XG8f/AUQDon1o6NymAAAAAElFTkSuQmCC"
+  "A base64 encoded png \"Maybe Later\" button.") 
+
+(defun emchat-make-donation ()
+  "Proceed with making a donation to the EMchat project."
+  (interactive)
+  (browse-url "http://tinyurl.com/2uzel4")
+  (kill-buffer "*emchat-donate*"))
+
+(defun emchat-no-donation ()
+  "Don't make a donation to the EMchat project."
+  (interactive)
+  (kill-buffer "*emchat-donate*"))
+
+(defconst emchat-donation-map
+  (let* ((map (make-sparse-keymap 'emchat-donation-map)))
+    (define-key map [button1] 'emchat-make-donation)
+    (define-key map [button2] 'emchat-make-donation)
+    (define-key map [button3] 'emchat-make-donation)
+    (define-key map [return] 'emchat-make-donation)
+    map)
+  "A keymap for the extents in the EMchat donation buffer.")
+
+(defconst emchat-nodonation-map
+  (let* ((map (make-sparse-keymap 'emchat-nodonation-map)))
+    (define-key map [button1] 'emchat-no-donation)
+    (define-key map [button2] 'emchat-no-donation)
+    (define-key map [button3] 'emchat-no-donation)
+    (define-key map [return] 'emchat-no-donation)
+    map)
+  "A keymap for the extents in the EMchat donation buffer.")
+
+(defun emchat-donation ()
+  "Make a donation to the EMchat project via PayPal."
+  (interactive)
+  (let ((buf (get-buffer-create "*emchat-donate*"))
+       (donate-help "Make a donation to the EMchat team.")
+       (cancel-help 
+        "Thank you for considering a donation... maybe another time.")
+       donate-glyph-ext
+       cancel-glyph-ext
+       donate-text-ext
+       cancel-text-ext)
+    (switch-to-buffer buf)
+    (erase-buffer)
+    (insert emchat-donation-notice)
+    (when (and (device-on-window-system-p)
+              (featurep 'png))
+      (setq donate-glyph-ext (make-extent (point-max) (point-max)))
+      (set-extent-begin-glyph
+       donate-glyph-ext
+       (make-glyph
+       (list (vector 'png ':data (with-temp-buffer
+                                    (insert emchat-paypal-glyph)
+                                    (base64-decode-region (point-min)
+                                                          (point-max))
+                                    (buffer-string))))))
+      (insert "\t\t\t")
+      (setq cancel-glyph-ext (make-extent (point-max) (point-max)))
+      (set-extent-begin-glyph
+       cancel-glyph-ext
+       (make-glyph
+       (list (vector 'png ':data (with-temp-buffer
+                                    (insert emchat-maybe-later-glyph)
+                                    (base64-decode-region (point-min)
+                                                          (point-max))
+                                    (buffer-string))))))
+      (set-extent-property donate-glyph-ext 'keymap emchat-donation-map)
+      (set-extent-property donate-glyph-ext 'help-echo donate-help)
+      (set-extent-property donate-glyph-ext 'balloon-help donate-help)
+      (set-extent-property cancel-glyph-ext 'keymap emchat-nodonation-map)
+      (set-extent-property cancel-glyph-ext 'help-echo cancel-help)
+      (set-extent-property cancel-glyph-ext 'balloon-help cancel-help))
+    (goto-char (point-min))
+    (re-search-forward "\\[Donate\\]" nil t)
+    (setq donate-text-ext (make-extent (match-beginning 0) (match-end 0)))
+    (re-search-forward "\\[Cancel\\]" nil t)
+    (setq cancel-text-ext (make-extent (match-beginning 0) (match-end 0)))
+    (set-extent-property donate-text-ext 'face 'bold)
+    (set-extent-property donate-text-ext 'mouse-face 'highlight)
+    (set-extent-property donate-text-ext 'keymap emchat-donation-map)
+    (set-extent-property donate-text-ext 'help-echo donate-help)
+    (set-extent-property donate-text-ext 'balloon-help donate-help)
+    (set-extent-property cancel-text-ext 'face 'bold)
+    (set-extent-property cancel-text-ext 'mouse-face 'highlight)
+    (set-extent-property cancel-text-ext 'keymap emchat-nodonation-map)
+    (set-extent-property cancel-text-ext 'help-echo cancel-help)
+    (set-extent-property cancel-text-ext 'balloon-help cancel-help)
+    (goto-char (point-min))))
+
+;; Load the toolbar
+(add-hook 'emchat-buddy-mode-hook 'emchat-install-buddy-toolbar)
+(add-hook 'emchat-log-mode-hook 'emchat-install-log-toolbar)
+
+;;; Code - utilities:
+
+;;;###autoload
+(defun emchat-customize ()
+  "Interactively customize settings and preferences."
+  (interactive)
+  (customize-group 'emchat))
+
+\f
+;;;###autoload
+(defun emchat-browse-homepage ()
+  "Browse emchat homepage for news and files."
+  (interactive)
+  (browse-url "http://www.emchat.org/"))
+
+(defcustom emchat-encoding-local 'koi8-r
+  "*Local hosts encoding."
+  :type '(choice (item :tag "ASCII" us-ascii)
+                 (item :tag "Russian KOI8-R" koi8-r)
+                 (item :tag "Russian CP1251" cp1251))
+  :group 'emchat)
+
+(defcustom emchat-encoding-remote 'cp1251
+  "Remote server encoding."
+  :type '(choice (item :tag "ASCII" us-ascii)
+                 (item :tag "Russian KOI8-R" koi8-r)
+                 (item :tag "Russian CP1251" cp1251))
+  :group 'emchat)
+
+(defconst emchat-encoding-koi8-r
+  (concat
+   "\301\302\327\307\304\305\243\326\332"
+   "\311\312\313\314\315\316\317\320"
+   "\322\323\324\325\306\310\303\336"
+   "\333\335\337\331\330\334\300\321"
+   "\341\342\367\347\344\345\263\366\372"
+   "\351\352\353\354\355\356\357\360"
+   "\362\363\364\365\346\350\343\376"
+   "\373\375\377\371\370\374\340\361"))
+
+(defconst emchat-encoding-cp1251
+  (concat
+   "\340\341\342\343\344\345\270\346\347"
+   "\350\351\352\353\354\355\356\357"
+   "\360\361\362\363\364\365\366\367"
+   "\370\371\372\373\374\375\376\377"
+   "\300\301\302\303\304\305\250\306\307"
+   "\310\311\312\313\314\315\316\317"
+   "\320\321\322\323\324\325\326\327"
+   "\330\331\332\333\334\335\336\337"))
+
+(defun emchat-translate-string (str from-enc to-enc)
+  "Translate STR from koi8 to cp1251."
+  (let ((fe (ecase from-enc
+              (us-ascii nil)
+              (koi8-r emchat-encoding-koi8-r)
+              (cp1251 emchat-encoding-cp1251)))
+        (te (ecase to-enc
+              (us-ascii nil)
+              (koi8-r emchat-encoding-koi8-r)
+              (cp1251 emchat-encoding-cp1251)))
+        (tt (make-vector 256 nil)))
+    (dotimes (idx (min (length fe) (length te)))
+      (aset tt (char-to-int (aref fe idx))
+            (char-to-string (aref te idx))))
+    (mapconcat #'(lambda (chr)
+                   (or (aref tt (char-to-int chr))
+                       (char-to-string chr)))
+               str nil)))
+
+(defun emchat-encode-string (string)
+  "Return a encoded string from STRING with DOS stuff added.
+Encode string with `emchat-coding-system'."
+  ;; add DOS stuff
+  ;; "0d" instead to avoid use of ^M
+  ;; which messes up with outline mode
+  (let ((estr (replace-in-string string "\x0a" "\x0d\x0a")))
+    (if (fboundp 'encode-coding-string)
+        (encode-coding-string estr emchat-coding-system)
+      (emchat-translate-string estr emchat-encoding-local emchat-encoding-remote))))
+
+(defun emchat-decode-string (string)
+  "Return a decoded string from STRING with DOS stuff removed.
+It also quote character % to make `format' happy in `emchat-log'.
+Decode string with `emchat-coding-system'."
+  ;; remove DOS stuff
+  ;; "0d0a" instead to avoid use of ^M
+  ;; which messes up with outline mode
+  (let ((dstr (replace-in-string string "\x0d\x0a" "\x0a")))
+    (if (fboundp 'decode-coding-string)
+        (decode-coding-string dstr emchat-coding-system)
+      (emchat-translate-string dstr emchat-encoding-remote emchat-encoding-local))))
+
+(defconst emchat-message-max-size 500
+  "Maximum size of message that ICQ will accept.
+Set it to small because size expands after `emchat-encode-string'.")
+
+(defun emchat-splitter (x)
+  "Split a long message X into parts of maximum length `emchat-message-max-size'.
+Only split at whitespace."
+  (loop
+    with i = emchat-message-max-size
+    while (> (length x) i)
+    do (while (and (not (memq (aref x (incf i -1)) '(?  ?\t)))
+                   ;; at least half, to safe guard
+                   (> i (/ emchat-message-max-size 2))))
+    collect (substring x 0 i) into parts
+    do (setq x (substring x i))
+    finally return (nconc parts (list x))))
+
+(defvar emchat-outgoing-queue nil
+  "Lists of outgoing queue to be sent.
+Each queue consists of the binary string and the resend counter.")
+
+(defvar emchat-frame nil
+  "The frame where EMchat is displayed.")
+
+(defun emchat-connected-p (ctx)
+  "Return non-nil when EMchat is connected to the ICQ server."
+  (memq ctx emchat-v8-connections))
+
+(defun emchat-exit ()
+  "Log out of ICQ and close all EMchat buffers."
+  (interactive)
+
+  (emchat-logout)
+  (set-buffer emchat-log-buffer)
+  (save-buffer)
+  (if emchat-save-log-on-exit-p
+      (rename-file emchat-log-filename
+                  (concat emchat-log-filename
+                          (format-time-string "-%Y-%b%d-%H%M-%S")))
+    (delete-file emchat-log-filename))
+  (loop for each in '(emchat-log-buffer 
+                     emchat-buddy-buffer 
+                     emchat-status-buffer)
+    do (when (buffer-live-p (symbol-value each))
+        (kill-buffer (symbol-value each))))
+  (delete-other-windows)
+  (when (and emchat-start-in-new-frame
+            (frame-live-p emchat-frame))
+    (delete-frame emchat-frame))
+  (setq emchat-frame nil)
+  (when (and (featurep 'emchat-wharf)
+            (frame-live-p emchat-wharf-frame))
+    (delete-frame emchat-wharf-frame))
+  (setq emchat-wharf-frame nil))
+
+(defvar emchat-trimmed-packet nil
+  "*Last incomplete packet.
+Due to limited buffer size of Emacs network buffer, packets can be trimmed
+and attached at the beginning of next callback.  Use this in
+`emchat-network-separator' to concatenate a packet across two callbacks.
+Usually only one per 1000 packets needs this.")
+
+;;; Code - client to server packets:
+
+(defvar emchat-current-seq-num 1
+  "Current sequence number in packet.")
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-pack-register-new-user (password)
+;   "Pack register new user packet 03fc."
+;   (emchat-pack
+;    "\xfc\x03"
+;    (emchat-int-bin (length password))
+;    password
+;    "\xa0\x00\x00\x00"
+;    "\x24\x61\x00\x00"
+;    "\x00\x00\x00\x00"))
+
+;;; FIXME: This needs to be updated for v8
+; (defvar emchat-random-groups
+;   '(("general" . "\x01\x00\x00\x00")
+;     ("romance" . "\x02\x00\x00\x00")
+;     ("games" . "\x03\x00\x00\x00")
+;     ("students" . "\x04\x00\x00\x00")
+;     ("age-20" . "\x06\x00\x00\x00")
+;     ("age-30" . "\x07\x00\x00\x00")
+;     ("age-40" . "\x08\x00\x00\x00")
+;     ("age-50+" . "\x09\x00\x00\x00")
+;     ("women-wanted" . "\x0a\x00\x00\x00")
+;     ("man-wanted" . "\x0b\x00\x00\x00"))
+;   "Random user groups.")
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-pack-set-random-group (group)
+;   "Pack set random group 0564."
+;   (emchat-pack
+;    "\x64\x05"
+;    (cdr (assoc group emchat-random-groups))))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-pack-search-random-user (group)
+;   "Pack search random user 056e."
+;   (emchat-pack
+;    "\x6e\x05"
+;    (cdr (assoc group emchat-random-groups))))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-pack-request-authorization ()
+;   "Pack request authorization packet 0456."
+;   (emchat-pack "\x56\x04"))
+
+;;; Code - server to client packets:
+
+;;; FIXME: Do we have an unknown packet handler for v8?
+; (defun emchat-do-unknown (packet)
+;   "Handle any unknown PACKET."
+;   (push (cons 'unknown-command emchat-recent-packet)
+;         emchat-error-packets)
+;   (emchat-log-error
+;    "Unknown command: %s"
+;    (emchat-bin-hex (substring packet 7 9))))
+
+;;; FIXME: How is this handled now?
+; (defun emchat-do-wrong-password (packet)
+;   ;; not authorized?
+;   "Handle server command 0064 in PACKET."
+;   (emchat-log-error "Your password is invalid"))
+
+(defun emchat-do-forced-logoff (ectx)
+  "Called when another user with same UIN is logged in."
+  (emchat-log-error "Another user with same UIN is logged in!")
+  (emchat-logout))
+
+;; Automatically reconnect when connection unexpectadly closes.
+;; WARNING!! This can cause problems, we should have maximum
+;; reconnections and reconnection rate custom variables.
+(defvar emchat-is-auto-reconnecting nil
+  "Internal variable.  Do not set.")
+
+(defun emchat-do-disconnect (ectx)
+  "Handle disconnect from server."
+  (emchat-log-error "Unexpected disconnection from server")
+  (emchat-logout)
+  (if emchat-user-password
+      (progn
+       (setq emchat-is-auto-reconnecting t)
+       (emchat-log-system "Attempting auto-reconnect...")
+       (emchat-login))
+    (with-current-buffer emchat-log-buffer
+      (emchat-log-system 
+       (substitute-command-keys
+       "Connection lost, use `\\[emchat-login]' to log back in.")))))
+
+;;; FIXME: How is this handled now?
+; (defun emchat-do-already-logged-in (packet)
+;   "Handle server command 00fa PACKET."
+;   (emchat-log-error "You are already logged in."))
+
+(defun emchat-do-instant-message (ectx &rest ih-arguments)
+  "Handle incoming instant message."
+  (emchat-do-message-helper
+   (emchat-get-arg :uin) (emchat-get-arg :msg) (emchat-get-arg :msg-type)))
+
+(defun emchat-do-missed-message (ectx &rest ih-arguments)
+  "Handle incoming notice about missed messages."
+  (let ((alias (emchat-uin-alias (emchat-stringular-uin (emchat-get-arg :uin))))
+       (num (emchat-get-arg :missed-messages))
+       (reason (emchat-get-arg :reason)))
+    (emchat-do-message-helper
+     alias
+     (format "Server dropped the last %d message%sfrom: %s
+Reason: %s"
+            num (if (> num 1) "s " " ") alias reason) 'missed)
+    (run-hook-with-args 'emchat-missed-message-hook alias num reason)))
+
+(defun emchat-do-offline-message (ectx &rest ih-arguments)
+  "Handle incoming offline message."
+  (let* ((time-stamp (emchat-get-arg :time-stamp))
+         (year (nth 0 time-stamp))
+         (month (nth 1 time-stamp))
+         (day (nth 2 time-stamp))
+         (hour (1- (nth 3 time-stamp)))
+         (min (nth 4 time-stamp))
+         (monthname (aref emchat-monthnames month))
+         (local-time
+          (timezone-fix-time
+           (format "%s %s %s:%s %s"
+                   monthname day hour min year)
+           nil nil))
+         (local-year (aref local-time 0))
+         (local-monthname (aref emchat-monthnames
+                                (aref local-time 1)))
+         (local-day (aref local-time 2))
+         (local-hour (aref local-time 3))
+         (local-min (aref local-time 4)))
+
+    (emchat-do-message-helper
+     (emchat-get-arg :uin)
+     (format "(%s %02s) %02s:%02s\n%s"
+            local-monthname local-day local-hour local-min
+             (emchat-get-arg :msg))
+     (emchat-get-arg :msg-type))))
+
+(defun emchat-do-added-you (ectx &rest ih-arguments)
+  "Handle incoming SVR_ADDEDYOU packets."
+  (let ((file emchat-recently-added-by-filename)
+       (uin (emchat-stringular-uin (emchat-get-arg :uin)))
+       (msg (emchat-get-arg :msg))
+       (type (emchat-get-arg :msg-type)))
+    (emchat-do-message-helper uin msg type)
+    (when (or (not (member uin emchat-all-uin))
+             emchat-world-track-all-adds)
+      (with-current-buffer (find-file-noselect file)
+       (unless (search-forward uin nil t)
+         (goto-char (point-max))
+         (insert uin)
+         (save-buffer))
+       (kill-buffer nil))
+      (add-to-list 'emchat-world-recently-added-by
+                  (emchat-numeric-uin uin) 'append))))
+
+(defun emchat-do-auth-request (ectx &rest ih-arguments)
+  "Handle incoming SRV_AUTHREQ."
+  (emchat-do-message-helper
+   (emchat-get-arg :uin) (emchat-get-arg :msg) (emchat-get-arg :msg-type)))
+
+(defun emchat-do-auth-accept (ectx &rest ih-arguments)
+  "Handle incoming SRV_AUTHREPLY (accepted)."
+  (emchat-do-message-helper
+   (emchat-get-arg :uin) (emchat-get-arg :msg) (emchat-get-arg :msg-type)))
+
+(defun emchat-do-auth-reject (ectx &rest ih-arguments)
+  "Handle incoming SRV_AUTHREPLY (rejected)."
+  (emchat-do-message-helper
+   (emchat-get-arg :uin) (emchat-get-arg :msg) (emchat-get-arg :msg-type)))
+
+(defun emchat-do-srv-contact-err (ectx &rest ih-arguments)
+  "Handle incoming SRV_CONTACTERR."
+  (emchat-log-error "Contacts Error: %s" (emchat-get-arg :reason)))
+
+(defun emchat-do-srv-general-err (ectx &rest ih-arguments)
+  "Handle incoming SRV_GEN_ERR."
+  (emchat-log-error "Server Error: %s" (emchat-get-arg :reason)))
+
+(defvar emchat-auto-reply-p nil
+  "If non-nil EMchat will not automatically set your state to online.
+
+It is used in `emchat-do-message-helper' and `emchat-send-message-helper'.")
+
+(defvar emchat-user-auto-away-p nil
+  "This variable is set when the auto-away timer expires, 
+and it is reset in emchat-send-message-helper and emchat-change-status.")
+
+(eval-when-compile (load "sound"))
+
+(when (featurep 'sxemacs)
+  (defvar emchat-audio-device default-audio-device
+    "The audio device to play sounds on.")
+  (defvar emchat-media-driver nil
+    "Optional driver to use with `emchat-load-media-streams'.
+See `make-media-stream' for what can be used here."))
+
+(defun emchat-load-media-streams (&optional force)
+  "Loads configured sounds into SXEmacs media streams.
+
+With optional prefix arg, FORCE, make the streams even if they already
+exist. This is useful when you want to replace existing sounds."
+  (interactive "p")
+  (emchat-do-in-sxemacs
+    (let ((sound-lst emchat-sound-alist)
+         (stub "emchat::"))
+      (mapcar
+       #'(lambda (el)
+          (when (stringp (cdr el))
+            (let* ((file (expand-file-name (cdr el) emchat-sound-directory))
+                    (streamsym (intern (concat stub (symbol-name (car el)))))
+                    (stream (ignore-errors (symbol-value streamsym))))
+              (when (and (file-readable-p file)
+                         (or force
+                             (not (media-stream-p stream))))
+                (set streamsym (make-media-stream :file file emchat-media-driver))))))
+       sound-lst))))
+
+(defun emchat-play-sound-maybe (type)
+  "Play sound TYPE if it exists."
+  (when emchat-use-sound-flag
+    (emchat-do-in-xemacs
+      (when (cdr (assq type emchat-sound-alist))
+       (let ((file (expand-file-name (cdr (assq type emchat-sound-alist))
+                                     emchat-sound-directory)))
+         (play-sound-file file))))
+    (emchat-do-in-sxemacs
+      (when (media-stream-p
+            (ignore-errors
+              (symbol-value (intern-soft (concat "emchat::" (symbol-name type))))))
+       (let ((stream (symbol-value (intern-soft
+                                    (concat "emchat::" (symbol-name type))))))
+         (play-media-stream stream emchat-audio-device))))))
+
+(defvar emchat-online-notifiers nil
+  "A list of aliases who have requested online notification.")
+
+(defun emchat-do-message-helper (uin message &optional msg-type)
+  "Helper for handling offline and online messages.
+UIN is uin of message sender.
+MSG-TYPE is type of message.  Possible type: `emchat-v8-message-types'.
+MESSAGE is message body of any type."
+  (let ((alias (emchat-uin-alias (emchat-stringular-uin uin)))
+       (type msg-type))
+    (add-to-list 'emchat-active-aliases alias)
+
+    ;; Doctor
+    (if (and emchat-doctor-enabled-flag
+            (member alias emchat-doctor-patients))
+       (emchat-doctor message alias)
+      (when (and emchat-doctor-enabled-flag
+                (equal message emchat-doctor-begin-string))
+       (add-to-list 'emchat-doctor-patients alias)
+       (emchat-doctor-reply emchat-doctor-hello-string alias)))
+
+    ;; Notify
+    (cond
+     ((string-match ",,notify-me\\(\\s-\\|$\\)" message)
+      (add-to-list 'emchat-online-notifiers alias)
+      (emchat-v8-send-simple-message
+       emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias))
+       "Online notification request set.
+Send \",,cancel-notify\" to cancel.")
+      (emchat-log-system (format "Online notify requested by: %s" alias))
+      (emchat-play-sound-maybe 'system-sound))
+     ((string-match ",,cancel-notify\\(\\s-\\|$\\)" message)
+      (setq emchat-online-notifiers (remove alias emchat-online-notifiers))
+      (emchat-v8-send-simple-message
+       emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias))
+       "Online notification request cancelled.")
+      (emchat-log-system (format "Online notify cancellation: %s" alias))
+      (emchat-play-sound-maybe 'system-sound)))
+
+    ;; Auto-response
+    (when (and emchat-auto-response-messages-p
+               (member emchat-user-status
+                       '("away" "na" "dnd" "occ")))
+      (if emchat-user-auto-away-p
+          (progn
+            (setq emchat-auto-reply-p t)
+            (emchat-idle-reply-maybe alias))
+        (emchat-auto-reply-maybe alias)))
+
+    (run-hooks 'emchat-new-message-hook)
+    
+    (case type
+      (normal
+       (emchat-log-buddy-message
+        alias "%s" (emchat-decode-string message))
+       (emchat-play-sound-maybe 'message-sound))
+      (chat-request 
+       (emchat-log-buddy-message 
+       alias "Request chat")
+       (emchat-play-sound-maybe 'chat-sound))
+      (url
+       (multiple-value-bind (message url)
+           (values-list (split-string message "\xfe"))
+         (emchat-log-buddy-url
+          alias (emchat-decode-string message) (emchat-decode-string url))
+         (emchat-play-sound-maybe 'url-sound)))
+      ;; Athorization messages
+      (auth-accept
+       (emchat-log-buddy-message 
+       alias "Authorisation Accepted!")
+       (emchat-play-sound-maybe 'auth-sound))
+      (auth-reject
+       (emchat-log-buddy-message
+        alias "Authorisation Rejected!\nReason: %s"
+       (substring (emchat-decode-string message) 0 -1))
+       (emchat-play-sound-maybe 'auth-sound))
+      (auth-request
+       (emchat-log-buddy-message
+        alias "Authorisation Request\nReason: %s"
+        (emchat-decode-string message))
+       (emchat-play-sound-maybe 'auth-sound))
+      ;; Pager messages
+      (web-pager
+       (emchat-log-buddy-message
+        alias "Web Pager = %s"
+        (emchat-decode-string
+        (replace-in-string message "[\xfe]+" "\n")))
+       (emchat-play-sound-maybe 'pager-sound))
+      (email-pager
+       (emchat-log-buddy-message 
+       alias "Email Pager = %s"
+       (emchat-decode-string
+        (replace-in-string message "[\xfe]+" "\n")))
+       (emchat-play-sound-maybe 'pager-sound))
+      (email-express
+       (emchat-log-buddy-message
+        alias "Email express = %s"
+        (emchat-decode-string
+         (replace-in-string message "[\xfe]+" "\n")))
+       (emchat-play-sound-maybe 'emailx-sound))
+      (added
+       (emchat-log-system (format "%s %s" alias message))
+       (emchat-play-sound-maybe 'system-sound))
+      (contact-list
+       (emchat-log-buddy-message
+        alias "Contact list = %s"
+        (emchat-decode-string
+         (replace-in-string message "\xfe" "\n"))))
+      (get-away
+       (let ((visible (or (member alias emchat-visible-contacts)
+                         (not (member alias emchat-invisible-contacts)))))
+        (emchat-log-system (format "%s requested our away msg (%s)"
+                                 alias
+                                 (if visible "sent" "not sent")))
+        (when visible
+          (emchat-send-message-helper
+           emchat-auto-reply-away
+           (list alias) 'automatic "away msg sent"))))
+      (get-occ
+       (let ((visible (or (member alias emchat-visible-contacts)
+                         (not (member alias emchat-invisible-contacts)))))
+        (emchat-log-system (format "%s requested our occupied msg (%s)"
+                                 alias
+                                 (if visible "sent" "not sent")))
+        (when visible
+          (emchat-send-message-helper
+           emchat-auto-reply-occ
+           (list alias) 'automatic "occ msg sent"))))
+      (get-na
+       (let ((visible (or (member alias emchat-visible-contacts)
+                         (not (member alias emchat-invisible-contacts)))))
+        (emchat-log-system (format "%s requested our not available msg (%s)"
+                                 alias
+                                 (if visible "sent" "not sent")))
+        (when visible
+          (emchat-send-message-helper
+           emchat-auto-reply-na
+           (list alias) 'automatic "na msg sent"))))
+      (get-dnd
+       (let ((visible (or (member alias emchat-visible-contacts)
+                         (not (member alias emchat-invisible-contacts)))))
+        (emchat-log-system (format "%s requested our dnd msg (%s)"
+                                 alias
+                                 (if visible "sent" "not sent")))
+        (when visible
+          (emchat-send-message-helper
+           emchat-auto-reply-dnd
+           (list alias) 'automatic "dnd msg sent"))))
+      (get-ffc
+       ;; TODO: send our free-for-chat message
+       )
+      ;; SRV_MISSED_ICBM
+      (missed
+       (emchat-log-system (format "%s" message))
+       (emchat-play-sound-maybe 'system-sound))
+      (automatic
+       (emchat-log-buddy-message
+       alias "-=[Automatic Response]=-\n%s"
+       (emchat-decode-string message))
+       (emchat-play-sound-maybe 'system-sound))
+      (otherwise (push (cons 'unknown-message-types
+                             emchat-recent-packet)
+                       emchat-error-packets)
+                 (emchat-log-error "Unknown message type: %S" msg-type)))))
+
+(defvar emchat-auto-reply-never emchat-auto-response-never-send-to
+  "List of people to never send auto-responses to.")
+
+(defun emchat-auto-reply (alias)
+  "Auto-reply to ALIAS/uin depending on `emchat-user-status'.
+Called by `emchat-do-message-helper'."
+  (let ((message (symbol-value (emchat-status-auto-reply emchat-user-status))))
+    (when message
+      (add-to-list 'emchat-active-aliases alias)
+      (emchat-send-message-helper
+       message (list alias) 'automatic "Auto reply sent"))))
+
+(defun emchat-auto-reply-maybe (alias)
+  "Possibly send an auto-response to ALIAS."
+  (unless (or (member alias emchat-auto-reply-never)
+             (member alias emchat-auto-response-never-send-to)
+             (member alias emchat-invisible-contacts)
+             (not (member alias emchat-visible-contacts)))
+    (emchat-auto-reply alias)
+    (add-to-list 'emchat-auto-reply-never alias)))
+
+(defun emchat-idle-reply (alias)
+  "Auto-reply to ALIAS/uin depending on `emchat-user-status'.
+Called by `emchat-do-message-helper'."
+  (let ((message (symbol-value (emchat-status-idle-reply emchat-user-status))))
+    (when message
+      (add-to-list 'emchat-active-aliases alias)
+      (emchat-send-message-helper
+       message (list alias) 'automatic "Idle reply sent"))))
+
+(defun emchat-idle-reply-maybe (alias)
+  "Possibly send an auto-response to ALIAS."
+  (unless (or (member alias emchat-auto-reply-never)
+             (member alias emchat-auto-response-never-send-to)
+             (member alias emchat-invisible-contacts)
+             (not (member alias emchat-visible-contacts)))
+    (emchat-idle-reply alias)
+    (add-to-list 'emchat-auto-reply-never alias))
+  (setq emchat-auto-reply-p nil))
+
+;;; FIXME: this isn't used, but having IP and port info in emchat-world
+;;; would be nice to have again.
+; (defun emchat-do-online (packet)
+;   "Handle server command 006e in PACKET."
+;   (let ((alias (emchat-bin-alias packet 21))
+;         (status (emchat-status-name (substring packet 38 39)))
+;         (ip (emchat-bin-ip packet 25))
+;         (port (emchat-bin-uin packet 29))
+;         (real-ip (emchat-bin-ip packet 33)))
+;     (if (emchat-valid-uin-p alias)
+;         (push (cons 'unknown-alias emchat-recent-packet)
+;               emchat-error-packets))
+;     (emchat-buddy-update-status alias status)
+;     (emchat-play-sound-maybe 'buddy-sound)
+;     (emchat-world-putf alias 'ip ip)
+;     (emchat-world-putf alias 'port port)
+;     (emchat-world-putf alias 'real-ip real-ip)))
+
+(defun emchat-do-login-confirm (ectx)
+  "Called when emchat successfully connected to icq server."
+  (emchat-log-debug "Successfully logged in to ICQ server")
+  (emchat-log-system "Connected to %s:%d"
+                  (emchat-v8-ctx-host ectx)
+                  (emchat-v8-ctx-port ectx))
+  (emchat-change-status emchat-user-initial-status 'no-network)
+  (emchat-keep-alive-start)
+  (emchat-check-contact-list)
+  (emchat-activate-contact-list)
+  (message "Welcome to EMchat...")
+  (if emchat-is-auto-reconnecting
+      (setq emchat-is-auto-reconnecting nil)
+    (emchat-show-window)))
+
+;;; FIXME:  What to do with this in v8?
+; (defun emchat-do-system-message (packet)  ; TODO
+;   "Handle server command 01c2 in PACKET."
+;   (run-hooks 'emchat-system-message-hook))
+
+(defun emchat-format-field (field field-var &optional format)
+  "Format FIELD.
+FORMAT specifies format to use for FIELD (default is \"%15s: %s\").
+
+Note: USE THIS FUNCTION VERY CAREFULY."
+  (let ((fi-name (cdr (assq field field-var)))
+        (fi-val (emchat-get-arg field)))
+    ;; NOTE: Do not format empty strings
+    (cond ((null fi-val) nil)
+          ((stringp fi-val)
+           (unless (string= fi-val "")
+             (format (or format "%15s: %s\n") fi-name fi-val)))
+          (t (format (or format "%15s: %S\n") fi-name fi-val)))))
+
+(defun emchat-add-user-ssi (uin nick ssi-grp id)
+  "Send a request to add UIN to your server side contact list.
+
+NICK is the name that will appear in the buddy buffer.  It defaults to
+whatever UIN has set their nick name to.  It can be overridden, in
+fact, you'll be asked if you want to keep the default or choose another
+nick name.
+
+Argument, SSI-GRP is the server side group ID this contact
+should be added to.  EMchat has its own notion of contact groups so
+SSI-GRP will rarely, if ever, be need to be set by hand.  A value for
+it is obtained from existing group IDs in world.
+
+Argument, ID, is the server side contact ID for this contact.  It is
+simply the highest ID from world incremented by 1.
+
+This might change in the future when EMchat has better SSI handling."
+  (let* ((uin (emchat-stringular-uin uin)))
+    (progn
+      (emchat-v8-snac-cli-ssi-edit-begin emchat-ctx)
+      (emchat-v8-snac-cli-ssi-add emchat-ctx uin ssi-grp id nick)
+      (emchat-v8-snac-cli-ssi-edit-end emchat-ctx))))
+
+(defun emchat-do-about-general (ectx &rest ih-arguments)
+  "Handle incoming general about info."
+  (let* ((uin (emchat-get-arg :uin))
+         (alias (emchat-uin-alias (emchat-stringular-uin uin)))
+         (nick (emchat-get-arg :nick)))
+    ;; Dynamically add a new user to your contact list.
+    (if (and (not (member (emchat-stringular-uin uin) emchat-all-uin))
+            emchat-add-user-p)
+       (let ((ssi-grp (emchat-world-ssi-grp))
+             (id (emchat-world-next-ssi-id)))
+         (setq nick (if (y-or-n-p
+                         (format "Default nick is set to: \"%s\", accept: "
+                                 nick))
+                        nick
+                      (read-string "New nick name: " nil nil alias)))
+         ;; ensure we have a valid nick name
+         (loop until (string-match "^[^:]" nick)
+           do (setq nick
+                    (read-string "Invalid Alias (can't begin with \":\"): "
+                                 nil nil alias)))
+         ;; load up a hash table to carry new user info over to world
+         (setq emchat-world-new-user-hash (make-hash-table :test #'equal :size 6))
+         (puthash :uin uin emchat-world-new-user-hash)
+         (puthash :nick nick emchat-world-new-user-hash)
+         (puthash :ssi-grp ssi-grp emchat-world-new-user-hash)
+         (puthash :id id emchat-world-new-user-hash)
+         (puthash :egrps
+                  (read-string 
+                   "Add user to group[s] (fmt: :group1 :group2 or RET for none): ")
+                  emchat-world-new-user-hash)
+         (emchat-add-user-ssi uin nick ssi-grp id))
+      ;; Not adding new user, output about info
+      (emchat-log-info
+       (emchat-decode-string
+        (concat
+         "GENERAL about result =\n"
+         (format "%15s: %d\n" "UIN" uin)
+         (format "%15s: %s\n" "Local alias" alias)
+         (apply 'concat
+                (mapcar #'(lambda (field)
+                            (emchat-format-field (car field) emchat-about-fields))
+                        emchat-about-fields))
+         "--- END ---"))))))
+
+(defun emchat-do-about-more (ectx &rest ih-arguments)
+  "Handle incoming more about info."
+  (let* ((uin (emchat-get-arg :uin))
+         (alias (emchat-uin-alias (emchat-stringular-uin uin))))
+    (emchat-log-info
+     (emchat-decode-string
+      (concat
+       "MORE about result =\n"
+       (format "%15s: %d\n" "UIN" uin)
+       (format "%15s: %s\n" "Local alias" alias)
+       (apply 'concat
+              (mapcar #'(lambda (field)
+                          (emchat-format-field (car field) emchat-about-more-fields))
+                      emchat-about-more-fields))
+       "--- END ---")))))
+
+(defun emchat-do-about-about (ectx &rest ih-arguments)
+  "Handle incoming user notes info."
+  (let* ((uin (emchat-get-arg :uin))
+         (alias (emchat-uin-alias (emchat-stringular-uin uin))))
+    (emchat-log-info
+     (emchat-decode-string
+      (concat
+       "ABOUT about result =\n"
+       (format "%15s: %d\n" "UIN" uin)
+       (format "%15s: %s\n" "Local alias" alias)
+       (emchat-get-arg :about) "\n"
+       "--- END ---")))))
+
+(defun emchat-do-search-found (ecxt &rest ih-arguments)
+  "A user we were looking for is found."
+  (apply 'emchat-do-about-general ecxt ih-arguments))
+
+(defun emchat-do-search-found-last (ecxt &rest ih-arguments)
+  "The last user in the search has been found."
+  (apply 'emchat-do-about-general ecxt ih-arguments)
+
+  (let ((status (if (= (emchat-get-arg :status) 1) 'online 'offline)))
+    (if (zerop (emchat-get-arg :missed))
+        (if emchat-add-user-p
+           (puthash :status status emchat-world-new-user-hash)
+          (emchat-log-info "All search results returned"))
+      (emchat-log-info "Too many seach results"))))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-do-update-info-confirm (packet)
+;   "Handle server command 01e0 in PACKET."
+;   (emchat-log-info "Update info succeeded"))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-do-update-info-fail (packet)
+;   "Handle server command 01ea in PACKET."
+;   (emchat-log-info "Update info failed"))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-do-update-authorization-confirm (packet)
+;   "Handle server command 01f4 in PACKET."
+;   (emchat-log-info "Update authorization succeeded"))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-do-update-authorization-fail (packet)
+;   "Handle server command 01fe in PACKET."
+;   (emchat-log-info "Update authorization failed"))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-do-update-info-ext-confirm (packet)
+;   "Handle server command 01c8 in PACKET."
+;   (emchat-log-info "Update extended info succeeded"))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-do-new-account-uin (packet)
+;   "Handle server command 0046 in PACKET."
+;   (emchat-log-info
+;    "New uin: %s"
+;    (emchat-bin-uin packet 13)))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-do-search-random-user-found (packet)
+;   "Handle server command 0258 in PACKET."
+;   (if (< (length packet) 30)
+;       (emchat-log-info "Random user search failed")
+;     (emchat-query-info (emchat-bin-uin packet 21))))
+
+;;; Code - alias and uin:
+
+(defvar emchat-alias-history nil
+  "History of aliases in `emchat-completing-aliases'.")
+
+(defvar emchat-alias-list-history nil
+  "History of aliases in `emchat-send-message-helper'.
+For sending messages of any kind to a single alias, it records the same
+thing as `emchat-alias-history' does, while sending to multiple aliases, this
+records a list of aliases instead of one by one.  This faciliates
+re-sending to a list of aliases in future version.")
+
+(defvar emchat-connected-aliases nil
+  "Aliases that are in any statuses except 'invisible'.")
+
+(defvar emchat-active-aliases nil
+  "Aliases which we have exchanged messages with.")
+
+(defun emchat-process-alias-input (symbol)
+  "Input alias as selected or from completing.
+SYMBOL is the symbol of variable (`alias') to be processed.
+
+Non-nil SYMBOL means no processing.
+Negative argument (press \\[negative-argument] before this command) means
+taking all selected alias in buddy buffer as input.
+Prefix argument (press \\[universal-argument] before this command) means
+completing-read multi aliases from minibuffer.
+Otherwise, completing-read one alias from minibuffer.
+
+See `emchat-completing-aliases'."
+  (or (symbol-value symbol)
+      (set symbol
+           (if (eq '- current-prefix-arg)
+               (emchat-buddy-selected-in-view)
+             (emchat-completing-aliases "to: " (not current-prefix-arg))))))
+
+;;; Code - system main:
+
+(defvar emchat-blurb 
+  "As succinctly as possible, tell us:-\n
+\tWhat happened.
+\tWhat you thought should happen.
+\tAnything else that you think is relevant.\n
+*** Please delete these instructions before submitting the report. ***
+======================================================================\n"
+  "Preamble to the bug report.")
+
+;;;###autoload
+(defun emchat-login ()
+  "Login to ICQ server.
+Make connection to server and network if necessary."
+  (interactive)
+  (let* ((uin (progn
+                (emchat-world-update)
+                (emchat-numeric-uin (emchat-alias-uin emchat-user-alias))))
+        (password (or emchat-user-password
+                      (read-passwd (format "Password for %s (%d): "
+                                           emchat-user-alias uin)))))
+
+    (when (equal emchat-user-status "offline")
+      (or (emchat-valid-uin-p uin)
+         (error "Invalid user uin"))
+
+      (setq emchat-trimmed-packet nil) ; hack
+      (setq emchat-current-seq-num 0)
+      (emchat-log-show-buffer nil 'no-select)
+
+      ;; Create emchat v8 context
+      (setq emchat-ctx (emchat-v8-create-ctx uin password
+                      'connect-tries 10
+                      'initial-status (append (and emchat-user-meta-web-aware '(web-aware))
+                                             (and emchat-user-meta-invisible '(invisible))
+                                              (list (emchat-status-v8
+                                                     emchat-user-initial-status)))))
+      ;; Install incoming handlers
+      (setf (emchat-v8-ctx-incoming-handlers emchat-ctx)
+           (list 'instant-message 'emchat-do-instant-message
+                  'missed-message 'emchat-do-missed-message
+                 'offline-message 'emchat-do-offline-message
+                 'connected 'emchat-do-login-confirm
+                 'status-update 'emchat-do-status-update
+                  'about-general 'emchat-do-about-general
+                  'about-more 'emchat-do-about-more
+                  'about-about 'emchat-do-about-about
+                  'logoff 'emchat-do-forced-logoff
+                  'disconnect 'emchat-do-disconnect
+                  'search-found 'emchat-do-search-found
+                 'search-found-last 'emchat-do-search-found-last
+                 'added-you 'emchat-do-added-you
+                 'auth-request 'emchat-do-auth-request
+                 'auth-accept 'emchat-do-auth-accept
+                 'auth-reject 'emchat-do-auth-reject
+                 'srv-contacterr 'emchat-do-srv-contact-err
+                 'srv-error 'emchat-do-srv-general-err
+                 'new-user 'emchat-world-add-new-user
+                 ))
+      ;; Load SXEmacs media streams
+      (when (and emchat-use-sound-flag
+                (featurep 'sxemacs))
+       (emchat-load-media-streams))
+      (emchat-v8-connect emchat-ctx emchat-server emchat-port))))
+
+(autoload 'emchat-wharf-change-messages "emchat-wharf")
+
+(defun emchat-logout ()
+  "Logout ICQ server.
+Remain connected to network and server.
+Don't send logout packet if KILL is non-nil,
+useful for emergency logout when being kicked out by server."
+  (interactive)
+
+  (emchat-log-debug "Logging out ICQ server.")
+  (setq emchat-connected-aliases nil)
+  (emchat-buddy-show-buffer 'new 'no-select)
+  (emchat-change-status "offline" 'no-network)
+  (emchat-keep-alive-stop)
+  (if (and (featurep 'emchat-wharf)
+          (frame-live-p emchat-wharf-frame))
+      (progn
+       (emchat-wharf-change-messages "New" -9999)
+       (emchat-wharf-change-messages "Sys" -9999)))
+  (when emchat-history-enabled-flag
+    (mapcar
+     #'(lambda (alias)
+        (let* ((histf (emchat-world-getf alias 'history))
+               (histb (and histf (find-buffer-visiting histf))))
+          (when histb
+            (with-current-buffer histb
+              (save-buffer)
+              (kill-buffer nil)))))
+     emchat-all-aliases))
+  (when (emchat-connected-p emchat-ctx)
+    (emchat-v8-close emchat-ctx)))
+
+(defvar emchat-contact-list-packets nil
+  "Lists of remaining contact list packets to be sent.
+For experimental purpose only.")
+
+;; Now broken because local contact lists are no longer
+;; supported. `emchat-activate-contact-list' replaces this.
+;;(defun emchat-send-contact-list ()
+;;  "Send the whole contact list.
+;;You can resend contact list after `emchat-world-update'."
+;;  (interactive)
+
+;;  (setq emchat-connected-aliases nil)
+;;  (emchat-buddy-show-buffer 'new 'no-select)
+
+;;  (emchat-world-update)
+;;  ;; Visible
+;;  (when emchat-visible-contacts
+;;    (emchat-v8-ctx-put-prop emchat-ctx 'visible-list
+;;      (mapcar
+;;       #'(lambda (v)
+;;        (emchat-numeric-uin (emchat-alias-uin v)))
+;;       emchat-visible-contacts))
+;;    (emchat-v8-snac-cli-addvisible emchat-ctx))
+;;  ;; Invisible
+;;  (when emchat-invisible-contacts
+;;    (emchat-v8-ctx-put-prop emchat-ctx 'invisible-list
+;;      (mapcar
+;;       #'(lambda (i)
+;;        (emchat-numeric-uin (emchat-alias-uin i)))
+;;       emchat-invisible-contacts))
+;;    (emchat-v8-snac-cli-addinvisible emchat-ctx))
+;;  ;; All
+;;  (emchat-v8-ctx-put-prop emchat-ctx 'contacts
+;;    (mapcar 'emchat-numeric-uin (mapcar 'cadr emchat-world)))
+;;  (emchat-v8-snac-cli-add-contact emchat-ctx))
+
+(defun emchat-check-contact-list ()
+  "Checks to ensure local copy of SSI list is up to date."
+  (interactive)
+  (emchat-v8-snac-cli-ssi-checkout emchat-ctx))
+
+(defun emchat-activate-contact-list ()
+  "Activate the server-side contact list."
+  (interactive)
+  (setq emchat-connected-aliases nil)
+  (emchat-buddy-show-buffer 'new 'no-select)
+  (emchat-world-update)
+  ;; Visible
+  (when emchat-visible-contacts
+    (emchat-v8-ctx-put-prop emchat-ctx 'visible-list
+      (mapcar
+       #'(lambda (v)
+          (emchat-numeric-uin (emchat-alias-uin v)))
+       emchat-visible-contacts))
+    ; (emchat-v8-snac-cli-addvisible emchat-ctx)
+    )
+  ;; Invisible
+  (when emchat-invisible-contacts
+    (emchat-v8-ctx-put-prop emchat-ctx 'invisible-list
+      (mapcar
+       #'(lambda (i)
+          (emchat-numeric-uin (emchat-alias-uin i)))
+       emchat-invisible-contacts))
+    ; (emchat-v8-snac-cli-addinvisible emchat-ctx)
+    )
+  ;; All
+  (emchat-v8-ctx-put-prop emchat-ctx 'contacts
+    (mapcar 'emchat-numeric-uin (mapcar 'cadr emchat-world)))
+  (emchat-v8-snac-cli-ssi-activate emchat-ctx))
+
+(defun emchat-keep-alive-start ()
+  "Start keeping alive."
+  (emchat-keep-alive-stop)
+  (start-itimer
+   "emchat keep-alive"
+   (lambda ()
+     (emchat-v8-snac-cli-keepalive emchat-ctx))
+   ;; sending faster won't hurt
+   60 60))
+
+(defun emchat-keep-alive-stop ()
+  "Stop keeping alive."
+  (let ((itimer (get-itimer "emchat keep-alive")))
+    (when (itimerp itimer)
+      (delete-itimer itimer))))
+
+(defun emchat-add-user (uin)
+  (interactive "sUIN: ")
+  (setq emchat-add-user-p t)
+  (emchat-search-by-uin uin))
+
+(defun emchat-change-user (alias password)
+  "Change user to ALIAS with PASSWORD.
+Need to relogin afterwards."
+  (interactive
+   (append (emchat-completing-aliases "Change to: " 'single)
+           (list (read-passwd "Password: "))))
+  (setq emchat-user-alias alias)
+  (setq emchat-user-password
+   (if (zerop (length password))
+       nil
+     password)))
+
+(defun emchat-auto-away-timeout-set (&optional symbol value)
+  "Set timer for auto-away.  See `emchat-auto-away-timeout'."
+  (when (itimerp (get-itimer "emchat auto-away"))
+    (delete-itimer (get-itimer "emchat auto-away")))      ; delete previous
+  (start-itimer
+   "emchat auto-away"
+   (lambda ()
+     ;; auto away for first idle
+     (when (member emchat-user-status '("online" "ffc"))
+       (emchat-log-system "Auto away.")
+       (emchat-change-status "away")
+       (setq emchat-user-auto-away-p t)))
+   value value
+   'is-idle)
+  (when (itimerp (get-itimer "emchat auto-na"))
+    (delete-itimer (get-itimer "emchat auto-na")))
+  (start-itimer
+   "emchat auto-na"
+   (lambda ()
+     ;; auto na for second idle
+     (when (and emchat-user-auto-away-p 
+               (equal emchat-user-status "away"))
+       (emchat-log-system "Auto na.")
+       (emchat-change-status "na")
+       ;; emchat-change-status resets this flag
+       (setq emchat-user-auto-away-p t)))
+   (* 2 value) (* 2 value)
+   nil))
+
+(defcustom emchat-auto-away-timeout 300
+  "*Seconds of inactivity in Emacs before auto-away.
+
+After two times the seconds of auto-away, it goes auto-na.
+See `emchat-auto-away'.
+
+If you set this outside of the custom buffer you _MUST_ use
+`customize-set-variable' and _NOT_ `setq'."
+  :type 'number
+  :set 'emchat-auto-away-timeout-set
+  :initialize 'custom-initialize-default
+  :group 'emchat-option)
+
+(defun emchat-change-idle-timeout (&optional seconds)
+  "Change the number of SECONDS before EMchat will idle to \"away\".
+
+Setting the timeout here does not save the value across emacs sessions.
+To do that, customise the variable, `emchat-auto-away-timeout'."
+  (interactive)
+  (let ((timeout (or seconds
+                    (read-number
+                     "New idle timeout in seconds [RET for no change]: "
+                     nil "0"))))
+    (unless (zerop timeout)
+      (emchat-auto-away-timeout-set nil timeout))))
+
+(defun emchat-send-message-helper (message aliases type log-message)
+  "Send message, url, authorization or others.
+MESSAGE is the message to send.
+ALIASES is a list of aliases/uin to send to.
+TYPE is the type of message in `emchat-v8-message-types'.
+LOG-MESSAGE is a message to put in log.
+
+See `emchat-send-message', `emchat-send-url' and `emchat-authorize'."
+  (when (and emchat-user-auto-away-p
+            (not emchat-auto-reply-p))
+    (emchat-change-status "online"))
+  (add-to-list 'emchat-alias-list-history aliases)
+  (loop for alias in aliases
+    do (add-to-list 'emchat-active-aliases alias)
+    do (if (eq type 'normal)
+           (emchat-v8-send-simple-message
+            emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias)) message)
+         (emchat-v8-send-typed-message
+          emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias)) type message))
+    do (emchat-log-outgoing alias ">>> %s" log-message))
+  (setq emchat-auto-reply-p nil))
+
+(defvar emchat-message-history nil
+  "History of `emchat-send-message' for `completing-read'.")
+
+(defun emchat-send-message (&optional message &rest aliases)
+  "Send an instant message.
+MESSAGE is the message to send.
+ALIASES is a list of aliases/uin to send to.
+
+See `emchat-process-alias-input'."
+  (interactive "P")
+  (let ((prompt
+         (concat "Message"
+                 ;; display alias if given
+                 (if (car aliases)
+                     (concat " to "
+                             (substring (format "%s" aliases) 1 -1)))
+                 ": ")))
+    (or (stringp message)
+        (setq message
+              (read-from-minibuffer prompt
+               nil nil nil 'emchat-message-history)))
+
+    ;; idea from Erik Arneson <erik@starseed.com>
+    ;; confirm sending a blank message
+    (unless (and (or (zerop (length message))
+                     ;; \\W fails with "=)" or "..."
+                     (string-match "^[ \t]+$" message))
+                 (not (y-or-n-p "Send a blank message? ")))
+      (emchat-process-alias-input 'aliases)
+
+      ;; apply encode only TEXT portion of packet
+      (let ((msg (emchat-splitter message)))
+       (loop for x in msg
+         do (emchat-send-message-helper
+             ;; encoding outgoing but not that to be insert in log buffer
+             (emchat-encode-string x) aliases 'normal x)
+         do (when (and (> (length msg) 1)
+                     (not (string= x (car (last msg)))))
+            (sit-for 1)))))))
+
+(defun emchat-send-message-via-mouse (event)
+  ;; Erik Arneson <erik@starseed.com> (from VM)
+  "`emchat-send-message' via mouse."
+  (interactive "e")
+  (set-buffer (window-buffer (event-window event)))
+  (and (event-point event) (goto-char (event-point event)))
+  (if (eq (current-buffer) emchat-buddy-buffer)
+      (emchat-send-message-alias-here)
+    ;; fall through
+    ;; any alias in log-mode format (enclosed by []) can use this
+    (emchat-send-message-alias-around)))
+
+(defvar emchat-url-history nil
+  "History of `emchat-send-url' for `completing-read'.")
+
+(defun emchat-send-url (&optional url description &rest aliases)
+  "Send an url.
+URL is any Internet address.
+DESCRIPTION is the description of url.
+ALIASES is a list of aliases/uin to send to.
+
+See `emchat-process-alias-input'."
+  (interactive "P")
+  (let ((prompt
+         (concat "url"
+                 ;; display alias if given
+                 (if (car aliases)
+                     (concat " to "
+                             (substring (format "%s" aliases) 1 -1)))
+                 ": ")))
+    (or (stringp url)
+        (setq url
+              (read-from-minibuffer
+               prompt nil nil nil 'emchat-url-history)))
+
+    ;; idea from Erik Arneson <erik@starseed.com>
+    ;; confirm sending a blank url
+    (unless (and (or (zerop (length url))
+                     ;; \\W fails with "=)" or "..."
+                     (string-match "^[ \t]+$" url))
+                 (not (y-or-n-p "Send a blank url? ")))
+      (or description
+          (setq description
+                (read-from-minibuffer
+                 "description: " nil nil nil 'emchat-message-history)))
+      (emchat-process-alias-input 'aliases)
+
+      (emchat-send-message-helper
+       (format "%s\xfe%s"
+               ;; encode only to TEXT portions of packet, instead of the whole
+               (emchat-encode-string description)
+               (emchat-encode-string url))
+       aliases 'url (format "%s (%s)" url description)))))
+
+(defun emchat-authorize (alias)
+  "Send authorization to allow adding to contact list.
+ALIAS is an alias/uin."
+  (interactive
+   (list (car (emchat-completing-aliases "Authorisation for: " 'single))))
+  (let (reply)
+    (if (y-or-n-p "Accept the authorisation request? ")
+       (progn
+         (setq reply 1)
+         (emchat-log-buddy-message alias ">>> %s" emchat-auth-accept-reason))
+      (setq reply 0)
+      (emchat-log-buddy-message alias ">>> %s" emchat-auth-reject-reason))
+    (emchat-v8-snac-cli-ssi-auth-reply
+     emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias))
+     reply
+     (if (zerop reply)
+        emchat-auth-reject-reason
+       emchat-auth-accept-reason))))
+
+(defun emchat-auth-request (alias)
+  "Request authorisation from ALIAS."
+  (interactive
+   (list (car (emchat-completing-aliases 
+              "Request Authorisation from: " 'single))))
+  (emchat-v8-snac-cli-ssi-send-auth-request
+   emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias))
+   emchat-auth-request-reason)
+  (emchat-log-info "Authorisation requested from: %s" alias))
+
+(defun emchat-request-away (&optional alias)
+  "Request away message from ALIAS."
+  (interactive)
+  (unless alias
+    (setq alias (car (emchat-completing-aliases
+                     "Get Away message from: " 'single))))
+  (emchat-send-message-helper
+   "" (list alias) 'get-away "Away message requested"))
+
+(defun emchat-request-na (&optional alias)
+  "Request Not Avaliable message from ALIAS."
+  (interactive)
+  (unless alias
+    (setq alias (car (emchat-completing-aliases
+                     "Get Not Available message from: " 'single))))
+  (emchat-send-message-helper
+   "" (list alias) 'get-na "Not Available message requested"))
+
+(defun emchat-request-dnd (&optional alias)
+  "Request Do Not Disturb message from ALIAS."
+  (interactive)
+  (unless alias
+    (setq alias (car (emchat-completing-aliases
+                     "Get Do Not Disturb message from: " 'single))))
+  (emchat-send-message-helper
+   "" (list alias) 'get-dnd "Do Not Disturb message requested"))
+
+(defun emchat-request-occ (&optional alias)
+  "Request occupied message from ALIAS."
+  (interactive)
+  (unless alias
+    (setq alias (car (emchat-completing-aliases
+                     "Get Occupied message from: " 'single))))
+  (emchat-send-message-helper
+   "" (list alias) 'get-occ "Occupied message requested"))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-register-new-user (password)
+;   "Register a new uin with PASSWORD."
+;   (interactive (list (read-passwd "Password: " 'confirm)))
+;   (emchat-send (emchat-pack-register-new-user password)))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-change-password (password)
+;   "Change PASSWORD."
+;   (interactive (list (read-passwd "Password: " 'confirm)))
+;   (emchat-send (emchat-pack-meta-user-change-password password)))
+
+(defun emchat-search (&optional online first last nick email)
+  "Search for ICQ users.
+
+Optional prefix arg, ONLINE when non-nil means to only return search
+results for ICQ users that are currently online.
+
+Argument FIRST - first name to search for
+Argument LAST  - last name to search for
+Argument NICK  - nick name to search for
+Argument EMAIL - email address to search for."
+  (interactive "P")
+  (let ((online (if online
+                   1
+                 (if current-prefix-arg
+                     1
+                   0)))
+       (first (if (interactive-p)
+                  (read-string "First Name [RET for null]: ")
+                (or first "")))
+       (last (if (interactive-p)
+                 (read-string "Last Name [RET for null]: ")
+               (or last "")))
+       (nick (if (interactive-p)
+                 (read-string "Nick Name [RET for null]: ")
+               (or nick "")))
+       (email (if (interactive-p)
+                  (read-string "Email Address [RET for null]: ")
+                (or email ""))))
+    (when (string= "" (concat first last nick email))
+      (error 'invalid-argument "You must provide at least one search term"))
+    (emchat-v8-snac-cli-searchbypersinf
+     emchat-ctx first last nick email online)))
+
+(defun emchat-search-by-uin (uin)
+  "Search user by UIN."
+  (interactive "sUIN: ")
+  (emchat-v8-snac-cli-searchbyuin
+   emchat-ctx (emchat-numeric-uin uin)))
+
+(defun emchat-search-by-email (email)
+  "Search for a user by their EMAIL address."
+  (interactive "sEmail address: ")
+  (emchat-v8-snac-cli-searchbyemail emchat-ctx email))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-search-random-user (group)
+;   "Search random user in GROUP."
+;   (interactive
+;    (list (emchat-completing-read
+;           "Random group: "
+;           (mapcar 'car emchat-random-groups))))
+;   (emchat-send (emchat-pack-search-random-user group)))
+
+;;; FIXME: This needs to be updated for v8
+; (defun emchat-set-random-group (group)
+;   "Set random user GROUP."
+;   (interactive
+;    (list (emchat-completing-read
+;           "Random group: "
+;           (mapcar 'car emchat-random-groups))))
+;   (emchat-send (emchat-pack-set-random-group group)))
+
+(defun emchat-query-info (&optional alias)
+  "Query meta user info.
+ALIAS is an alias/uin."
+  (interactive)
+  (if alias
+      ;; display alias if given
+      (message "Query %s." alias)
+    (setq alias (car (emchat-completing-aliases "Query: " 'single))))
+  (let ((local-info (emchat-world-info alias)))
+    (if local-info
+        (emchat-log-info "Local info:\n%s" local-info)))
+
+  (emchat-v8-snac-cli-metareqinfo
+   emchat-ctx (emchat-numeric-uin (emchat-alias-uin alias))))
+
+(defun emchat-add-to-visible-list (aliases)
+  "Add ALIASES, a list of alias names/UINs, to your visible list."
+  (interactive
+   (list (emchat-completing-aliases "Visible to alias/UIN (RET to send): ")))
+  (let ((uins (mapcar
+              #'(lambda (alias)
+                  (emchat-numeric-uin (emchat-alias-uin alias)))
+              aliases)))
+    (emchat-v8-snac-cli-addvisible emchat-ctx uins)
+    (mapcar
+     #'(lambda (alias)
+        (add-to-list 'emchat-visible-contacts alias 'append))
+     aliases)
+    (emchat-log-info "You are now visible to: %s" aliases)
+    (when (y-or-n-p "Do you want this change saved for future sessions ")
+      (customize-save-variable 'emchat-visible-contacts 
+                              (symbol-value 'emchat-visible-contacts)))))
+    
+(defun emchat-add-to-invisible-list (aliases)
+  "Add ALIASES, a list of alias names/UINs, to your invisible list."
+  (interactive
+   (list (emchat-completing-aliases "Invisible to alias/UIN (RET to send): ")))
+  (let ((uins (mapcar
+              #'(lambda (alias)
+                  (emchat-numeric-uin (emchat-alias-uin alias)))
+              aliases)))
+    (emchat-v8-snac-cli-addinvisible emchat-ctx uins)
+    (mapcar
+     #'(lambda (alias)
+        (add-to-list 'emchat-invisible-contacts alias 'append))
+     aliases)
+    (emchat-log-info "You are now invisible to: %s" aliases)
+    (when (y-or-n-p "Do you want this change saved for future sessions ")
+      (customize-save-variable 'emchat-invisible-contacts 
+                              (symbol-value 'emchat-invisible-contacts)))))
+
+(defun emchat-remove-from-visible-list (aliases)
+  "Remove ALIASES, a list of alias names/UINs, from your visible list."
+  (interactive
+   (list (emchat-completing-aliases "Not visible to alias/UIN (RET to send): ")))
+  (let ((uins (mapcar #'(lambda (alias)
+                         (emchat-numeric-uin (emchat-alias-uin alias)))
+                     aliases))
+       nvis)
+    (mapcar
+     #'(lambda (alias)
+        (setq emchat-visible-contacts
+              (remove alias emchat-visible-contacts)))
+     aliases)
+    (setq nvis
+         (mapcar #'(lambda (alias)
+                     (emchat-numeric-uin (emchat-alias-uin alias)))
+                 emchat-visible-contacts))
+    (emchat-v8-ctx-put-prop emchat-ctx 'visible-list nvis)
+    (emchat-v8-snac-cli-remvisible emchat-ctx uins)
+    (emchat-log-info "You are no longer visible to: %s" aliases)
+    (when (y-or-n-p "Do you want this change saved for future sessions ")
+      (customize-save-variable 'emchat-visible-contacts
+                              (symbol-value 'emchat-visible-contacts)))))
+
+(defun emchat-remove-from-invisible-list (aliases)
+  "Remove ALIASES, a list of alias names/UINs, from your invisible list."
+  (interactive
+   (list (emchat-completing-aliases "Not invisible to alias/UIN (RET to send): ")))
+  (let ((uins (mapcar #'(lambda (alias)
+                         (emchat-numeric-uin (emchat-alias-uin alias)))
+                     aliases))
+       nvis)
+    (mapcar
+     #'(lambda (alias)
+        (setq emchat-invisible-contacts
+              (remove alias emchat-invisible-contacts)))
+     aliases)
+    (setq nvis
+         (mapcar #'(lambda (alias)
+                     (emchat-numeric-uin (emchat-alias-uin alias)))
+                 emchat-invisible-contacts))
+    (emchat-v8-ctx-put-prop emchat-ctx 'invisible-list nvis)
+    (emchat-v8-snac-cli-reminvisible emchat-ctx uins)
+    (emchat-log-info "You are no longer invisible to: %s" aliases)
+    (when (y-or-n-p "Do you want this change saved for future sessions ")
+      (customize-save-variable 'emchat-invisible-contacts
+                              (symbol-value 'emchat-invisible-contacts)))))
+
+(defun emchat-remove-yourself-from-buddy (alias)
+  "Removes your entry from ALIAS' server side contact list."
+  (interactive
+   (list (emchat-completing-read
+         "UIN: "
+         (mapcar #'number-to-string emchat-world-recently-added-by)
+         #'(lambda (match)
+             (not (or (member match emchat-all-uin)
+                      emchat-world-track-all-adds))))))
+  (let ((uin (emchat-numeric-uin (emchat-alias-uin alias))))
+    (emchat-v8-snac-cli-ssi-del-yourself emchat-ctx uin)
+    (emchat-log-info "You have removed yourself from %s's server-side
+contact list.  When %1$s cycles their ICQ connection you should
+disappear from their local list as well."
+                    alias)
+    (setq emchat-world-recently-added-by
+         (delete (emchat-numeric-uin uin) emchat-world-recently-added-by))
+    (with-current-buffer (find-file-noselect
+                         emchat-recently-added-by-filename)
+      (erase-buffer)
+      (mapcar
+       #'(lambda (el)
+          (insert (emchat-stringular-uin el)))
+       emchat-world-recently-added-by)
+      (save-buffer)
+      (kill-buffer nil))))
+
+(autoload 'emchat-wharf-new-frame "emchat-wharf")
+
+(defun emchat-switch-to-buddy-buffer ()
+  "Switches from the log buffer to the buddy buffer."
+  (interactive)
+  (emchat-switch-buffer emchat-buddy-buffer))
+
+(defun emchat-switch-to-log-buffer ()
+  "Switches from the buddy buffer to the log buffer."
+  (interactive)
+  (emchat-switch-buffer emchat-log-buffer))
+
+;;;###autoload
+(defun emchat-show-window ()
+  "Show windows of emchat buffers.
+Make them if not yet done.
+See `emchat-buddy-buffer' and `emchat-log-buffer'."
+  (interactive)
+  (unless (frame-live-p emchat-frame)
+    (setq emchat-frame
+         (if (and emchat-start-in-new-frame
+                  (device-on-window-system-p))
+             (new-frame '((name . "EMchatLog")))
+           (last-nonminibuf-frame))))
+  (when (device-on-window-system-p)
+    (select-frame emchat-frame))
+  (emchat-buddy-show-buffer)
+  (if emchat-status-use-gutter
+      (progn
+       (set-specifier top-gutter-visible-p t emchat-frame)
+       (emchat-update-tab-in-gutter))
+    (emchat-status-show-buffer))
+  (emchat-log-show-buffer)
+  (set-window-buffer nil emchat-buddy-buffer)
+  (delete-other-windows)
+  (set-window-buffer
+   (split-window nil emchat-buddy-window-width t) emchat-log-buffer)
+  (if emchat-status-use-gutter
+      (emchat-switch-buffer emchat-log-buffer)
+    (set-window-buffer nil emchat-status-buffer)
+    (set-window-buffer
+     (split-window nil emchat-status-window-height) emchat-buddy-buffer)
+    (emchat-switch-buffer emchat-log-buffer))
+  (save-excursion
+    (if emchat-wharf-frame-use-p
+       (emchat-wharf-new-frame)))
+  (focus-frame emchat-frame))
+
+(defun emchat-hide-window ()
+  "Hide windows of emchat buffers."
+  (interactive)
+  (delete-other-windows)
+  (loop for each in '(emchat-buddy-buffer 
+                     emchat-log-buffer 
+                     emchat-status-buffer
+                     emchat-debug-buffer)
+    do (when (buffer-live-p (symbol-value each))
+        (bury-buffer (symbol-value each))))
+  (bury-buffer)
+  (when emchat-status-use-gutter
+    (set-specifier top-gutter-visible-p nil emchat-frame)))
+
+(defun emchat-window-hidden-p ()
+  "Returns non-nil when the EMchat buffers are hidden."
+  (if (or (get-buffer-window emchat-log-buffer emchat-frame)
+         (get-buffer-window emchat-buddy-buffer emchat-frame)
+         (get-buffer-window emchat-status-buffer emchat-frame))
+      nil
+    t))
+
+;;; Code - log:
+
+;; message history buffer
+
+(defun emchat-alias-around ()
+  "Return an alias/uin on current line or lines before.
+If called interactively, display and push alias into `kill-ring'."
+  (interactive)
+  (save-excursion
+    (outline-back-to-heading)
+    (looking-at "^...:.. \\[\\([^]]+\\)\\]")
+    (let ((alias (match-string 1)))
+      (cond
+       ((or (member alias emchat-all-aliases)
+              (emchat-valid-uin-p alias))
+        (when (interactive-p)
+          (message alias)
+          (kill-new alias))
+        alias)
+       (t (error "No valid alias/uin found"))))))
+
+(defun emchat-oops ()
+  "Oops that message went to the wrong person.
+
+When you accidently send a message to the wrong person, `emchat-oops'
+can be used to send the original message to the correct person and
+send the wrong person an explanation.  The explanation sent is the
+value of `emchat-oops-msg-wrong-recipient'.
+
+You will be prompted for the new contact to send to."
+  (interactive)
+  (let ((message (emchat-log-around))
+       (alias (emchat-alias-around)))
+    (emchat-send-message emchat-oops-msg-wrong-recipient alias)
+    (emchat-send-message message)))
+
+(defun emchat-forward-message-around (&optional no-header)
+  "Forward message around
+Non-nil NO-HEADER means avoid prefixing message with original sender's
+info.
+ALIASES is a list of aliases/uin to send to.
+
+See `emchat-process-alias-input'."
+  (interactive "P")
+  (let* ((message (emchat-log-around))
+         (alias (emchat-alias-around))
+         (uin (emchat-alias-uin alias)))
+    (emchat-send-message
+     (concat
+      (if (not no-header)
+          (format "%s (ICQ#%s) Wrote:\n" alias uin))
+      message))))
+
+(defun emchat-forward-message-around-without-header ()
+  "See `emchat-forward-message-around'."
+  (interactive)
+  (emchat-forward-message-around 'no-header))
+
+(defun emchat-select-alias-around ()
+  "See `emchat-group-select-aliases' and `emchat-alias-around'."
+  (interactive)
+  (emchat-group-select-aliases 'toggle (emchat-alias-around)))
+
+(defun emchat-send-message-alias-around ()
+  "See `emchat-send-message' and `emchat-alias-around'."
+  (interactive)
+  (emchat-log-mark 'read)
+  (when emchat-wharf-frame-use-p
+    (emchat-wharf-dec-messages))
+  (emchat-send-message nil (emchat-alias-around)))
+
+(defun emchat-send-url-alias-around ()
+  "See `emchat-send-url' and `emchat-alias-around'."
+  (interactive)
+  (emchat-log-mark 'read)
+  (when emchat-wharf-frame-use-p
+    (emchat-wharf-dec-messages))
+  (emchat-send-url nil nil (emchat-alias-around)))
+
+(defun emchat-authorize-alias-around ()
+  "See `emchat-authorize' and `emchat-alias-around'."
+  (interactive)
+  (emchat-authorize (emchat-alias-around)))
+
+(defun emchat-query-info-alias-around ()
+  "See `emchat-query-info' and `emchat-alias-around'."
+  (interactive)
+  (emchat-query-info (emchat-alias-around)))
+
+;;; Code - buddy:
+
+;; contact list (list of aliases) buffer
+
+(defun emchat-alias-here ()
+  "Return an alias/uin on current line.
+Leading or trailing whitespace are ignored.
+If called interactively, display and push alias into `kill-ring'."
+  (interactive)
+  (save-excursion
+    (end-of-line)
+    (let ((alias
+           (buffer-substring
+            (progn
+              (beginning-of-line)
+              (skip-chars-forward "[ \t]")
+              (point))
+            (progn
+              (end-of-line)
+              (skip-chars-backward "[ \t]")
+              (point)))))
+      (cond
+       ((or (member alias emchat-all-aliases)
+            (emchat-valid-uin-p alias))
+        (when (interactive-p)
+          (message alias)
+          (kill-new alias))
+          alias)
+       (t (error "No valid alias/uin found"))))))
+
+(defun emchat-select-alias-here (action)
+  "See `emchat-group-select-aliases' and `emchat-alias-here'.
+Nil or 'toggle ACTION means toggle selection for alias here.
+`numberp' action or digit arguments (press \\[digit-argument] before this
+command) means select the number of next/previous aliases.
+'toggle-all ACTION or prefix argument (press \\[universal-argument] before this command) means
+toggle selections for all aliases in view.
+'deselect-all or other non-nil ACTION or negative argument (press
+\\[negative-argument] before this command) means deselect for all aliases
+in view.
+
+See `emchat-buddy-select-all-in-view'."
+  (interactive
+   (list (cond
+          ((not current-prefix-arg) 'toggle)
+          ((eq '- current-prefix-arg) 'deselect-all)
+          ((numberp current-prefix-arg) current-prefix-arg)
+          (t 'toggle-all))))
+  (cond
+   ((or (not action) (eq action'toggle))
+    (emchat-group-select-aliases 'toggle (emchat-alias-here))
+    (forward-line))
+   ((and (numberp action) (zerop action))) ; recurrsion done
+   ((natnump action)
+    (emchat-group-select-aliases 'select (emchat-alias-here))
+    (forward-line 1)
+    (emchat-select-alias-here (1- action)))
+   ((numberp action)                    ; negative digit
+    (emchat-group-select-aliases 'select (emchat-alias-here))
+    (forward-line -1)
+    (emchat-select-alias-here (1+ action)))
+   ((eq action 'toggle-all)
+    (emchat-buddy-select-all-in-view 'toggle))
+   ((eq action 'deselect-all)
+    (emchat-buddy-select-all-in-view nil))))
+
+(defun emchat-send-message-alias-here ()
+  "See `emchat-send-message' and `emchat-alias-here'."
+  (interactive)
+  (emchat-send-message nil (emchat-alias-here)))
+
+(defun emchat-send-url-alias-here ()
+  "See `emchat-send-url' and `emchat-alias-here'."
+  (interactive)
+  (emchat-send-url nil nil (emchat-alias-here)))
+
+(defun emchat-authorize-alias-here ()
+  "See `emchat-authorize' and `emchat-alias-here'."
+  (interactive)
+  (emchat-authorize (emchat-alias-here)))
+
+(defun emchat-query-info-alias-here ()
+  "See `emchat-query-info' and `emchat-alias-here'."
+  (interactive)
+  (emchat-query-info (emchat-alias-here)))
+
+;; Default toolbar button
+(defun emchat-toolbar-login ()
+  "Log into ICQ from the toolbar."
+  (interactive)
+  (call-interactively #'emchat-login))
+
+(defvar emchat-toolbar-icon
+  (toolbar-make-button-list
+   (expand-file-name "mini-logo.png" emchat-glyph-dir))
+  "EMchat button for the default toolbar.")
+
+(defvar emchat-toolbar-spec
+  (vector emchat-toolbar-icon
+         'emchat-toolbar-login
+         t
+         "Waste time with EMchat")
+  "EMchat default toolbar spec.")
+
+(defun emchat-add-to-toolbar ()
+  "Adds the EMchat button to the default toolbar."
+  (let ((origbar (specifier-instance default-toolbar
+                                    (selected-window)))
+       (spec emchat-toolbar-spec))
+    (or (ignore-errors (toolbar-find-button emchat-toolbar-icon))
+       (set-specifier default-toolbar
+                      (toolbar-add-item origbar spec 'right)
+                      'global))))
+
+;;; Code - footer:
+
+;; otherwise sending large contact list leads to significant delay
+(byte-compile 'emchat-pack-contact-list)
+
+;; Start the idle timer
+(emchat-auto-away-timeout-set nil emchat-auto-away-timeout)
+;; Install bindings
+(emchat-install-bindings 'emchat-prefix-key emchat-prefix-key)
+;; Add our button to the default toolbar
+(when (and (featurep 'toolbar)
+          (featurep 'png)
+          (device-on-window-system-p))
+  (emchat-add-to-toolbar))
+;; Pre-load the saved recent-adds
+(with-current-buffer (find-file-noselect emchat-recently-added-by-filename)
+  (while (re-search-forward "\\(\\w+\\)" nil t)
+    (add-to-list 'emchat-world-recently-added-by
+                (string-to-number (match-string 1))))
+  (kill-buffer nil))
+;; Finally, run the load hook
+(run-hooks 'emchat-load-hook)
+
+(provide 'emchat)
+
+;;; emchat.el ends here
+
diff --git a/emchat.texi b/emchat.texi
new file mode 100644 (file)
index 0000000..ac7ad08
--- /dev/null
@@ -0,0 +1,77 @@
+\input texinfo @c emchat.texi   -*-TeXinfo-*-
+@c Copyright (C) 2000 - 2007 Steve Youngs
+@c %**start of header
+@setfilename emchat.info
+@settitle An Instant Messaging Client for (S)XEmacs.
+@finalout
+@setchapternewpage odd
+@c %**end of header
+@set EDITION 1.2
+@set UPDATED Nov 13, 2007
+
+@include emchat-version.texi
+
+@dircategory Lisp
+@direntry
+* EMchat: (emchat).              An Instant Messaging Client for SXEmacs
+@end direntry
+
+@ifinfo
+This manual documents EMchat, an instant messaging client for SXEmacs.
+It corresponds to EMchat version @value{VERSION}.  
+
+The manual was last updated @value{UPDATED}.
+@end ifinfo
+
+@titlepage
+@title EMchat
+@subtitle Yet another instant messaging client
+@subtitle Edition @value{EDITION}, for EMchat Version @value{VERSION}
+@author by Steve Youngs
+
+@end titlepage
+Copyright @copyright{} 2000 - 2007  Steve Youngs.
+
+@contents
+
+@node Top, Overview, (dir), (dir)
+
+@ifinfo 
+This manual documents EMchat, an instant messaging client for SXEmacs.
+It corresponds to EMchat version @value{VERSION}.  
+
+The manual was last updated @value{UPDATED}.
+@end ifinfo
+
+This manual is far from finished.  Actually, it hasn't even been started
+yet.  At this stage you would be better off looking at the source .el
+files to answer your questions.  You are very welcome to direct any
+questions to either @email{emchat-users@@emchat.org, the EMchat Users
+mailing list} or to me at @email{steve@@emchat.org, Steve Youngs}.
+
+
+@menu
+* Overview::                    A brief introduction.
+* Concept Index::               Go here to find what you're after.
+@end menu
+
+
+@node Overview, Concept Index, Top, Top
+@chapter Overview
+@cindex overview
+EMchat is an instant messaging client, written in elisp.  It @emph{only}
+runs in SXEmacs or XEmacs.  So all of you die hard GNU/Emacs users, you'll just
+have to install that other breed of emacsen.  You never know, you
+might even like it.  Of course this is GPL software, so you are quite
+welcome to port it.
+
+Now you have one more reason to @emph{not} leave SXEmacs.
+
+@node Concept Index,  , Overview, Top
+@unnumbered Concept Index
+     
+@printindex cp
+     
+@contents
+
+@bye
diff --git a/images/auth-here.xpm b/images/auth-here.xpm
new file mode 100644 (file)
index 0000000..3d581c9
--- /dev/null
@@ -0,0 +1,204 @@
+/* XPM */
+static char *file[] = {
+"32 32 169 2",
+".. c #000000",
+".# c #000500",
+".a c #050505",
+".b c #00000b",
+".c c #0b000b",
+".d c #0b0b0b",
+".e c #000011",
+".f c #001100",
+".g c #001101",
+".h c #001111",
+".i c #110000",
+".j c #110011",
+".k c #1d0e1d",
+".l c #111111",
+".m c #171717",
+".n c #161c1c",
+".o c #111122",
+".p c #112211",
+".q c #112222",
+".r c #221100",
+".s c #221111",
+".t c #331111",
+".u c #331c11",
+".v c #221122",
+".w c #222211",
+".x c #332211",
+".y c #222222",
+".z c #2d2d2d",
+".A c #222233",
+".B c #2d2d33",
+".C c #223322",
+".D c #223333",
+".E c #332222",
+".F c #332233",
+".G c #332d33",
+".H c #333322",
+".I c #333333",
+".J c #333833",
+".K c #383338",
+".L c #393939",
+".M c #3e383e",
+".N c #333344",
+".O c #334433",
+".P c #334444",
+".Q c #3e4444",
+".R c #443311",
+".S c #552211",
+".T c #443e3e",
+".U c #552222",
+".V c #553322",
+".W c #5a3822",
+".X c #443344",
+".Y c #443e44",
+".Z c #4f442d",
+".0 c #444433",
+".1 c #444444",
+".2 c #454545",
+".3 c #444944",
+".4 c #444949",
+".5 c #494444",
+".6 c #494449",
+".7 c #4f4f44",
+".8 c #494949",
+".9 c #494f49",
+"#. c #4f4f49",
+"## c #444455",
+"#a c #445544",
+"#b c #4f5a4f",
+"#c c #445555",
+"#d c #554444",
+"#e c #554455",
+"#f c #555544",
+"#g c #555555",
+"#h c #556655",
+"#i c #556666",
+"#j c #5a6969",
+"#k c #664444",
+"#l c #665566",
+"#m c #666655",
+"#n c #66665a",
+"#o c #666671",
+"#p c #666677",
+"#q c #667166",
+"#r c #667766",
+"#s c #667777",
+"#t c #776666",
+"#u c #716671",
+"#v c #776677",
+"#w c #717166",
+"#x c #777766",
+"#y c #717171",
+"#z c #777777",
+"#A c #71717c",
+"#B c #717c71",
+"#C c #7c717c",
+"#D c #7c7c7c",
+"#E c #777788",
+"#F c #7c7c88",
+"#G c #778877",
+"#H c #778888",
+"#I c #884433",
+"#J c #885533",
+"#K c #995533",
+"#L c #887777",
+"#M c #aa5544",
+"#N c #887788",
+"#O c #aa8866",
+"#P c #cc8877",
+"#Q c #dd8866",
+"#R c #888888",
+"#S c #888893",
+"#T c #888899",
+"#U c #889388",
+"#V c #889988",
+"#W c #889999",
+"#X c #938893",
+"#Y c #998899",
+"#Z c #939388",
+"#0 c #999988",
+"#1 c #939393",
+"#2 c #939e93",
+"#3 c #939e9e",
+"#4 c #999999",
+"#5 c #9e9e9e",
+"#6 c #99aa99",
+"#7 c #aa9999",
+"#8 c #aa99aa",
+"#9 c #aaaaaa",
+"a. c #aaaabb",
+"a# c #aabbaa",
+"aa c #aabbbb",
+"ab c #bbaaaa",
+"ac c #bbaabb",
+"ad c #bbbbaa",
+"ae c #bbbbbb",
+"af c #bbccbb",
+"ag c #ddbb88",
+"ah c #c4b5b5",
+"ai c #ccbbbb",
+"aj c #eebb99",
+"ak c #ffbbaa",
+"al c #ccbbcc",
+"am c #ccccbb",
+"an c #eecc88",
+"ao c #ffcc99",
+"ap c #cccccc",
+"aq c #ccccdd",
+"ar c #ccddcc",
+"as c #ccdddd",
+"at c #ddcccc",
+"au c #ddccdd",
+"av c #ddddcc",
+"aw c #dddddd",
+"ax c #ddddee",
+"ay c #ddeedd",
+"az c #ddeeee",
+"aA c #eedddd",
+"aB c #eeddee",
+"aC c #eeeedd",
+"aD c #e2e2e2",
+"aE c #eeeeee",
+"aF c #eeeeff",
+"aG c #eeffee",
+"aH c #eeffff",
+"aI c #ffeeee",
+"aJ c #ffeeff",
+"aK c #ffffee",
+"aL c #ffffff",
+"aM c #b2c0dc",
+"#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g#g",
+"#g..............................................................",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaMaM#3#5#1#U#q#uaMaMaMaMaMaMaM#u#F.J",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMapaIawawavaual#6aMaMaMaMaMaM#8aw.7.Y",
+"#g..aMaMaMaMaMaMaMaM#6alaJaCayaAawawawauauar#9#8aMaMaeaJaJaL#b.5",
+"#g..aMaMaMaMaMaMaM#8aEaGazaEaxayawawawasasauaqaa#6#8aLaHaLaL#o.3",
+"#g.eaMaMaMaMalaEaGaFaFaEazaBaBayayawawawasauauawaLaLaLaLaH.N#C.3",
+"#g..aMaMabavaGaIaIaEaEaEaBaCayaBaAawawawauavaEaJaLaLaLaL#7.C#D.6",
+"#g.JaKaLaLaKaKaJaIaEaEaIaEaCaCaBaAawawawaLaKaLaLaLaLaKaL.v#m#R.6",
+"#g.BaLaLaHaJaJaGaGaJaFaEaEaEaEayayaxaBaHaLaLaLaLaLaLaLaL.O#p#S.3",
+"#g...IaHaLaLaJaGaGaFaEaGaGaEaEazaGaLaLaHaLaLaLaLaHaLaL#G#h#E#X.4",
+"#g..#i.saLaKaKaJaIaEaEaIaEaEawaBaLaLaKaLaLaKaLaLaBam#r.s#v#R#Z.6",
+"#g..aMaM.XaLaKaJaJaGaEaEaBaEaLaJalae#a.v.i.l.p.E.1.1#f#l#Yae#Z.6",
+"#g..aMaM#c.IaLaHaGaFaFawaGac.I.D.h.v.I.O#h#v#z#G#H#R#R#Va#au#1.4",
+"#g..aMaMaMaM#gaHaHaJ###VayaBaEayazaEaEazayaBaBayayaBaxayawaw#1.4",
+"#g..aMaMaMaM.p#vaJaGaE.FaJaGaGaIaEaEaEaEaBaEayaBaBayawawawaw#Z.T",
+"#g..aMaMaMaMaMaM#YaKaGaI#Y.0aGaIaIaEaEaIaEaCaCaBaBayayaAawaw.d.I",
+"#g..aM#6#6#L#Pajag#Qaoananaoaoananaoaoananaoaoananaoaoananao#O.Z",
+"#g..aMaMaMaM#k.V.R.s.j.f.f.j.j.f.w.s.s.w.w.s.s.w.w.s.s.f.f.j.c.#",
+"#g..aMaM.F.C.C.F.F.C.2#Y#Y#V#0#Y#tadadacacadadacacad#9.j#Y#V#n.G",
+"#g..aMaMaMaMaMaMaMaMaM#RauaEaEaIaEa#awaEaEaEaEaBaB#maeauatap#y.m",
+"#g..aMaMaMaMaMaMaMaMaMaM.fauaFaGaEaE.IaraGaEaEaE...oawararaq.b.n",
+"#g..aMaMaMaMaMaMaMaMaMaMaM#zaBaEaEaEaEay#WaFap.hawawawas.f.gaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaM.paAaEaEaEaB#v#r..#Nawawaw#g#eaMaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaM#eaAaEaEaBaBayawaAaA#R.yaMaMaMaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaMaM.CaEaEaEazaBaBay.y.gaMaMaMaMaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaMaMaM.laEaEazaE#g..aMaMaMaMaMaMaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM.1aIaEam..#laMaMaMaMaMaMaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM.j..#faMaMaMaMaMaMaMaMaMaM",
+"#g..aMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaMaM#6#c#8aMaMaMaMaMaMaMaMaMaM"};
diff --git a/images/emchat-icon.png b/images/emchat-icon.png
new file mode 100644 (file)
index 0000000..c59da86
Binary files /dev/null and b/images/emchat-icon.png differ
diff --git a/images/exit.xpm b/images/exit.xpm
new file mode 100644 (file)
index 0000000..f39f889
--- /dev/null
@@ -0,0 +1,51 @@
+/* XPM */
+static char *file[] = {
+"32 32 16 1",
+". c #ffffff",
+"# c #b6aeb6",
+"a c #beb6be",
+"b c #a6a2a6",
+"c c #000000",
+"d c #aeaeae",
+"e c #a6a6a6",
+"f c #aeaeb6",
+"g c #969696",
+"h c #000808",
+"i c #a69ea6",
+"j c #8e8a8e",
+"k c #fffbff",
+"l c #080408",
+"m c #9e9a9e",
+"n c #a6798e",
+"................................",
+".#a#ba###b#b##a###b#b##a#b#b####",
+".bdadaaaad#aaaaaaad#aaaaaaad#aaa",
+".baeadaafaaaefdaaeabaafdaaeabaaa",
+".adddadddadddaadd#daadaadaaadad#",
+".#addaaddaddadddfa#d#faaaddaadfb",
+".bebbbebaebaba#ababbaebdeaadba#a",
+".bbbbbeb#bebadd#babbaeeba#a#bafa",
+".#aaafaaeaa#abdafeddbdf#abbaabab",
+".gbbbbeeaebee##ab#bbchhbe#aabaaf",
+".beccccccc.edb##babbcccbbbccbafa",
+".bbccccccc.#dbebbbab...##cccebbb",
+".bbccc.bbbbhhcbbchbbchh#cccccheb",
+".gbhcc.b#bbccc.ccc.bcccbhccccc##",
+".bbcccccchbbccccc.bbcccbbccc..#b",
+".bbcccccccbbcccc..bbcccbbcccbbbb",
+".bbccc....bbbcccbbbbcccbbcccbbbb",
+".ggccc.gbbgbbcccgbbgcccbbcccgbbb",
+".bbccc.bbbbbcccc.bbbcccbbcccbbbb",
+".bbccccccccbccccccbbcccbbcccccbb",
+".ggcccccccccccbcccggcccbbbccccbb",
+".ggg..........bb...g...gbbi...bi",
+".bbbbbbbgbbbbggbbgbbgbbbbggbbgbg",
+".bibbbbbgbbbbgjgbgbigibibjggbggg",
+".ggggjggbggjggibgiggigggggbigiib",
+".ggiggijgigbijgjjgijgigiigggjggg",
+".gjgggjgggiigggggjggggiiggggggjg",
+".gggiggiiggggiijgggiijgggiiggiii",
+".gjgjgjjigggggigjigggigigggggjij",
+"kggggggggggggjgjggggggjgggggjmgg",
+".jgmmggggggggngggmmmggngggnggggg",
+".ggjngggngngjgggnggjjggngggngjjj"};
diff --git a/images/help.xpm b/images/help.xpm
new file mode 100644 (file)
index 0000000..aac8845
--- /dev/null
@@ -0,0 +1,33 @@
+/* XPM */
+static char *file[] = {
+"28 28 2 1",
+". c #b2b2b2 s backgroundToolBarColor",
+"# c #000000",
+"............................",
+"............................",
+"............................",
+"............................",
+"........##########..........",
+".......##.#.#.#.#.#.........",
+"......##.#.#.#.#.#.#........",
+".....##.#.#######.#.#.......",
+".....#.#.#########.#.#......",
+".....##.###########.#.......",
+".....#.#.###.#.###.#.#......",
+".....##.#####.#####.#.#.....",
+".....#.#.###.#.###.#.#.#....",
+".....##.#.#.#.#####.#.#.#...",
+".....#.#.#.#.#####.#.####...",
+".....##.#.#.#####.#.#.......",
+"......##.#.#####.#.#.#......",
+".......##.#.###.#.#.#.......",
+"........##.#####.#.#........",
+".........##.#.#.#.#.#.......",
+".........#.#.#.#.#.#........",
+".........##.###.#...........",
+".........#.#####.#..........",
+".........##.###.#...........",
+"........##.#.#.#.#..........",
+"........#.#.#.#.#.#.........",
+"............................",
+"............................"};
diff --git a/images/info-around.xpm b/images/info-around.xpm
new file mode 100644 (file)
index 0000000..f272b40
--- /dev/null
@@ -0,0 +1,114 @@
+/* XPM */
+static char *file[] = {
+"32 32 79 2",
+".. c #000000",
+".# c #b2c0dc",
+".a c #101000",
+".b c #101800",
+".c c #101f10",
+".d c #101f1f",
+".e c #10381f",
+".f c #1f1f20",
+".g c #201810",
+".h c #202000",
+".i c #202810",
+".j c #204740",
+".k c #206020",
+".l c #20682f",
+".m c #2f2f30",
+".n c #2f3000",
+".o c #2f7f30",
+".p c #2f902f",
+".q c #2fa82f",
+".r c #30302f",
+".s c #30383f",
+".t c #3f204f",
+".u c #3f3000",
+".v c #3f303f",
+".w c #3f3050",
+".x c #3f371f",
+".y c #3f4000",
+".z c #402000",
+".A c #40c84f",
+".B c #4f4f00",
+".C c #4f574f",
+".D c #4f7f9f",
+".E c #50804f",
+".F c #509f60",
+".G c #5f2810",
+".H c #5f500f",
+".I c #5f5030",
+".J c #5f5f60",
+".K c #5faf5f",
+".L c #60474f",
+".M c #70404f",
+".N c #707780",
+".O c #7f402f",
+".P c #7f706f",
+".Q c #7f808f",
+".R c #7fa79f",
+".S c #803f30",
+".T c #808890",
+".U c #8f370f",
+".V c #8f909f",
+".W c #8fa8b0",
+".X c #8fbfcf",
+".Y c #90786f",
+".Z c #908780",
+".0 c #90ff90",
+".1 c #9f7f6f",
+".2 c #9fafa0",
+".3 c #a05f5f",
+".4 c #a06f5f",
+".5 c #a0907f",
+".6 c #a09890",
+".7 c #a0a7c0",
+".8 c #af2000",
+".9 c #b03830",
+"#. c #b07850",
+"## c #b0b7cf",
+"#a c #c0a84f",
+"#b c #c0df9f",
+"#c c #cfa77f",
+"#d c #dfafa0",
+"#e c #e0903f",
+"#f c #e0a810",
+"#g c #e0efe0",
+"#h c #e0f0cf",
+"#i c #e0f7e0",
+"#j c #efb89f",
+"#k c #efeff0",
+"#l c #efffdf",
+"#m c #ffffff",
+".#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#",
+".#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#",
+".#.#.#.#.#.#.##m.C#m#m#m.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#",
+".#.#.#.#.#.##m.i.6#m#m...#.#.#.#.#.#.#.#.#.#.#.#.#.##l#d#m#m...#",
+".#.#.#.#.##m.C.6#m#m.....#.#.#.#.##l.x#m#m.C.#.#.#.##m#m..#m.2..",
+".#.#.#.#.##m#m#m#m.7.....#.#.#.#.##i#m#m#m.C.#.#.#.##m#m...2#m..",
+".#.#.#.#.##m.7##.X.7.....#..#m#m#l.G#m#m.2...#.#.#.##m#m#c#d.C.I",
+".#.#.#.#.##..B.z.z.B.......C#m.6#i#l#l#i.z...#.#.#.##m#m.M.c.b..",
+".#.#...V#m.5.B.G.z.u......#m.R.r#i#c.H#a.G...#.#.#.##c#k.M.b.c..",
+".##g.C#m#m.1.f.d.B.m.....k.R.R.e#c.z.O.z.....#..#m#m..#m#c#d.C.I",
+"#l#g#i#l.k#m.7##.X.7.....m.w.j..#i#c#e#f.x...v..#m#m...C#j#d.L.C",
+"#h.A.E.p...5.B.z.z.B.....s.R.R.r#c.z.z.O.....y..#m#m.y..#d#c.I.M",
+"#b.E.e....#m.q.7.W.V.....s.R.R.r#i#e.B#c.z...y.y.y.y.y..#d#c.I.M",
+"#l.R.p.E..#m.7##.X.T.....m.w.j..#i#e.n#c.x...v.y.j.v.y..#j#d.L.C",
+".0.p.e.e..#m.a##.X.V.....k.R.R.e#l#e#c#c.x...y.y.y.y.v..#c#d.C.I",
+"#b.E.e....#m.s.7.W.V.....s.R.R.r#i#e.B#c.z...y.Q.Q.Z.y..#d#c.I.M",
+"#b.E......#m.w.7.W.V.....s.R.R.r#i#c.B#c.G...y.Q.Q.Z.y..#d#c.I.M",
+"#l.R.p.E..#m.7##.X.V.....k.R.R.e#l#c.n#c.x...y.y.y.y.v..#c#d.C.I",
+"#l.R.p.E..#m.a##.X.T.....k.R.R.e#i#c#c#f.x...v.y.j.v.y..#j#d.L.C",
+"#h.A.E.p..#m.7.7.W.V.....s.R.R.r#i#c.h#a.G...y.y.y.c.y..#d#c.I.M",
+"#g.K.p.p..#m.s.7.W.V.....s.R.R.r#i#c.h#e.z...y.y.y.y.y..#d#c.I.M",
+"#l.R.p.E..#m.7##.X.T.....k.R.R.e#i#c#c#f.x...v.c.c.v.y..#j#d.L.C",
+"#l.R.p.E..#m.7##.X.V.....k.R.R.e#l#c.O#f.x...y.y.y.y.v..#c#d.C.I",
+"#b.E......#m##.7.W.V.....s.R.R.r#i#e#c#e.z...y.3.Y.D.y..#d#c.I.M",
+"#b.E......#m.7.7.W.7.....s.R.R.r#i#e.y.y.G...y.Y.3.4.y..#d#c.I.M",
+"#l.R.p.E...7.B.u.B.w.....k.R.R.e#l#e#c.y.x...y.P.D.D.v...I.c....",
+"#l.R.p.E...7.w.s.u.w.......w.j..#i#c#c.j.x...v.y.j.v.y...C.c....",
+"#h.A.E.p..#m.7.7.W.7.....s.R.R.r#i#c.H.y.G...y.Y.3.D.y..#d#c.I.M",
+".#.#.#.#.##m.q.7.W##...#........#c#c#e#e.z...y.y.y.y.y..........",
+".#.#.#.#.##m.W.X.X.7...#.#.#.#.#.#.....................#.#.#.#.#",
+".#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#",
+".#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#.#"};
diff --git a/images/info-here.xpm b/images/info-here.xpm
new file mode 100644 (file)
index 0000000..286e664
--- /dev/null
@@ -0,0 +1,82 @@
+/* XPM */
+static char *file[] = {
+"32 32 47 1",
+". c #101028",
+"# c #101828",
+"a c #181828",
+"b c #101830",
+"c c #181830",
+"d c #182038",
+"e c #182041",
+"f c #202049",
+"g c #202849",
+"h c #202859",
+"i c #283449",
+"j c #383c59",
+"k c #283061",
+"l c #303871",
+"m c #304179",
+"n c #414961",
+"o c #494d61",
+"p c #515569",
+"q c #595d79",
+"r c #697579",
+"s c #384586",
+"t c #38418e",
+"u c #38498e",
+"v c #41498e",
+"w c #41518e",
+"x c #49598e",
+"y c #415196",
+"z c #495196",
+"A c #495996",
+"B c #515d96",
+"C c #59619e",
+"D c #697196",
+"E c #797da6",
+"F c #868696",
+"G c #868aae",
+"H c #9692a6",
+"I c #c7c3c7",
+"J c #c7cbcf",
+"K c #cfcbdf",
+"L c #d7d3d7",
+"M c #d7d7df",
+"N c #dfdbdf",
+"O c #e7e3e7",
+"P c #efebef",
+"Q c #f7f3f7",
+"R c #fffbff",
+"S c #b2c0dc",
+"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS",
+"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS",
+"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS",
+"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS",
+"SSSSSSSSSSSSc.cehhffooSSSSSSSSSS",
+"SSSSSSSSSSbbhlttuuuusspSSSSSSSSS",
+"SSSSSSSSi.hmttBMNNuuvvssSSSSSSSS",
+"SSSSSSSebkttttMOIImmvvvvqqSSSSSS",
+"SSSSSSibltttttPIIIddvvvvwwSSSSSS",
+"SSSSSp.ktttttuKIJJ##vvvvwwSSSSSS",
+"SSSSScftttttuuCHFFddvvwwwwDDSSSS",
+"SSSSp.lttttuuuum##mmvvwwwwzzSSSS",
+"SSSSifttttuCPPPPQQvvwwwwyyzzSSSS",
+"SSSSbktttuuCs.JJLL##wwwwzzzzSSSS",
+"SSSS.mttuuuusvPLLL##wwyyzzzzSSSS",
+"SSSSbttuuuuuvvQLNN##wwzzzzzzSSSS",
+"SSSSetuuuuuvvvQLNN##yyzzzzzzSSSS",
+"SSSSeuuuuuvvvvQNNN##zzzzzzzzSSSS",
+"SSSScuuuuvvvvvQNOO##zzzzzzAASSSS",
+"SSSSeuuuvvvvvvQNOO##zzzzzzAASSSS",
+"SSSSpmuvvvvvvwQOOO##zzzzAAAASSSS",
+"SSSSSgvvvvvvwwQOOO##zzzzAAAASSSS",
+"SSSSSovvvvvwwwQOPP##zzAAAASSSSSS",
+"SSSSSSlvvvwwwwQPPP##zzAAAASSSSSS",
+"SSSSSSFxvwwwQQQPQQQQAAAACCSSSSSS",
+"SSSSSSSDxwwwy#####aaaaAASSSSSSSS",
+"SSSSSSSSSSwyzzzzzzAAAADDSSSSSSSS",
+"SSSSSSSSSSSBzzzzzzAACCSSSSSSSSSS",
+"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS",
+"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS",
+"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS",
+"SSSSSSSSSSSSSSSSSSSSSSSSSSSSSSSS"};
diff --git a/images/log-header.xbm b/images/log-header.xbm
new file mode 100644 (file)
index 0000000..a2b003e
--- /dev/null
@@ -0,0 +1,493 @@
+#define brilliant_width 390
+#define brilliant_height 120
+static unsigned char brilliant_bits[] = {
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xcf,
+   0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f,
+   0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9,
+   0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf,
+   0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xe0, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f,
+   0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe,
+   0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3,
+   0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f,
+   0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x02,
+   0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x70, 0x1c, 0x00, 0x07,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x7f, 0xc7, 0x01,
+   0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x04, 0x00, 0x00, 0x00,
+   0x81, 0x0b, 0x82, 0x73, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f,
+   0xe3, 0x00, 0x70, 0x71, 0x80, 0x00, 0x00, 0x00, 0x01, 0x20, 0x08, 0x00,
+   0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x42, 0xc6,
+   0x00, 0x08, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x92, 0x04, 0x00, 0x00,
+   0x00, 0x41, 0x0c, 0x02, 0x21, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x04, 0x63, 0x00, 0x88, 0x41, 0x00, 0x00, 0x00, 0x00, 0x01, 0x20, 0x09,
+   0x07, 0x04, 0x5c, 0x3c, 0xb6, 0xe1, 0x00, 0xe0, 0x83, 0x07, 0x00, 0x42,
+   0xea, 0x70, 0xe9, 0xe0, 0xe1, 0x03, 0x00, 0x00, 0x00, 0x92, 0x74, 0xe0,
+   0x00, 0x80, 0x40, 0x08, 0x04, 0x12, 0x84, 0xb6, 0xf1, 0xc0, 0xc5, 0x07,
+   0x00, 0x04, 0x75, 0x00, 0x04, 0x41, 0xe0, 0x80, 0x63, 0x87, 0x0f, 0x20,
+   0x89, 0x08, 0x04, 0x62, 0x42, 0x6c, 0x11, 0x01, 0x40, 0x40, 0x08, 0x00,
+   0x12, 0xaa, 0x88, 0x19, 0x11, 0x42, 0x00, 0x00, 0x00, 0x00, 0x10, 0x8c,
+   0x10, 0x01, 0x80, 0x40, 0x00, 0x04, 0x12, 0x24, 0x6c, 0x09, 0x21, 0x26,
+   0x04, 0x00, 0x04, 0x55, 0x00, 0x04, 0x40, 0x80, 0x40, 0xc4, 0x08, 0x01,
+   0xa0, 0x4a, 0x10, 0x04, 0x41, 0x81, 0x24, 0x09, 0x02, 0x40, 0x20, 0x10,
+   0x00, 0x1e, 0x92, 0x04, 0x09, 0x01, 0x42, 0x00, 0x80, 0x1f, 0x00, 0x10,
+   0x84, 0x08, 0x02, 0x80, 0x80, 0x07, 0x04, 0x0c, 0x3c, 0x24, 0x01, 0x11,
+   0x24, 0x00, 0x00, 0x04, 0x49, 0x00, 0x04, 0x40, 0x80, 0x20, 0x48, 0x08,
+   0x01, 0xa0, 0xca, 0x1f, 0x04, 0x01, 0x81, 0x24, 0xf9, 0x03, 0x40, 0x20,
+   0x10, 0x00, 0x12, 0x92, 0x04, 0x08, 0xe1, 0x43, 0x00, 0x00, 0x00, 0x00,
+   0x10, 0x84, 0xf8, 0x03, 0x80, 0x00, 0x08, 0x04, 0x12, 0x24, 0x24, 0xf1,
+   0x11, 0xc0, 0x03, 0x00, 0x04, 0x49, 0x00, 0x04, 0x40, 0x80, 0xe0, 0x4f,
+   0x08, 0x01, 0x40, 0x44, 0x00, 0x04, 0x01, 0x81, 0x24, 0x09, 0x00, 0x40,
+   0x20, 0x10, 0x00, 0x42, 0x82, 0x04, 0x08, 0x11, 0x42, 0x00, 0x00, 0x00,
+   0x00, 0x10, 0x84, 0x08, 0x00, 0x80, 0x40, 0x08, 0x04, 0x12, 0x84, 0x24,
+   0x09, 0x11, 0x00, 0x04, 0x00, 0x04, 0x41, 0x00, 0x04, 0x40, 0x80, 0x20,
+   0x40, 0x08, 0x01, 0x40, 0x84, 0x10, 0x04, 0x42, 0x42, 0x24, 0x11, 0x02,
+   0x40, 0x44, 0x08, 0x00, 0x42, 0x82, 0x08, 0x09, 0x11, 0x43, 0x04, 0x00,
+   0x00, 0x00, 0x10, 0x84, 0x10, 0x02, 0x80, 0xc0, 0x08, 0x04, 0x21, 0x84,
+   0x24, 0x89, 0x21, 0x24, 0x04, 0x00, 0x04, 0x41, 0x00, 0x08, 0x41, 0x80,
+   0x40, 0x48, 0x08, 0x11, 0x40, 0x04, 0x0f, 0x1f, 0x3c, 0x3c, 0x6e, 0xe3,
+   0x01, 0x80, 0x83, 0x07, 0x00, 0x7f, 0xc7, 0xf1, 0x9c, 0xe3, 0x86, 0x03,
+   0x00, 0x00, 0x00, 0x7c, 0xce, 0xe1, 0x01, 0x00, 0x41, 0x07, 0x82, 0x73,
+   0xfe, 0x6e, 0x73, 0xc3, 0xe3, 0x03, 0x00, 0x9f, 0xe3, 0x00, 0xf0, 0xf0,
+   0xe1, 0x83, 0xe7, 0x1c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00,
+   0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x06, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x03, 0x00,
+   0x00, 0x00, 0xc0, 0x07, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x00,
+   0xc1, 0x00, 0x00, 0x00, 0x04, 0x04, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x02,
+   0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+   0x00, 0x80, 0x00, 0x00, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x02, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x0f, 0x80, 0x73, 0x3c, 0xc6, 0x00,
+   0x80, 0xc0, 0x81, 0x1c, 0x0e, 0x00, 0x3e, 0x74, 0x70, 0xe0, 0x03, 0x80,
+   0x0f, 0x0f, 0x3f, 0x3e, 0x8e, 0xf3, 0x30, 0x83, 0x03, 0x00, 0x80, 0x1d,
+   0x10, 0x70, 0xf0, 0xe0, 0x83, 0x03, 0x00, 0x2e, 0x1e, 0x3b, 0xf8, 0x70,
+   0xe0, 0x82, 0xc3, 0x0c, 0x00, 0x00, 0x01, 0x01, 0x00, 0x21, 0x42, 0x84,
+   0x00, 0x80, 0x00, 0x81, 0x04, 0x11, 0x00, 0x04, 0x8c, 0x40, 0x10, 0x02,
+   0x40, 0x88, 0x10, 0x04, 0x04, 0x04, 0x09, 0xa1, 0x44, 0x04, 0x00, 0x00,
+   0x23, 0x10, 0x88, 0x08, 0x11, 0x42, 0x04, 0x00, 0x31, 0x21, 0x46, 0x84,
+   0x40, 0x10, 0x43, 0x84, 0x12, 0x00, 0x00, 0x01, 0x01, 0x00, 0x21, 0x81,
+   0x84, 0x00, 0x80, 0x00, 0x81, 0x82, 0x20, 0x00, 0x04, 0x84, 0x40, 0x10,
+   0x00, 0x40, 0x40, 0x20, 0x04, 0x04, 0x24, 0x01, 0x61, 0x20, 0x08, 0x00,
+   0x00, 0x41, 0x10, 0x04, 0x01, 0x11, 0x20, 0x08, 0x80, 0xa0, 0x40, 0x42,
+   0x04, 0x40, 0x08, 0x22, 0x88, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0x12,
+   0x81, 0x84, 0x00, 0x80, 0x00, 0x81, 0x81, 0x3f, 0x00, 0x04, 0x84, 0x40,
+   0xe0, 0x01, 0x80, 0x47, 0x20, 0x04, 0x04, 0x24, 0xf1, 0x21, 0xe0, 0x0f,
+   0x00, 0x00, 0x41, 0x10, 0xfc, 0xf1, 0xe1, 0xe1, 0x0f, 0x80, 0x80, 0x40,
+   0x42, 0x78, 0x40, 0x08, 0xe2, 0x8f, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00,
+   0x12, 0x81, 0x84, 0x00, 0x80, 0x00, 0x81, 0x82, 0x00, 0x00, 0x04, 0x84,
+   0x40, 0x00, 0x02, 0x00, 0x48, 0x20, 0x04, 0x04, 0xa8, 0x08, 0x21, 0x20,
+   0x00, 0x00, 0x00, 0x41, 0x10, 0x04, 0x08, 0x01, 0x22, 0x00, 0x80, 0x80,
+   0x40, 0x42, 0x80, 0x40, 0x08, 0x22, 0x80, 0x00, 0x00, 0x00, 0x01, 0x01,
+   0x00, 0x0c, 0x42, 0xc4, 0x00, 0x80, 0x00, 0x81, 0x04, 0x21, 0x00, 0x44,
+   0x84, 0x40, 0x10, 0x02, 0x40, 0x88, 0x10, 0x04, 0x44, 0xd8, 0x88, 0x21,
+   0x40, 0x08, 0x03, 0x00, 0x23, 0x10, 0x08, 0x89, 0x11, 0x42, 0x08, 0x00,
+   0x21, 0x21, 0x42, 0x84, 0x40, 0x10, 0x43, 0x88, 0x00, 0x00, 0xc0, 0xc7,
+   0x07, 0x00, 0x08, 0x3c, 0xb8, 0x01, 0xe0, 0xc3, 0xc7, 0x1c, 0x1e, 0x00,
+   0x38, 0xce, 0xf1, 0xf1, 0x01, 0xc0, 0x07, 0x0f, 0x1f, 0x38, 0xd8, 0x70,
+   0xf3, 0x80, 0x07, 0x03, 0x00, 0x1d, 0x7c, 0xf0, 0x70, 0xf3, 0x81, 0x07,
+   0x00, 0x1e, 0x1e, 0xe7, 0x7c, 0xf0, 0xe1, 0x86, 0xc7, 0x03, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x80, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x07, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+   0x00, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0xc1, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x40, 0x00, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00, 0x04,
+   0x00, 0x00, 0x00, 0xfc, 0xf0, 0xe7, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x31, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x40, 0x00, 0x00, 0x02, 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x08, 0x21, 0x24, 0x09, 0x01, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x3a, 0x00, 0xee, 0x00, 0xe0,
+   0xd8, 0x86, 0x4b, 0x07, 0x0f, 0x1f, 0x00, 0xb8, 0xf0, 0xd8, 0xc1, 0xc3,
+   0x07, 0x07, 0x1e, 0x3b, 0x00, 0x08, 0x21, 0x24, 0x09, 0x01, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x2a, 0x00, 0x44, 0x00,
+   0x10, 0xb1, 0x45, 0xcc, 0x88, 0x10, 0x02, 0x00, 0xc4, 0x08, 0x31, 0x22,
+   0x84, 0x00, 0x04, 0x21, 0x46, 0x00, 0x08, 0x21, 0x01, 0x01, 0x01, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x24, 0x3f, 0x28,
+   0x00, 0x08, 0x92, 0x24, 0x48, 0x08, 0x10, 0x02, 0x7e, 0x82, 0x04, 0x12,
+   0x02, 0x84, 0x00, 0x84, 0x40, 0x42, 0x00, 0x88, 0xe0, 0x01, 0x01, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x24, 0x00,
+   0x10, 0x00, 0xf8, 0x93, 0x24, 0x40, 0x08, 0x1f, 0x02, 0x00, 0x82, 0x04,
+   0x12, 0xc2, 0x87, 0x00, 0x84, 0x40, 0x42, 0x00, 0x78, 0x20, 0x01, 0x01,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x20,
+   0x00, 0x28, 0x00, 0x08, 0x90, 0x24, 0x40, 0x88, 0x10, 0x02, 0x00, 0x82,
+   0x04, 0x12, 0x22, 0x84, 0x00, 0x84, 0x40, 0x42, 0x00, 0x88, 0x20, 0x04,
+   0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+   0x20, 0x00, 0x44, 0x00, 0x10, 0x92, 0x44, 0x48, 0x88, 0x18, 0x22, 0x00,
+   0xc4, 0x08, 0x11, 0x22, 0x86, 0x08, 0x04, 0x21, 0x42, 0x00, 0x08, 0x21,
+   0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0xc0, 0x71, 0x00, 0xee, 0x00, 0xe0, 0xb9, 0x8d, 0xe7, 0x1c, 0x37, 0x1c,
+   0x00, 0xb8, 0xf1, 0x38, 0xc7, 0x0d, 0x07, 0x1f, 0x1e, 0xe7, 0x00, 0x1c,
+   0xf2, 0xc7, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,
+   0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f,
+   0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc,
+   0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7,
+   0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0xe0, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf,
+   0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f,
+   0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9,
+   0xf3, 0xe7, 0xcf, 0x9f, 0x3f, 0x7f, 0xfe, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf,
+   0x9f, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
diff --git a/images/login.xpm b/images/login.xpm
new file mode 100644 (file)
index 0000000..22af370
--- /dev/null
@@ -0,0 +1,41 @@
+/* XPM */
+static char *file[] = {
+"32 32 6 1",
+". c #808080",
+"# c #000000",
+"a c #808080",
+"b c #5050ff",
+"c c #ffffff",
+"d c #d0d0d0",
+"................................",
+"................................",
+"..........aaaaaaaaaaaaaaaaaa....",
+"..........aaaaaaaaaaaaaaaaaa....",
+"........aaddddddddddddddddaa##..",
+"........aaddddddddddddddddaa##..",
+"......aaccccccccccccccccaaaa##..",
+"......aaccccccccccccccccaaaa##..",
+"......aacc############ccaaaa##..",
+"......aacc############ccaaaa##..",
+"......aacc##bbbbbbbbbbccaaaa##..",
+"......aacc##bbbbbbbbbbccaaaa##..",
+"......aacc##bbbbbbbbbbccaaaa##..",
+"......aacc##bbbbbbbbbbccaaaa##..",
+"......aacc##bbbbbbbbbbccaaaa##..",
+"......aacc##bbbbbbbbbbccaaaa##..",
+"......aaccccccccccccccccaa##aaaa",
+"......aaccccccccccccccccaa##aaaa",
+"......aa##################aadd##",
+"......aa##################aadd##",
+"....aaccccccccccccccccccaaddaa##",
+"....aaccccccccccccccccccaaddaa##",
+"....aaaa##aa##aa##aa##aa##aaaa##",
+"....aaaa##aa##aa##aa##aa##aaaa##",
+"..aadd##dd##dd##dd##dd##dd####..",
+"..aadd##dd##dd##dd##dd##dd####..",
+"aaccccccccccccccccccccccdd##....",
+"aaccccccccccccccccccccccdd##....",
+"##########################......",
+"##########################......",
+"................................",
+"................................"};
diff --git a/images/logo.png b/images/logo.png
new file mode 100644 (file)
index 0000000..32a99ad
Binary files /dev/null and b/images/logo.png differ
diff --git a/images/logout.xpm b/images/logout.xpm
new file mode 100644 (file)
index 0000000..76ef4c8
--- /dev/null
@@ -0,0 +1,269 @@
+/* XPM */
+static char *logout[] = {
+"32 32 234 2",
+".. c #c7cbc7",
+".# c #bebebe",
+".a c #bebabe",
+".b c #b6babe",
+".c c #bec3c7",
+".d c #bebeb6",
+".e c #b6b6b6",
+".f c #c7c7c7",
+".g c #a6aeae",
+".h c #eff3f7",
+".i c #e7ebef",
+".j c #cfd3d7",
+".k c #cfcfcf",
+".l c #d7d7d7",
+".m c #d7dbd7",
+".n c #dfdfd7",
+".o c #dfe3e7",
+".p c #d7d7cf",
+".q c #717979",
+".r c #515151",
+".s c #a6aaae",
+".t c #a6aaa6",
+".u c #9ea6a6",
+".v c #9ea2a6",
+".w c #9e9ea6",
+".x c #9e9e9e",
+".y c #969a9e",
+".z c #969696",
+".A c #8e9296",
+".B c #8e8e8e",
+".C c #868686",
+".D c #798286",
+".E c #868a86",
+".F c #969a96",
+".G c #515959",
+".H c #494d49",
+".I c #8e928e",
+".J c #9ea29e",
+".K c #414141",
+".L c #494949",
+".M c #383c38",
+".N c #414541",
+".O c #868a8e",
+".P c #8e8e9e",
+".Q c #86869e",
+".R c #797d79",
+".S c #8e8686",
+".T c #aeb2ae",
+".U c #aeb6b6",
+".V c #797d8e",
+".W c #717571",
+".X c #867d79",
+".Y c #697571",
+".Z c #697171",
+".0 c #b6b2be",
+".1 c #efebdf",
+".2 c #e7e7df",
+".3 c #e7e3d7",
+".4 c #dfdbd7",
+".5 c #dfdbcf",
+".6 c #d7d3be",
+".7 c #d7cfc7",
+".8 c #cfcfc7",
+".9 c #cfcbbe",
+"#. c #cfc7be",
+"## c #c7c7be",
+"#a c #c7c3b6",
+"#b c #c7beb6",
+"#c c #bebab6",
+"#d c #beb6ae",
+"#e c #b6aea6",
+"#f c #968e8e",
+"#g c #797979",
+"#h c #383838",
+"#i c #dfd7cf",
+"#j c #beb2ae",
+"#k c #aea6a6",
+"#l c #a69e96",
+"#m c #616161",
+"#n c #867979",
+"#o c #797571",
+"#p c #696979",
+"#q c #696d71",
+"#r c #616561",
+"#s c #595969",
+"#t c #595551",
+"#u c #515571",
+"#v c #494969",
+"#w c #414559",
+"#x c #494551",
+"#y c #968a8e",
+"#z c #b6b2ae",
+"#A c #8e8a86",
+"#B c #9e9a96",
+"#C c #717586",
+"#D c #616579",
+"#E c #515171",
+"#F c #494d79",
+"#G c #494971",
+"#H c #96928e",
+"#I c #303430",
+"#J c #514d49",
+"#K c #9e9eb6",
+"#L c #717196",
+"#M c #71718e",
+"#N c #515586",
+"#O c #494996",
+"#P c #494986",
+"#Q c #49458e",
+"#R c #414161",
+"#S c #202420",
+"#T c #494541",
+"#U c #797996",
+"#V c #aeaab6",
+"#W c #71759e",
+"#X c #595996",
+"#Y c #515596",
+"#Z c #383c9e",
+"#0 c #414596",
+"#1 c #595986",
+"#2 c #696561",
+"#3 c #383c51",
+"#4 c #202020",
+"#5 c #595d59",
+"#6 c #696d8e",
+"#7 c #61618e",
+"#8 c #69699e",
+"#9 c #41459e",
+"a. c #616596",
+"a# c #4949a6",
+"aa c #5959a6",
+"ab c #696db6",
+"ac c #494da6",
+"ad c #4949b6",
+"ae c #383886",
+"af c #a6a2b6",
+"ag c #303449",
+"ah c #303038",
+"ai c #201c18",
+"aj c #515551",
+"ak c #616961",
+"al c #4145b6",
+"am c #5151b6",
+"an c #7175ae",
+"ao c #8e8eb6",
+"ap c #6165ae",
+"aq c #595d8e",
+"ar c #383c69",
+"as c #303051",
+"at c #303030",
+"au c #181818",
+"av c #282c28",
+"aw c #8682ae",
+"ax c #dfdbbe",
+"ay c #303471",
+"az c #181410",
+"aA c #282828",
+"aB c #596159",
+"aC c #495149",
+"aD c #e7dfd7",
+"aE c #8e8ea6",
+"aF c #383479",
+"aG c #282c61",
+"aH c #282c41",
+"aI c #282851",
+"aJ c #aeb2b6",
+"aK c #5155ae",
+"aL c #282c8e",
+"aM c #202449",
+"aN c #383c49",
+"aO c #d7d7be",
+"aP c #e7e3be",
+"aQ c #9692ae",
+"aR c #282871",
+"aS c #aeaea6",
+"aT c #696d69",
+"aU c #595da6",
+"aV c #202486",
+"aW c #282c79",
+"aX c #202049",
+"aY c #868279",
+"aZ c #616969",
+"a0 c #7979b6",
+"a1 c #282896",
+"a2 c #30308e",
+"a3 c #30348e",
+"a4 c #201c8e",
+"a5 c #797971",
+"a6 c #595979",
+"a7 c #7171a6",
+"a8 c #101441",
+"a9 c #61619e",
+"b. c #303496",
+"b# c #181861",
+"ba c #181451",
+"bb c #101038",
+"bc c #797171",
+"bd c #515561",
+"be c #383879",
+"bf c #303069",
+"bg c #202079",
+"bh c #181c69",
+"bi c #100c28",
+"bj c #717169",
+"bk c #101010",
+"bl c #494d96",
+"bm c #494d69",
+"bn c #181c49",
+"bo c #a6a29e",
+"bp c #696961",
+"bq c #ae7969",
+"br c #a68a86",
+"bs c #a66d69",
+"bt c #9e7d69",
+"bu c #9e7969",
+"bv c #8e9659",
+"bw c #96ba20",
+"bx c #8e9a38",
+"by c #716d69",
+"bz c #716969",
+"bA c #516961",
+"bB c #8e8661",
+"bC c #9e968e",
+"bD c #867971",
+"bE c #595951",
+"bF c #415151",
+"bG c #080808",
+"bH c #080400",
+"bI c #100c08",
+"bJ c #696159",
+"bK c #696969",
+"bL c #968e86",
+"bM c #dfdfdf",
+"bN c #515951",
+".....#.#.#.#.a.b.#.#.#.c.#.#.#.#.#.c.c.c.b.e.e.e.b.#.c.f.f.#.a.g",
+".b.h.j.j.j.k.l.l.j.j.l.l.l.l.l.l.o.n.n.m.p.m.l.m.m.m.n.n.n.m.b.q",
+".e.m.A.z.z.A.I.B.A.z.z.z.F.F.z.A.z.A.B.B.D.C.I.I.z.x.y.I.B.I.B.K",
+".e.m.I.A.z.z.A.I.A.A.I.A.A.z.I.B.I.B.B.E.D.D.B.B.F.y.B.C.I.y.E.M",
+".b.m.z.I.z.I.P.O.O.O.C.O.C.C.C.C.B.E.D.C.R.D.C.O.A.O.D.I.F.F.C.M",
+".U.l.x.A.B.O.O.D.D.C.C.C.R.q.D.C.C.V.V.q.q.V.D.C.O.D.C.P.z.z.B.K",
+".0.l.x.P.D.D.1.1.1.1.2.3.n.n.5.m.6.7.9.8###a.d#c#e.y#g.q.B.x.B#h",
+".U.l.F.B.X.p.1.1.1.i.2.3.o.4#i.m.j.j.9#.#a#b#c#c#e#k.D#m.O.v.C#h",
+"#z.p.A.B.D.1#g#A#B.z#g.V#C#p#D#D#E#F#G#v#v#x#x#x.K#h#H#I.Z.D.Y#I",
+".e.j.O.O#g.1#A.e.e#K#p#D#M#u#N#G#P#P#Q#Q#Q#G#R#x#h#h.z#S#m.q.Y#I",
+".e.j.O.B#g.1#U#k#6#7#Y#9a.a#a#aaabaaacad#0#0af#uagah#yaiaj#qak#I",
+".e.j.B.A.R.2.q#K#W#8#Xacada#aladanaf#Kaoadaeaqarasat#Aau.L#mak#I",
+".U.j.I.A.R.3.QaEawapaaada##8adaladad#K.f.9af#9aFaHaI.Saz.K#m.R.M",
+"aJ.k.A.z.WaD#8#U#Xac#9adab.0aladalalaa.a.p#VaLaLaIaM.Saz.N#r.qaN",
+"aS.8.z.yaT.4#L#Laaacala#adalaUadadadad##.2.0#ZaVaIaXaYaz#T#maT#I",
+"aJ.k.z.IaZ.4#1#X#0#Qa#a#adadabamadada0aOaP##ada1ayaM.Xaz#T#m.Z#I",
+".d.l.A.O.Y.l#1#1aca##9adadadamadadal#iaxaO.c#Za1.a#E#naz.N#maT#I",
+".c.j.I.C.Z.6#N#Na##Qa#a#adadananab#Vax.9#.#Va1a1.QaM.Raz.L#m.Z#h",
+".c.l.I.D.q.7a6#E#Na.#Q#O#Qada0#.aOax.6.9a7aKa4a4#Ea8#oaz#T#m.Z#I",
+".c.p.B.C.q.9#s#s#u#U#Q#Q#9#9#9a9a0aw#W#8b.a1a4b#babbbcaz.N#r.Z#I",
+".f.p.B.O.V#.#t.Gbd#E#s#E#O#P#O#O#F#P#G#u#E#F#P#Pbmbibcbk.K#maT#h",
+".c.m.O.O.R#..z.H.H#T.H#wararbfbfaIaMaMaXbnbna8a8bi#rbcbk.K#m.Y#h",
+"...m.B.O.Rbp#e#e.s#k#l#lbr#Bbsbt#Hbs.S#y.ZaYbwbxbybz#tbk.M#m.Y#h",
+".f.m.I.B.DaTbAbB#l#BbC.z#H#f#A#yaY.DaY#n#oa5bj#2bEbFbGbk.M.GaZat",
+"##.m.z.I.C.X#m#JahaA.L#5.r.r#5ajbpbJbEbKbE#5bIbkazazau#4.N#5.Z#h",
+".f.m.z.P.E.CaTaB.CbL#f#A.S.S.S.X.Xa5#o#objbz#5#5ai#4aA#IajaT.q#I",
+".c.m.z.A.B.I.R.Waj.NaAaibkazbkbkbkbkbkazazauai#S#I.M.H#t.W.C.R#h",
+".c.m.z.z.B.I.E.X#5.H#hat#S#S#S#4#S#SaAaAaAaAah#h.L.r#mbK.D.B.D#h",
+".fbM.y.F.A.z.x.z.D.Wbpak#r#rbp#m#m#r#r#2#rbpbpaT.W.q.E.O.A.z.C.M",
+".c.m.y.z.z.x.v.x.B.C.qa5.R.R.C.C.X.R.q.C.D.D.D.D.S.B.A.z.x.x.C.M",
+"...k.I.I.J.t.v.F.B.E.E.B.z.z.y.J.B.I.I.D.R.R.R.R.R.V.D.C.D.D.Z.M",
+".d#Kat#I#h.M#IaAaA#S#S#SaAaAaAaAaAaAaA#h#Iag#h#I#I#h#h#h#I#IavaA"};
diff --git a/images/mini-logo.png b/images/mini-logo.png
new file mode 100644 (file)
index 0000000..83b149f
Binary files /dev/null and b/images/mini-logo.png differ
diff --git a/images/msg-around.xpm b/images/msg-around.xpm
new file mode 100644 (file)
index 0000000..32b7e21
--- /dev/null
@@ -0,0 +1,74 @@
+/* XPM */
+static char *file[] = {
+"32 32 39 1",
+". c #fffbff",
+"# c #b6aeb6",
+"a c #080408",
+"b c #9e9a9e",
+"c c #8e8a8e",
+"d c #386da6",
+"e c #beb6be",
+"f c #000018",
+"g c #a6798e",
+"h c #79869e",
+"i c #a6a2a6",
+"j c #aeaeb6",
+"k c #000808",
+"l c #000010",
+"m c #8e8679",
+"n c #a69ea6",
+"o c #717986",
+"p c #ae9e59",
+"q c #aeb2cf",
+"r c #9696ae",
+"s c #51718e",
+"t c #fff3ff",
+"u c #c7bac7",
+"v c #cfc7cf",
+"w c #eff3f7",
+"x c #696971",
+"y c #ffffff",
+"z c #aea671",
+"A c #ae6161",
+"B c #aea6ae",
+"C c #717571",
+"D c #51a249",
+"E c #867986",
+"F c #bec3cf",
+"G c #6986be",
+"H c #a6a6a6",
+"I c #969696",
+"J c #f7b2ae",
+"K c #5155ff",
+"................................",
+".###############################",
+".#########cddcccbb##############",
+".b#b###cdacddfehcaai##e#e#b#b##e",
+".######kadd#ldmgadaaje####j###e#",
+".ee##jafb#ejdggpogddabb##j###j#b",
+".bbbbdddesdejqerldalaaeeebrbbeee",
+".bbbaddddg######ucaaaddq#rbbre##",
+".###dlllde.####rcddadaabb####b#b",
+".bbdaddgwe######qaaadca##brbb#e#",
+".brabndt.######q#caaadda#rbbb###",
+"tb#dbnv.y...###oogdddaaab#b#nbnb",
+".bA#dqd##y.####ccddddaaabbbrbbbb",
+".bdcadt.y####e###aalldaa#rbbr###",
+".bdcccdh#..####eqclala.abbDEbnub",
+"tbdr##aak#####gcccdda...hodfgnbb",
+".ndpbcaaadd#ecgcsbma....#...Drgb",
+".cdcbndddlaac#jccdd..###..#.drrr",
+"tbdghnallddddhcrpra.#.#..#..fDnb",
+"tbGmohdalddddfzdda.#...#.#...lnb",
+".DDddhoddallacddde#e#########ecq",
+".gcddcscdllldg.#.##.yy.....HH.an",
+".bbbdddolddbhd.##..........mp.lc",
+".nbndfddaddodd.............JJ.lc",
+".hchcddgdadddd......ch#.......an",
+".obcbgfdlddddd................ac",
+".mDmpsgddddKdd................ac",
+".gghcnbBdllald......gh##me....ab",
+".mopcronhmdaad..........y.....ao",
+"whhococchgcgcc.........y.y....ap",
+".Ighhohrccghozgddccccddddccccddc",
+".gzocDocrchosomocgpcopcoscgpcgzr"};
diff --git a/images/msg-here.xpm b/images/msg-here.xpm
new file mode 100644 (file)
index 0000000..cba58fb
--- /dev/null
@@ -0,0 +1,192 @@
+/* XPM */
+static char *file[] = {
+"32 32 157 2",
+".. c #000000",
+".# c #080c08",
+".a c #100400",
+".b c #100c08",
+".c c #101010",
+".d c #181410",
+".e c #181c18",
+".f c #200c00",
+".g c #202020",
+".h c #202028",
+".i c #202428",
+".j c #202430",
+".k c #280c00",
+".l c #281000",
+".m c #281c08",
+".n c #282420",
+".o c #282830",
+".p c #282c30",
+".q c #301000",
+".r c #301400",
+".s c #301408",
+".t c #302820",
+".u c #303038",
+".v c #381400",
+".w c #382010",
+".x c #383840",
+".y c #401808",
+".z c #401c08",
+".A c #402418",
+".B c #402c18",
+".C c #403420",
+".D c #403c28",
+".E c #404040",
+".F c #404448",
+".G c #482008",
+".H c #482818",
+".I c #484850",
+".J c #502008",
+".K c #502810",
+".L c #504c50",
+".M c #505858",
+".N c #582408",
+".O c #582810",
+".P c #582c10",
+".Q c #584838",
+".R c #585868",
+".S c #585c60",
+".T c #602c10",
+".U c #603010",
+".V c #603818",
+".W c #606468",
+".X c #684c30",
+".Y c #686460",
+".Z c #686868",
+".0 c #687070",
+".1 c #703410",
+".2 c #703818",
+".3 c #704028",
+".4 c #705c30",
+".5 c #707470",
+".6 c #784018",
+".7 c #786848",
+".8 c #787470",
+".9 c #787878",
+"#. c #787c78",
+"## c #804420",
+"#a c #808080",
+"#b c #808480",
+"#c c #808888",
+"#d c #884c28",
+"#e c #887048",
+"#f c #887c78",
+"#g c #888888",
+"#h c #888c90",
+"#i c #903020",
+"#j c #905c38",
+"#k c #906438",
+"#l c #909090",
+"#m c #909490",
+"#n c #909498",
+"#o c #909898",
+"#p c #989490",
+"#q c #989898",
+"#r c #989c98",
+"#s c #989ca0",
+"#t c #98a0a0",
+"#u c #a07450",
+"#v c #a07c50",
+"#w c #a08878",
+"#x c #a09c98",
+"#y c #a0a0a0",
+"#z c #a0a4a0",
+"#A c #a0a4a8",
+"#B c #a0a8a8",
+"#C c #a8a4a8",
+"#D c #a8a8a8",
+"#E c #a8aca8",
+"#F c #a8acb0",
+"#G c #a8b0b0",
+"#H c #b09050",
+"#I c #b0b0b0",
+"#J c #b0b4b0",
+"#K c #b0b4b8",
+"#L c #b0b8b8",
+"#M c #b8a490",
+"#N c #b8b8b8",
+"#O c #b8bcb8",
+"#P c #b8bcc0",
+"#Q c #b8c0c0",
+"#R c #c0a058",
+"#S c #c0bcb0",
+"#T c #b2c0dc",
+"#U c #c0c4c0",
+"#V c #c0c4c8",
+"#W c #c0c8c8",
+"#X c #c89060",
+"#Y c #c8ac58",
+"#Z c #c8c8c0",
+"#0 c #c8c8c8",
+"#1 c #c8ccc8",
+"#2 c #c8ccd0",
+"#3 c #d0c0b8",
+"#4 c #d0c8a8",
+"#5 c #d0c8c0",
+"#6 c #d0d0d0",
+"#7 c #d0d0d8",
+"#8 c #d0d4d8",
+"#9 c #d0d8d8",
+"a. c #d8b888",
+"a# c #d8cc58",
+"aa c #d8d8d8",
+"ab c #d8dcd8",
+"ac c #d8dce0",
+"ad c #d8e0e0",
+"ae c #e0b088",
+"af c #e0d0b8",
+"ag c #e0d468",
+"ah c #e0e0e0",
+"ai c #e0e4e8",
+"aj c #e0e8e8",
+"ak c #e8d8b0",
+"al c #e8dc70",
+"am c #e8e8e8",
+"an c #e8ece8",
+"ao c #e8ecf0",
+"ap c #e8f0f0",
+"aq c #f0e460",
+"ar c #f0e4b8",
+"as c #f0f0e8",
+"at c #f0f0f0",
+"au c #f0f0f8",
+"av c #f0f4f8",
+"aw c #f8e8d8",
+"ax c #f8ece0",
+"ay c #f8f4f0",
+"az c #f8f8f8",
+"aA c #f8fcf8",
+"#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#J.8#T#T#T#T#T#T#T#T#f#T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#T#T#T#1#M.z.Z#T#T#T#T#T#T#T#j.k#x#T#T#T#T",
+"#T#T#T#T#T#T#Zad#6.M#T#T#5.4.O.J#f.G#g#T#T#T#T#T.5.W.L#T#T#T#T#T",
+"#T#T#T#T#T#Taa#t#V#b.L.9.l.r.N#eaa#p.A#g#T#T#T#T.L.W#a#T#T#T#T#T",
+"#T#T#T#T#T#T#T#V.R.R.I.E.j.h.h.Saa#8.7.G#r#T#T#Ta#.Q#T#T#T#T#T#T",
+"#T#T#T#T#T#T#U#5.R.I.u.j.j.j.Y#6#P#8#2.X.D#T#T#T#Y.m#T#T#T#T#T#T",
+"#T#T#T#T#5#v#p.x.j.h.j.e#Faj#s#Daa#8#2#2.K.q#Ta..P.0#T#T#T#T#T#T",
+"#T#T#U#S.6.2.W.j.j.o.g#mamajahadaaaa#8#2#C.G.Zag.m#x#T#T#T#T#T#T",
+"anae.6##.6#u#G.o.Zaiatapamajah#Uacacaa#8#V#P#ka#.8#T#T#T#T#T#T#T",
+"acaw##.6#3aAaA.Iavavatapamaj#E#K#zaa#2#2#W#Pag#H#m#T#T#T#T#T#T#T",
+"#T#O#X.6#OaAaAazab#qatapab#F#V#Kaa#m#2#2#0#0#Y.w.y.D#T#T#T#T#T#T",
+"#T#Taw#k.VabaA#c#b#0atah#1#Oahad#I#F#2#2#0#0#H.d.H.q#T#T#T#T#T#T",
+"#T#T#Nay.6.2aAaz#L#q#Uah#I#2#r#q#A#O#B#A#Val.m#y#F.8.l.S#T#T#T#T",
+"#T#T#T#2#k.6#Eazaj#oah#zab#F#V#V#P#m#B#g#Taq.n#L#F#D.q.l#T#T#T#T",
+"#T#T#T#Tazae.2.tavav#C#6#y#F#a#K#g#W#2#qal#Y#z#K#F#E#y.Q.l#m#T#T",
+"#T#T#T#T#Uas.2.Tavav#g#g#yaa#D#g#z#8#r#Qaq#k#N#N#I#F#A#n.q.m#T#T",
+"#T#T#T#T#T#Eae.1.Aaaat#U#z#y#8ai#I#y#T#q#H.m#N#N#N#K#y#s#a.s.t#r",
+"#T#T#T#T#T#Tay#X.1.Fatap.9acaj#K#c#0#r#1#d.I#N#N#N#K#t#s#o.C.k.L",
+"#T#T#T#T#T#T#Taj.2.1#Napao#q#r#.#g#t#2al.d#V#V#V#A#A#t#m.k.k#m#T",
+"#T#T#T#T#T#T#T#J#X.U.tahan#y#z#U#P#t#5aq.M#V#V#V#D#D#g.g.k.##T#T",
+"#T#T#T#T#T#T#T#Tahaf.U.Ganaj.9#oaa#8ae#j#V#T#V#V#F.0.a.f#g#T#T#T",
+"#T#T#T#T#T#T#T#T#Ean.T.P#Uaj#0aiaa#8ae.s#T#Q#N#m.p.....##T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#Taf.3.J.Sahadaa#8.Q.5.i.p.5.p.v.k#g#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#Tanae.T.rahadaa.8.u.F#r#N.F.a.l.##T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#2.3.N.p#8aa#8#2#2#L.g.y.l#.#T#T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#T#4.V.z.Zaa#8#2#2.d.f.l.##T#T#T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#T#Uaw.N.J#N#8#a.c.z.l#g#T#T#T#T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#T#Taa.V.N.pac...s.l.##T#T#T#T#T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#T#T#Tax#u.J.k.G.s.5#T#T#T#T#T#T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#T#T#T#6ar.K.G.l.##T#T#T#T#T#T#T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#J#w.r#.#T#T#T#T#T#T#T#T#T#T#T#T#T",
+"#T#T#T#T#T#T#T#T#T#T#T#T#T#T#T#Taw.p#T#T#T#T#T#T#T#T#T#T#T#T#T#T"};
diff --git a/images/new-log.xpm b/images/new-log.xpm
new file mode 100644 (file)
index 0000000..2f46af8
--- /dev/null
@@ -0,0 +1,132 @@
+/* XPM */
+static char *file[] = {
+"32 32 97 2",
+".. c #889988",
+".# c #888899",
+".a c #998899",
+".b c #889999",
+".c c #999999",
+".d c #9999aa",
+".e c #99aa99",
+".f c #aa99aa",
+".g c #99aaaa",
+".h c #aaaaaa",
+".i c #998888",
+".j c #888888",
+".k c #999988",
+".l c #aa9999",
+".m c #cccccc",
+".n c #887788",
+".o c #222222",
+".p c #444444",
+".q c #666666",
+".r c #bbaabb",
+".s c #777777",
+".t c #dddddd",
+".u c #aaaabb",
+".v c #333333",
+".w c #111111",
+".x c #111122",
+".y c #331111",
+".z c #554411",
+".A c #aaaa99",
+".B c #eeddee",
+".C c #778877",
+".D c #666677",
+".E c #776677",
+".F c #221111",
+".G c #443322",
+".H c #555544",
+".I c #ddeedd",
+".J c #777788",
+".K c #556666",
+".L c #778888",
+".M c #555566",
+".N c #555555",
+".O c #bbbbcc",
+".P c #eeeeee",
+".Q c #bbbbbb",
+".R c #443344",
+".S c #110011",
+".T c #111100",
+".U c #772211",
+".V c #663311",
+".W c #442222",
+".X c #332222",
+".Y c #ffffff",
+".Z c #000000",
+".0 c #664433",
+".1 c #ddddcc",
+".2 c #bbaaaa",
+".3 c #ccbbcc",
+".4 c #552200",
+".5 c #884422",
+".6 c #ccdddd",
+".7 c #886655",
+".8 c #776666",
+".9 c #aabbaa",
+"#. c #774444",
+"## c #774433",
+"#a c #bbaa88",
+"#b c #997755",
+"#c c #332211",
+"#d c #332233",
+"#e c #553333",
+"#f c #eeeecc",
+"#g c #ffeeee",
+"#h c #bb8855",
+"#i c #332200",
+"#j c #ccddcc",
+"#k c #333311",
+"#l c #aa9966",
+"#m c #ddbb77",
+"#n c #eedd99",
+"#o c #887777",
+"#p c #ccbbbb",
+"#q c #aaaa66",
+"#r c #eedddd",
+"#s c #8899aa",
+"#t c #8888aa",
+"#u c #667766",
+"#v c #996677",
+"#w c #554444",
+"#x c #aa6633",
+"#y c #884444",
+"#z c #eeeeff",
+"#A c #886666",
+"#B c #bbbbaa",
+"#C c #aabbbb",
+"#D c #776655",
+"#E c #445544",
+"...#...a...a...a...a.b.c.b.c.c.c.c.c.c.c.c.d.e.f.e.d.e.f.e.f.g.h",
+".i.j.a...a...a...a.k.a.k.a.c.c.c.c.c.c.c.l.c.f.c.l.c.f.e.f.e.f.e",
+"...a...#...a.c.m.n.o.p.q.c.c.r.k.i.s.c.d.e.d.e.d.e.f.e.f.e.h.e.h",
+".a...i...a.j.t.h.g.u.v.o.w.x.w.y.z.w.s.j.l.e.l.c.f.e.f.A.f.A.f.A",
+"...a...a...n.B.C.v.h.a.s.D.s.E.o.F.G.F.H...d.e.f.e.f.g.h.g.f.g.h",
+".a...a...a.h.I.J.K.D.L.#.s.M.N.p.o.w.z.F.v.j.f.e.f.e.f.e.f.A.f.A",
+"...a...a.O.P.Q.j.j.L.E.N.R.v.S.T.y.G.U.V.W.X...f.e.h.e.h.g.h.g.h",
+".a...c.m.Y.u.b.E.s.M.p.o.Z.w.o.G.z.V.z.V.0.W.T.k.f.A.f.A.h.A.f.h",
+".r.1.2.P.3.q.E.N.v.T.Z.T.4.0.U.z.V.V.V.z.V.0.V.T.j.f.g.h.g.h.h.h",
+".A.5.z.Y.6.q.v.S.Z.F.z.5.0.V.0.0.z.V.z.G.z.V.z.G.T.s.a.A.f.h.h.h",
+".7.0.U.A.l.v.Z.T.V.5.U.0.V.z.U.V.V.z.V.0.V.z.V.0.V.T.8.h.h.h.h.u",
+".I#..5.V.p.F.z.5.0.V.0.V.0##.z.V.0.V.z.V.z.V.0.V.z.W.T.N.h.h.2.h",
+".J.P#..5.5.5.5.0.V.0.U.z.U.V.V.z.V.z.V.z.V.V.V.z.U.z.V.T.v.u.9.u",
+".E.c.P#..0.0.0.w#a#b.z.V.0.V.z.V.0.V.0.G.0.V.z.V.G.G.z.V#c#d.c.h",
+".j.s.b.t#..5.U.5#e#f#g#h.0.z.V.z.V.z.V.z.V.z.U.z.V.z.V.4.V#i.Z.u",
+".c.C.s.c#j#..0.5.0.F#k#l#m#m.0.V.z.V.0.V.z.V.G.V.z.W.z.G.z.4.W.S",
+".c.c.j.s.r.1.0.z.5.0.W.T.y#h#n#m.5.z.V.z.V.z.V.z.V.4.V.G.4.W.W.G",
+".c.c.j.j#o.Q.1.0.0.0.0.V#c.Z.o#l#n#m.0.G.z.V.z.4.z.G.G.G.z.G.z.G",
+".e.c.c.d...J#p.1.V.z.U.0.5.0.y.Z.y#q#n#m.5.z.U.4.V.z.4.z.z.z.U.z",
+".c.c.l.c.i.C#o.O.9.0.0.V.0.G.0.V#c.S.o#l#n#m.0.G.G.W.z.G.z.V.G.Z",
+".c.d.e.f.e.d.C.n#r.2.U.z.U.z.V.z.V.V.y.Z.y#h#n#m.V.4.W.z.U.Z.Z.p",
+".l.c.f.c.l.c.a.C.n.P.A.V.0.V.z.G.z.V.z.G.o.Z.o#l#s#t.G.W.Z.o.N#u",
+".e.d.e.d.e.f.e.f.C.j#g.A.V.z.V.V.V.z.V.z.V.z.y.T.p.s#v.0#w.q#u.n",
+".l.e.l.c.f.e.f.A.a.C.L.Y.A.V.z.V.z.V.z.G.z.V.z.V.o.x#x#y.E.C.j.k",
+".e.d.e.f.e.f.g.h.g.f.L.C#g.i.U.z.U.z.V.z.V.V.W#c.Z.v.y.4.C.a.b.h",
+".l.c.f.e.f.e.f.e.f.A.a.C.L#z#A.V.z.G.G.W.0.W.Z.Z.p.q.n.C.a.A.f#B",
+".e.f.e.f.e.h.e.h.g.h.b.c.j.k.Y#A.V.V.V.W.W.Z.v.N#u.n.j.a.g.Q#C.Q",
+".f.e.f.A.f.A.f.A.h.A.f.h.c.j.c.Y#D.G.z.W.Z.p.8.C.n.j.f.A.r#B.r.Q",
+".e.f.g.h.g.f.g.h.g.h.h.h.h.d...d.h.W.Z.o#E.E.C.j...f.Y.Y.Y.Y.Y.Y",
+".f.e.f.e.f.A.f.A.f.h.h.h.2.h.c.j.N.W.o.q.E.s.a...f#B.Y.h.h.h.h.N",
+".e.h.e.h.g.h.g.h.h.h.h.u.9.h.e.d.j.q.q.J.j.a.e.r#C.Q.Y.h.h.h.h.N",
+".f.A.f.A.h.A.f.h.h.h.2.h.2.h.2.c.l...j.j.a.e.f#B.r#B.Y.N.N.N.N.N"};
diff --git a/images/password.xpm b/images/password.xpm
new file mode 100644 (file)
index 0000000..c3261c4
--- /dev/null
@@ -0,0 +1,45 @@
+/* XPM */
+static char *file[] = {
+"32 32 10 1",
+". c #ffffff",
+"# c #bebabe",
+"a c #000010",
+"b c #beb6be",
+"c c #aeaaae",
+"d c #aea6ae",
+"e c #c7bac7",
+"f c #000000",
+"g c #ffff00",
+"h c #9e9a9e",
+"................................",
+".###############################",
+".###############################",
+".c#c######c#d####c#d######d#c###",
+".#b#b##b#e#b##b#b#b#eb#beb#bebe#",
+".#####b#d####d#b######d########c",
+".cddc####ccdd####ddcc##b#ddcc###",
+".cddd####dddcb###cdcfff##dccc###",
+".####ccbc####ccc###fgggfc####c#c",
+".cdcd####dcdc####dfggggg#dccc###",
+".cccd####cdcd##ffcggggggfcccc###",
+".c#c#cccffffffffffggggffgfc#cccc",
+".ccccccfggggggggggggggccgfcccccc",
+".cccc###gggggggggggggg##gfccc###",
+".ccdc#c#cfgfgggffcggggggfccccc#c",
+".cccccccccfcffffccggggggfccccccc",
+".cccccccccccccccccffgggfcccccccc",
+".hchcccccchchccfchfffffffchchccc",
+".cccccccccccccccccfffffffccccccc",
+".cccccccffffffffffffffccffcccccc",
+".hhhhccfffffffffffffffccffhhhccc",
+".hhhhcccfffffffffffffffffhhhhccc",
+".ccccchchfffffffccfffffffcccchch",
+".cccchhhhcccchhhhcffffffhcccchhh",
+".hhhhcccchhhhcccchhfffffchhhhccc",
+".hchchhhhchchhhhhhchffhhhchchhhh",
+".hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh",
+".hhhhcccchhhhcccchhhhcccchhhhccc",
+".hhhhchchhhhhhchchhhhchchhhhhhch",
+".hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh",
+".hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh",
+".hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh"};
diff --git a/images/search.xpm b/images/search.xpm
new file mode 100644 (file)
index 0000000..659017c
--- /dev/null
@@ -0,0 +1,53 @@
+/* XPM */
+static char *file[] = {
+"32 32 18 1",
+". c #ffffff",
+"# c #bebabe",
+"a c #bec3be",
+"b c #000010",
+"c c #aeaaae",
+"d c #9e9a9e",
+"e c #000000",
+"f c #79869e",
+"g c #080408",
+"h c #7992b6",
+"i c #717986",
+"j c #9696ae",
+"k c #bec3cf",
+"l c #beb6be",
+"m c #aeb2cf",
+"n c #867986",
+"o c #c7bac7",
+"p c #aea6ae",
+"................................",
+".####aaaa####aaaa####aaaa####aaa",
+".a##############################",
+".c#c######c#c####cac#a###acac###",
+".###a###a####a###a####aaa#a#a###",
+".a#a#aa#c##aacaa##a###c##aa##a#c",
+".cccc##a#cccc###acccca###cccc#a#",
+".cccc####cccc####cccc####cccca##",
+".a###ccac#a##ccc#a##a#ccc##a#c#c",
+".cccc###acccc####cccc##a#cccc##a",
+".cccca###ceafffa#e#fff##acccd#a#",
+".c#c#cdcc#eeeeecceeegeccd#c#cccc",
+".cccccccccb#ijfccbkjffcccccccccc",
+".cccc####ce#fii##e#fji###cccc###",
+".cccc#c#cce.hiic#e.iihc#cccccc#c",
+".cccccccccelihfeeemiifcccccccccc",
+".cccccccccbkjigeee#nihcccccccccc",
+".dcdcccccce#ihb#ff#hjiccccdcdccc",
+".ccccccccceohieegeonifcccccccccc",
+".ccccccccceegggeeebebecccccccccc",
+".ddddccccdde##fge#afecccpddddccc",
+".ddddccccdddeffccefedccpcddddccc",
+".cccccdcdccceeedceeeccdcdcpccdcd",
+".ccccddddccceggeeegecddddccccddd",
+".ddddcccpdddd#cccddddccccddddccc",
+".dcdcddddcdcddddddcdcddddcdcdddd",
+".ddddddddddddddddddddddddddddddd",
+".ddddccccddddccccddddccccddddccc",
+".ddddcdcddddddcdcddddcdcddddddcd",
+".ddddddddddddddddddddddddddddddd",
+".ddddddddddddddddddddddddddddddd",
+".ddddddddddddddddddddddddddddddd"};
diff --git a/images/upd-info.xpm b/images/upd-info.xpm
new file mode 100644 (file)
index 0000000..ae2fbb6
--- /dev/null
@@ -0,0 +1,139 @@
+/* XPM */
+static char *file[] = {
+"32 32 104 2",
+".. c #000000",
+".# c #001111",
+".a c #110011",
+".b c #111111",
+".c c #111122",
+".d c #220011",
+".e c #331111",
+".f c #221133",
+".g c #222222",
+".h c #222233",
+".i c #332233",
+".j c #333333",
+".k c #332244",
+".l c #333355",
+".m c #551133",
+".n c #552200",
+".o c #442222",
+".p c #443322",
+".q c #553333",
+".r c #772211",
+".s c #443344",
+".t c #443355",
+".u c #444444",
+".v c #445555",
+".w c #554444",
+".x c #555555",
+".y c #444466",
+".z c #554466",
+".A c #555566",
+".B c #555577",
+".C c #556666",
+".D c #774444",
+".E c #776655",
+".F c #666666",
+".G c #666677",
+".H c #667766",
+".I c #776666",
+".J c #776677",
+".K c #777777",
+".L c #557788",
+".M c #665588",
+".N c #666688",
+".O c #777788",
+".P c #118811",
+".Q c #778877",
+".R c #778888",
+".S c #778899",
+".T c #880011",
+".U c #bb2233",
+".V c #bb6633",
+".W c #996677",
+".X c #cc4422",
+".Y c #dd7733",
+".Z c #886688",
+".0 c #887788",
+".1 c #8877aa",
+".2 c #bb8855",
+".3 c #ddaa77",
+".4 c #888888",
+".5 c #888899",
+".6 c #889988",
+".7 c #889999",
+".8 c #998888",
+".9 c #998899",
+"#. c #999999",
+"## c #8888aa",
+"#a c #8899aa",
+"#b c #9999aa",
+"#c c #9999bb",
+"#d c #99aa99",
+"#e c #99aaaa",
+"#f c #aa9999",
+"#g c #bb9988",
+"#h c #aa88bb",
+"#i c #aa99aa",
+"#j c #aaaaaa",
+"#k c #aaaabb",
+"#l c #aabbaa",
+"#m c #aabbbb",
+"#n c #bbaaaa",
+"#o c #bbaabb",
+"#p c #bbbbbb",
+"#q c #bbbbcc",
+"#r c #bbccbb",
+"#s c #ccbbaa",
+"#t c #ddbbbb",
+"#u c #ccbbcc",
+"#v c #ccbbdd",
+"#w c #ddbbcc",
+"#x c #cccccc",
+"#y c #ccddcc",
+"#z c #ccdddd",
+"#A c #ddcccc",
+"#B c #ddccdd",
+"#C c #ddddcc",
+"#D c #dddddd",
+"#E c #ddeedd",
+"#F c #ddeeee",
+"#G c #eedddd",
+"#H c #eeddee",
+"#I c #eeeeee",
+"#J c #eeeeff",
+"#K c #ffffff",
+"#L c #b2c0dc",
+"#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L",
+"#L#L#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#w#g.e#z#p#L",
+"#L#K#I#F#F#I#J#F#F#J#I#F#F#I#J#F#F#J#I#F#F#F#D#E#K.2.U.n.E.5.M.j",
+"#L#K#F#I#I#F#I#I#I#I#F#I#I#F#I#I#I#I#F#H#D#E#D#I#t.U.T...K.K.G.h",
+"#L#K#I#I....................................#I#H.U.U.d.c.K#..N.f",
+"#L#K#I#F...J.J.L.K.J.0.O.S.0.0.S.R.0.O.O.L.J#K.U.U.n.q.u.6#k.J.g",
+"#L#K#J#F...J.J.O.S.0###a#a#c.9##.5##.0.S.O#H.U.U...e.t.v#m#q.J.c",
+"#L#K#I#I...K.O.0.9.5.9#c#i#b#b.9.9.5.5.0#u#K.U.U.d.j.u.F#p#m.G.c",
+"#L#K#F#I...O.5.9.9#b#k#o#o#k#k#i#h#b.5.9#H.U.T...s.u.F.J#p#l.G.c",
+"#L#K#J#F...O#####c#i#k#q#K#D#i#e#c#c.9#r.V.U...e.u.u.N.L#l#k.N.c",
+"#L#K#I#F...0###a#e#k#K#A.U.U.J#b#c#c#I#E.U.T.w.u.v.G.J.K#l#k.M.c",
+"#L#K#F#I...O.5.9#i#i#C.U.U.U.e.0#h#b#K.X.U...u.u.M.G.K.J#j#j.G.c",
+"#L#K#I#I...O.5.9#c#b.D.3.U.U.T.e.9#x.U.U...q.u.F.J.K.K.J#j#e.A.c",
+"#L#K#I#F...O###a#a#c#q#A.U.U.U.n#b#K.U.U.e.u.A.K.K.J.J.K#e#j.M.b",
+"#L#K#J#F...J.0.S##.9#c#k.U.U.U.U#K.X.T...u.u.J.O.L.J.J.L#e#b.M.b",
+"#L#K#I#I...K.O.0.1.5.5.9.Y.U.U.U.U.U.e...t.x.K.J.J.K.K.J#i#..A.a",
+"#L#K#F#I...K.K.J.0.0.4.0#B.X.U.U.U.U.e.t.z.G.K.J.J.K.K.J#.#..A.b",
+"#L#K#J#F...J.J.L.O.0.0.S#b#t.U.U.U.T.s.u.C.J.J.K.L.J.J.L.7#..B.#",
+"#L#K#I#F...J.J.L.K.J.O.O.O.9.U.U.n.a.u.v.K.J.J.L.K.J.J.K.7#..A.#",
+"#L#K#E#H...K.K.J.J.K.K.J.J.K.....d.o.u.z.J.K.K.J.J.K.K.J.9.6.A.a",
+"#L#K#E#D...K.K.J.J.K.K.J.J.K.G.M.x.u.F.J.J.K.K.J.J.K.K.J.9.4.v.a",
+"#L#K#D#E...J.J.L.K.J.J.K.L.J.J.K.C.M.J.K.L.J.J.L.K.J.J.K.6.4.z..",
+"#L#K#D#z#z#x#x#r#r#x#q#r#m#p#o#l#l#k#k#e#e#b#b.7.7#..z.y.R.4.z..",
+"#L#K#z#D#B#y#x#x#u#r#p#p#o#m#l#n#j#j#j#i#i#.#.#..9.6.P.P.0.Q.u..",
+"#L#K.O.J.J.O.J.J.J.G.G.J.M.G.G.M.M.A.A.M.B.A.A.z.z.x.u.z.z.u.u..",
+"#L.O............................................................",
+"#L#L#L#L#L#L#L#K.H.G.G.H.l.G.0.R.A.u.l.c.h.l.G.H.G.h#L#L#L#L#L#L",
+"#L#L#L#L#L#L#K#D.0.4.Q.0.0.F.u.t.s.l.l.t.A.Q.4.4.8.G#L#L#L#L#L#L",
+"#L#L#L#L#L#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K#K.G.i#L#L#L#L",
+"#L#L#L#L#L#K#j#j#j#j#j#j#j#j#j#j#j#j#j#j#j#j#j#j#j#j#j..#L#L#L#L",
+"#L#L#L#L#L.M...........................................h#L#L#L#L",
+"#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L#L"};
diff --git a/images/url-around.xpm b/images/url-around.xpm
new file mode 100644 (file)
index 0000000..b5de461
--- /dev/null
@@ -0,0 +1,209 @@
+/* XPM */
+static char *file[] = {
+"32 32 174 2",
+".. c #3f281f",
+".# c #302820",
+".a c #30282f",
+".b c #303720",
+".c c #3f372f",
+".d c #3f3f2f",
+".e c #203740",
+".f c #2f3f50",
+".g c #3f4f30",
+".h c #3f4740",
+".i c #304750",
+".j c #3f4f50",
+".k c #3f5f40",
+".l c #30575f",
+".m c #3f5f5f",
+".n c #2f4f60",
+".o c #3f5760",
+".p c #305f7f",
+".q c #3f5f70",
+".r c #3f676f",
+".s c #50301f",
+".t c #403f2f",
+".u c #503f20",
+".v c #5f3720",
+".w c #5f3820",
+".x c #603f1f",
+".y c #603820",
+".z c #6f3f20",
+".A c #404730",
+".B c #4f4f30",
+".C c #40582f",
+".D c #504f30",
+".E c #50573f",
+".F c #505f3f",
+".G c #5f573f",
+".H c #406730",
+".I c #4f673f",
+".J c #50673f",
+".K c #5f673f",
+".L c #5f6f3f",
+".M c #70401f",
+".N c #70471f",
+".O c #7f471f",
+".P c #6f472f",
+".Q c #6f4f3f",
+".R c #7f4820",
+".S c #40574f",
+".T c #4f574f",
+".U c #4f5f5f",
+".V c #505f40",
+".W c #5f5740",
+".X c #5f5f4f",
+".Y c #40576f",
+".Z c #4f5f60",
+".0 c #505f6f",
+".1 c #5f6740",
+".2 c #5f704f",
+".3 c #5f7840",
+".4 c #506760",
+".5 c #5f6f6f",
+".6 c #50777f",
+".7 c #605f50",
+".8 c #705f4f",
+".9 c #606740",
+"#. c #6f6f40",
+"## c #60675f",
+"#a c #607740",
+"#b c #607f4f",
+"#c c #60775f",
+"#d c #706750",
+"#e c #706f50",
+"#f c #606f7f",
+"#g c #706f60",
+"#h c #707f60",
+"#i c #707770",
+"#j c #7f7f7f",
+"#k c #406780",
+"#l c #707f90",
+"#m c #6f875f",
+"#n c #708850",
+"#o c #6f977f",
+"#p c #7f8760",
+"#q c #708f7f",
+"#r c #7f9760",
+"#s c #408fb0",
+"#t c #6f8f90",
+"#u c #7f8780",
+"#v c #7087af",
+"#w c #5097cf",
+"#x c #4fa0df",
+"#y c #5fa0cf",
+"#z c #5fafe0",
+"#A c #6098c0",
+"#B c #6fa8e0",
+"#C c #60b0f0",
+"#D c #6fb8ff",
+"#E c #7fb8f0",
+"#F c #7fc0e0",
+"#G c #7fc0f0",
+"#H c #80481f",
+"#I c #8f4f1f",
+"#J c #90501f",
+"#K c #90571f",
+"#L c #9f501f",
+"#M c #804f20",
+"#N c #8f572f",
+"#O c #a0581f",
+"#P c #af581f",
+"#Q c #af5f1f",
+"#R c #b0601f",
+"#S c #af672f",
+"#T c #b06820",
+"#U c #b06f20",
+"#V c #bf703f",
+"#W c #806050",
+"#X c #cf6f1f",
+"#Y c #c07730",
+"#Z c #8f8f6f",
+"#0 c #90976f",
+"#1 c #8f8f80",
+"#2 c #8f8f90",
+"#3 c #809780",
+"#4 c #8f979f",
+"#5 c #90979f",
+"#6 c #9fa890",
+"#7 c #8fa0af",
+"#8 c #8fb0b0",
+"#9 c #90a0af",
+"a. c #a0b89f",
+"a# c #afb0a0",
+"aa c #a0b0b0",
+"ab c #afb8bf",
+"ac c #b0b8bf",
+"ad c #8fa8cf",
+"ae c #8fb8df",
+"af c #9fb0c0",
+"ag c #9fb8d0",
+"ah c #80b0ef",
+"ai c #80b8e0",
+"aj c #a0b8c0",
+"ak c #bfc08f",
+"al c #bfd8bf",
+"am c #80c8ff",
+"an c #8fc8ff",
+"ao c #9fc7ef",
+"ap c #90d0ff",
+"aq c #9fe0ff",
+"ar c #afc0cf",
+"as c #bfc0c0",
+"at c #b0c8d0",
+"au c #afc8e0",
+"av c #afd0ef",
+"aw c #b0d0ef",
+"ax c #bfd0ef",
+"ay c #bfdfff",
+"az c #a0efff",
+"aA c #afe0ff",
+"aB c #b0efff",
+"aC c #c0b0bf",
+"aD c #cfc0bf",
+"aE c #cfc8df",
+"aF c #c0d0c0",
+"aG c #d0d8df",
+"aH c #cfe0e0",
+"aI c #cfe0ff",
+"aJ c #cfe8ff",
+"aK c #cff7ff",
+"aL c #d0e8e0",
+"aM c #e0e8ff",
+"aN c #e0ffff",
+"aO c #eff0f0",
+"aP c #f0f8ff",
+"aQ c #ffffff",
+"aR c #b2c0dc",
+"aRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaR..aRaRaRaRaRaRaRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaRaRaRaRaRaRaR..aRaRaRaRaRaRaRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaRaRaRaRaR.T.Z.h.h#jaRaRaRaRaRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaRaRaRaRabalayaIau#u#laRaRaRaRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaRasaQaOaJamaiaraHajaf#7#uaRaRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaRaQaQaKaA#Gaiarataf#8#9#2#faRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRa#aQaLaNanamaiaiajaa#4#7#9#2#i.2aRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaQaQaQaNam#G#Fai#5#Z#m#u#5#j.7.F.CaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaR#4aPaQ#6aNaiaiaxaa#r#r.I.J.F.1.C.I.F.IaRaRaRaRaRaR",
+"aRaRaRaRaRaR#wavaNaPaIaMaoavar#p#n#3.J.J.I.I.C.F.F.FaRaRaRaRaRaR",
+"aRaRaRaRaRaR#FazaqaAaIawaFaE#a#m#3#2.I.J.C.C.F.C.I.F.CaRaRaRaRaR",
+"aRaRaRaRaRaRapazaqaBaoauabaE#1#3#2#j.I.I.H.C.J.F.1.J.BaRaRaRaRaR",
+"aRaRaRaR#H###Gap#D#zaca##h#1.L.K.3.L.I.C.K.F.K.J.F.L.V.d.saRaRaR",
+"aRaR#J#I#X.i#Dam#C#zagac#p#b.L.9.K.L.L.F.1.C.K.8.K.L.9.b.x.vaRaR",
+"aRaR#X#R#I.h#Bah#x#x#t#t#n#..X.X.V.F.V.4.Z.0.F##.K.K#d.c.O.M.zaR",
+"aRaR#R#R#I.O#v#B#w#w.6#a#h.6.6.0.6.7.X.m####.W.X.F.W.c.P.O.O.uaR",
+"aRaR.y#J#Q#R#P#L#V.r.Z.Z.m.Z.m.j.r.m.V.X.G.G.h#N#M.R.R.O.M.x.#aR",
+"aRaRaR.w.R#L#Q#Q#R#T#Y#U#Y#Y#U#U#T#R#R#Q#Q#Q#K#K#J#M.R.M.v..aRaR",
+"aRaRaRaRaRaR.P.z.O.M.O.R.M.M.M.M.M.M.M.M.M.M.R.R.P.z.z.#aRaRaRaR",
+"aRaRaRaRaRaR.Y#W.P.P.w.w.z.M.z.z.z.z.z.z.z.z.w.z.i.q..aRaRaRaRaR",
+"aRaRaRaRaRaRaRaR#k.q.V.1.9.L.9.9.9.V.L.9.W.9.0.q.iaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaR.r.p.r.r.m.4.V.V#.#g.V.V.S.l.r.raRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaR#k.q.q.q.5.X.9.7.W.E.l.n.faRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaR.l.Y.p.q.r.7#d.9.U.m.o.oaRaRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaRaRaR.M.M#Q#I.v.z.N.#.#aRaRaRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaRaR#Q#P#I#R#I.y.z.N...a.aaRaRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaR#R#X#R#I#Q#J.w.w.x...#.#.#.vaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaR.M#X#R#R#Q...O.z.y.....#.#....aRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaR.M#R#R#R#R.O.M.s.s.s.........saRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaR.w#I#P#R#R#P#H.w.v.s.........saRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaR.w.M#L#P#Q#P#L.M.x.s.s.v.waRaRaRaRaRaRaRaRaR",
+"aRaRaRaRaRaRaRaRaRaRaRaR.y.M#H#H.R.M.x.v.w.waRaRaRaRaRaRaRaRaRaR"};
diff --git a/images/url-here.xpm b/images/url-here.xpm
new file mode 100644 (file)
index 0000000..82d8090
--- /dev/null
@@ -0,0 +1,92 @@
+/* XPM */
+static char *file[] = {
+"32 32 57 1",
+". c #000000",
+"# c #100010",
+"a c #101000",
+"b c #101010",
+"c c #101020",
+"d c #201010",
+"e c #301010",
+"f c #302010",
+"g c #303010",
+"h c #202020",
+"i c #302020",
+"j c #303030",
+"k c #412020",
+"l c #413020",
+"m c #513030",
+"n c #414530",
+"o c #514530",
+"p c #614530",
+"q c #714530",
+"r c #414541",
+"s c #514541",
+"t c #515541",
+"u c #515551",
+"v c #714541",
+"w c #716551",
+"x c #616561",
+"y c #716571",
+"z c #717571",
+"A c #8e4541",
+"B c #8e6551",
+"C c #9e6551",
+"D c #9e7551",
+"E c #8e6561",
+"F c #9e6571",
+"G c #ae8a61",
+"H c #ae8a71",
+"I c #ae9a61",
+"J c #8e8a8e",
+"K c #9e8a8e",
+"L c #9e8a9e",
+"M c #9e9a8e",
+"N c #ae9a9e",
+"O c #be9a8e",
+"P c #aeaa9e",
+"Q c #beaa8e",
+"R c #aebaae",
+"S c #beaaae",
+"T c #bebaae",
+"U c #cfbaae",
+"V c #dfbabe",
+"W c #cfcfbe",
+"X c #efdf9e",
+"Y c #ffcfae",
+"Z c #dfdfcf",
+"0 c #efdfdf",
+"1 c #efefcf",
+"2 c #b2c0dc",
+"2222222222222222222222222SXYN222",
+"222222222222222222222222ZXSQwO22",
+"2222222222222222222222SXQOGHEv22",
+"2222222222222222222SYQSGGHHHQi22",
+"22222222222222222TZXQHGEHHOQQi22",
+"2222222222221EKYSjuGwEGOOQOQOi22",
+"222222222222WXYQ1BpBGGHOOOOHOi22",
+"222222222SXYOGHBBSiDHGHGGGGHHmy2",
+"22222222YXSQGEwEDUiGGHGGGGGGIsx2",
+"2222TZXUHGEwwBwDDWiDDDDDGGGIQKjL",
+"222SYUOGBBvvBBBBDUiCEDGDGGGHOQvw",
+"TW1ZGDBwvvvBBwBBBYiCCDGDGHIOQQHB",
+"0P.iEwtwwtwwwwwBBZiDDGGGHGHOODvs",
+"1o..1stvvtvtvwwBB1iHDDGGHGDthx22",
+"1pasZpsppvtvvvBBoZ.ZGDGGBvlki222",
+"1saBZosppvtvBwBBoZiEDBvipvBBk222",
+"1odw1sosstvtwBwBDZiDokjsBwGGi222",
+"1pdEZmmopspvBwBBBYisiovwDGGGk222",
+"1shFZmmmoppsvvvviUhpvDCDDCDGk222",
+"1ocKUvommosotwjijWitDEDDDDGGi222",
+"0oiMGHommomjhjosBUiBDCDDGDBshrxx",
+"1siOBHmmlmfcmpswBSiCCDCDBs..rrxJ",
+"1pkNkBsdlmopAvAvBOiCCvs.hrrrxxJJ",
+"0oiThchkmovvvwwBBQiDj..hrrxxJJ22",
+"1oiWomnsstvtvwwBwI..rrrxxJJ22222",
+"1phVspsppvpvvvvpgA.rrxxxJ2222222",
+"1sdWposppvvvk..hrrxxJJ2222222222",
+"1obZospsvpsi.hrrxxxJ222222222222",
+"0o#1ssos..hrrxxxJ222222222222222",
+"Ns.Zvok.hrrrxxJJ2222222222222222",
+"2mm..hrrxxxJ22222222222222222222",
+"2xrrxrxxxJJ222222222222222222222"};